PageRenderTime 42ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/src/main/java/org/primefaces/behavior/base/AbstractBehaviorHandler.java

http://primefaces.googlecode.com/
Java | 240 lines | 178 code | 40 blank | 22 comment | 49 complexity | 2ab3a6271a7540cb5b9e0c49f0c64eb5 MD5 | raw file
Possible License(s): Apache-2.0
  1. /*
  2. * Copyright 2009-2014 PrimeTek.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.primefaces.behavior.base;
  17. import java.beans.BeanDescriptor;
  18. import java.beans.BeanInfo;
  19. import java.io.IOException;
  20. import java.lang.reflect.Method;
  21. import java.util.ArrayList;
  22. import java.util.Collection;
  23. import java.util.List;
  24. import java.util.Map;
  25. import java.util.logging.Level;
  26. import java.util.logging.Logger;
  27. import javax.el.ValueExpression;
  28. import javax.faces.component.UIComponent;
  29. import javax.faces.component.behavior.ClientBehaviorBase;
  30. import javax.faces.component.behavior.ClientBehaviorHolder;
  31. import javax.faces.context.FacesContext;
  32. import javax.faces.view.AttachedObjectHandler;
  33. import javax.faces.view.AttachedObjectTarget;
  34. import javax.faces.view.BehaviorHolderAttachedObjectHandler;
  35. import javax.faces.view.BehaviorHolderAttachedObjectTarget;
  36. import javax.faces.view.facelets.ComponentHandler;
  37. import javax.faces.view.facelets.FaceletContext;
  38. import javax.faces.view.facelets.TagAttribute;
  39. import javax.faces.view.facelets.TagConfig;
  40. import javax.faces.view.facelets.TagException;
  41. import javax.faces.view.facelets.TagHandler;
  42. import org.primefaces.behavior.ajax.AjaxBehaviorHandler;
  43. import org.primefaces.context.RequestContext;
  44. public abstract class AbstractBehaviorHandler<E extends AbstractBehavior>
  45. extends TagHandler implements BehaviorHolderAttachedObjectHandler {
  46. private final TagAttribute event;
  47. public AbstractBehaviorHandler(TagConfig config) {
  48. super(config);
  49. this.event = this.getAttribute("event");
  50. }
  51. public void apply(FaceletContext faceletContext, UIComponent parent) throws IOException {
  52. if (!ComponentHandler.isNew(parent)) {
  53. return;
  54. }
  55. String eventName = getEventName();
  56. if (UIComponent.isCompositeComponent(parent)) {
  57. boolean tagApplied = false;
  58. if (parent instanceof ClientBehaviorHolder) {
  59. applyAttachedObject(faceletContext, parent);
  60. tagApplied = true;
  61. }
  62. BeanInfo componentBeanInfo = (BeanInfo) parent.getAttributes().get(UIComponent.BEANINFO_KEY);
  63. if (null == componentBeanInfo) {
  64. throw new TagException(tag, "Composite component does not have BeanInfo attribute");
  65. }
  66. BeanDescriptor componentDescriptor = componentBeanInfo.getBeanDescriptor();
  67. if (null == componentDescriptor) {
  68. throw new TagException(tag, "Composite component BeanInfo does not have BeanDescriptor");
  69. }
  70. List<AttachedObjectTarget> targetList = (List<AttachedObjectTarget>)componentDescriptor.getValue(AttachedObjectTarget.ATTACHED_OBJECT_TARGETS_KEY);
  71. if (null == targetList && !tagApplied) {
  72. throw new TagException(tag, "Composite component does not support behavior events");
  73. }
  74. boolean supportedEvent = false;
  75. for (AttachedObjectTarget target : targetList) {
  76. if (target instanceof BehaviorHolderAttachedObjectTarget) {
  77. BehaviorHolderAttachedObjectTarget behaviorTarget = (BehaviorHolderAttachedObjectTarget) target;
  78. if ((null != eventName && eventName.equals(behaviorTarget.getName()))
  79. || (null == eventName && behaviorTarget.isDefaultEvent())) {
  80. supportedEvent = true;
  81. break;
  82. }
  83. }
  84. }
  85. if(supportedEvent) {
  86. // Workaround to implementation specific composite component handlers
  87. FacesContext context = FacesContext.getCurrentInstance();
  88. if (context.getExternalContext().getApplicationMap().containsKey("com.sun.faces.ApplicationAssociate")) {
  89. addAttachedObjectHandlerToMojarra(parent);
  90. }
  91. else {
  92. addAttachedObjectHandlerToMyFaces(parent, faceletContext);
  93. }
  94. }
  95. else {
  96. if (!tagApplied) {
  97. throw new TagException(tag, "Composite component does not support event " + eventName);
  98. }
  99. }
  100. }
  101. else if (parent instanceof ClientBehaviorHolder) {
  102. applyAttachedObject(faceletContext, parent);
  103. }
  104. else {
  105. throw new TagException(this.tag, "Unable to attach behavior to non-ClientBehaviorHolder parent");
  106. }
  107. }
  108. public String getEventName() {
  109. if (event == null) {
  110. return null;
  111. }
  112. if (event.isLiteral()) {
  113. return event.getValue();
  114. } else {
  115. FaceletContext faceletContext = getFaceletContext(FacesContext.getCurrentInstance());
  116. ValueExpression expression = event.getValueExpression(faceletContext, String.class);
  117. return (String) expression.getValue(faceletContext);
  118. }
  119. }
  120. protected abstract E createBehavior(FaceletContext ctx, String eventName);
  121. protected void setBehaviorAttribute(FaceletContext ctx, E behavior, TagAttribute attr, Class<?> type) {
  122. if (attr != null) {
  123. String attributeName = attr.getLocalName();
  124. if (attr.isLiteral()) {
  125. behavior.setLiteral(attributeName, attr.getObject(ctx, type));
  126. } else {
  127. behavior.setValueExpression(attributeName, attr.getValueExpression(ctx, type));
  128. }
  129. }
  130. }
  131. protected FaceletContext getFaceletContext(FacesContext context) {
  132. FaceletContext faceletContext = (FaceletContext) context.getAttributes().get(FaceletContext.FACELET_CONTEXT_KEY);
  133. if (faceletContext == null) {
  134. faceletContext = (FaceletContext) context.getAttributes().get("com.sun.faces.facelets.FACELET_CONTEXT");
  135. }
  136. return faceletContext;
  137. }
  138. public void applyAttachedObject(FacesContext context, UIComponent parent) {
  139. FaceletContext faceletContext = getFaceletContext(context);
  140. applyAttachedObject(faceletContext, parent);
  141. }
  142. public void applyAttachedObject(FaceletContext faceletContext, UIComponent parent) {
  143. ClientBehaviorHolder holder = (ClientBehaviorHolder) parent;
  144. String eventName = getEventName();
  145. if (null == eventName) {
  146. eventName = holder.getDefaultEventName();
  147. if (null == eventName) {
  148. throw new TagException(this.tag, "Event attribute could not be determined: " + eventName);
  149. }
  150. } else {
  151. Collection<String> eventNames = holder.getEventNames();
  152. if (!eventNames.contains(eventName)) {
  153. throw new TagException(this.tag, "Event:" + eventName + " is not supported.");
  154. }
  155. }
  156. ClientBehaviorBase behavior = createBehavior(faceletContext, eventName);
  157. holder.addClientBehavior(eventName, behavior);
  158. }
  159. public String getFor() {
  160. return null;
  161. }
  162. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  163. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Mojarra ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  164. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  165. protected static String MOJARRA_ATTACHED_OBJECT_HANDLERS_KEY = "javax.faces.RetargetableHandlers";
  166. protected static String MOJARRA_22_ATTACHED_OBJECT_HANDLERS_KEY = "javax.faces.view.AttachedObjectHandlers";
  167. protected void addAttachedObjectHandlerToMojarra(UIComponent component) {
  168. String key = MOJARRA_ATTACHED_OBJECT_HANDLERS_KEY;
  169. if (RequestContext.getCurrentInstance().getApplicationContext().getConfig().isAtLeastJSF22())
  170. {
  171. key = MOJARRA_22_ATTACHED_OBJECT_HANDLERS_KEY;
  172. }
  173. Map<String, Object> attrs = component.getAttributes();
  174. List<AttachedObjectHandler> result = (List<AttachedObjectHandler>) attrs.get(key);
  175. if (result == null) {
  176. result = new ArrayList<AttachedObjectHandler>();
  177. attrs.put(key, result);
  178. }
  179. result.add(this);
  180. }
  181. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  182. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ MyFaces ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  183. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  184. protected static Method MYFACES_GET_COMPOSITION_CONTEXT_INSTANCE;
  185. protected static Method MYFACES_ADD_ATTACHED_OBJECT_HANDLER;
  186. protected void addAttachedObjectHandlerToMyFaces(UIComponent component, FaceletContext ctx) {
  187. try {
  188. if (MYFACES_GET_COMPOSITION_CONTEXT_INSTANCE == null || MYFACES_ADD_ATTACHED_OBJECT_HANDLER == null) {
  189. Class<?> clazz = Class.forName("org.apache.myfaces.view.facelets.FaceletCompositionContext");
  190. MYFACES_GET_COMPOSITION_CONTEXT_INSTANCE = clazz.getDeclaredMethod("getCurrentInstance", FaceletContext.class);
  191. MYFACES_ADD_ATTACHED_OBJECT_HANDLER = clazz.getDeclaredMethod("addAttachedObjectHandler", UIComponent.class, AttachedObjectHandler.class);
  192. }
  193. Object faceletCompositionContextInstance = MYFACES_GET_COMPOSITION_CONTEXT_INSTANCE.invoke(null, ctx);
  194. MYFACES_ADD_ATTACHED_OBJECT_HANDLER.invoke(faceletCompositionContextInstance, component, this);
  195. }
  196. catch (Exception ex) {
  197. Logger.getLogger(AjaxBehaviorHandler.class.getName()).log(Level.SEVERE, "Could not add AttachedObjectHandler to MyFaces!", ex);
  198. }
  199. }
  200. }