View Javadoc

1   /*
2    * $Id: CameliaComponentHandler.java,v 1.14.2.2 2011/02/02 14:59:21 jbmeslin Exp $
3    */
4   package org.rcfaces.core.internal.facelets;
5   
6   import java.lang.reflect.Method;
7   import java.util.HashMap;
8   import java.util.Iterator;
9   import java.util.Map;
10  
11  import javax.el.ExpressionFactory;
12  import javax.el.MethodExpression;
13  import javax.faces.component.UIComponent;
14  
15  import org.apache.commons.logging.Log;
16  import org.apache.commons.logging.LogFactory;
17  import org.rcfaces.core.internal.lang.StringAppender;
18  import org.rcfaces.core.internal.tools.ListenersTools;
19  import org.rcfaces.core.internal.tools.ListenersTools.IListenerType;
20  
21  import com.sun.facelets.FaceletContext;
22  import com.sun.facelets.FaceletException;
23  import com.sun.facelets.el.TagMethodExpression;
24  import com.sun.facelets.tag.MetaRule;
25  import com.sun.facelets.tag.MetaRuleset;
26  import com.sun.facelets.tag.Metadata;
27  import com.sun.facelets.tag.MetadataTarget;
28  import com.sun.facelets.tag.TagAttribute;
29  import com.sun.facelets.tag.TextHandler;
30  import com.sun.facelets.tag.jsf.ComponentConfig;
31  
32  /**
33   * 
34   * @author Olivier Oeuillot (latest modification by $Author: jbmeslin $)
35   * @version $Revision: 1.14.2.2 $ $Date: 2011/02/02 14:59:21 $
36   */
37  public class CameliaComponentHandler extends CameliaComponentHandler0 {
38      private static final Log LOG = LogFactory
39              .getLog(CameliaComponentHandler.class);
40  
41      /**
42       * 
43       * @author Olivier Oeuillot (latest modification by $Author: jbmeslin $)
44       * @version $Revision: 1.14.2.2 $ $Date: 2011/02/02 14:59:21 $
45       */
46      private static interface IAttributeMetaData {
47          Metadata processAttribute(String expression,
48                  IListenerType defaultListenerType, String attributeName,
49                  TagAttribute tagAttribute);
50      }
51  
52      /**
53       * 
54       * @author Olivier Oeuillot (latest modification by $Author: jbmeslin $)
55       * @version $Revision: 1.14.2.2 $ $Date: 2011/02/02 14:59:21 $
56       */
57      private static class ListenerAttributeMetaData implements
58              IAttributeMetaData {
59          private static final String REVISION = "$Revision: 1.14.2.2 $";
60  
61          private final IListenerType listenerType;
62  
63          private ListenerAttributeMetaData(IListenerType listenerType) {
64              this.listenerType = listenerType;
65          }
66  
67          public Metadata processAttribute(final String expression,
68                  final IListenerType defaultListenerType, String attributeName,
69                  final TagAttribute tagAttribute) {
70              Metadata metadata = new Metadata() {
71                  public void applyMetadata(final FaceletContext ctx,
72                          Object instance) {
73                      ListenersTools.parseListener(ctx.getFacesContext(),
74                              (UIComponent) instance, listenerType, expression,
75                              listenerType == defaultListenerType,
76                              new ListenersTools.IMethodExpressionCreator() {
77  
78                                  public MethodExpression create(
79                                          String expression, Class[] paramTypes) {
80  
81                                      ExpressionFactory expressionFactory = ctx
82                                              .getExpressionFactory();
83  
84                                      MethodExpression methodExpression = expressionFactory
85                                              .createMethodExpression(ctx,
86                                                      expression, null,
87                                                      paramTypes);
88  
89                                      return new TagMethodExpression(
90                                              tagAttribute, methodExpression);
91                                  }
92                              });
93                  }
94              };
95  
96              return metadata;
97          }
98      }
99  
100     private static final Class[] ENUMERATION_PARAMETERS = new Class[] { String.class };
101 
102     private static IAttributeMetaData ENUMERATION_ATTRIBUTE_METADATA = new IAttributeMetaData() {
103         private static final String REVISION = "$Revision: 1.14.2.2 $";
104 
105         public Metadata processAttribute(final String expression,
106                 IListenerType defaultListenerType, final String attributeName,
107                 TagAttribute tagAttribute) {
108 
109             Metadata metadata = new Metadata() {
110                 public void applyMetadata(FaceletContext ctx, Object instance) {
111                     try {
112                         String setterMethodName = "set"
113                                 + Character
114                                         .toUpperCase(attributeName.charAt(0))
115                                 + attributeName.substring(1);
116 
117                         Method method = instance.getClass().getMethod(
118                                 setterMethodName, ENUMERATION_PARAMETERS);
119 
120                         method.invoke(instance, new Object[] { expression });
121 
122                     } catch (Throwable th) {
123                         throw new FaceletException(
124                                 "Can not set the value of attribute '"
125                                         + attributeName
126                                         + "'. (Use String parameter setter)",
127                                 th);
128                     }
129                 }
130 
131             };
132 
133             return metadata;
134         }
135     };
136 
137     private static final Map ATTRIBUTES_METADATA = new HashMap(32);
138     static {
139         ATTRIBUTES_METADATA.put("blurListener", new ListenerAttributeMetaData(
140                 ListenersTools.BLUR_LISTENER_TYPE));
141         ATTRIBUTES_METADATA.put("checkListener", new ListenerAttributeMetaData(
142                 ListenersTools.CHECK_LISTENER_TYPE));
143         ATTRIBUTES_METADATA.put("closeListener", new ListenerAttributeMetaData(
144                 ListenersTools.CLOSE_LISTENER_TYPE));
145         ATTRIBUTES_METADATA.put("doubleClickListener",
146                 new ListenerAttributeMetaData(
147                         ListenersTools.DOUBLE_CLICK_LISTENER_TYPE));
148         ATTRIBUTES_METADATA.put("focusListener", new ListenerAttributeMetaData(
149                 ListenersTools.FOCUS_LISTENER_TYPE));
150         ATTRIBUTES_METADATA.put("initListener", new ListenerAttributeMetaData(
151                 ListenersTools.INIT_LISTENER_TYPE));
152         ATTRIBUTES_METADATA.put("keyDownListener",
153                 new ListenerAttributeMetaData(
154                         ListenersTools.KEY_DOWN_LISTENER_TYPE));
155         ATTRIBUTES_METADATA.put("keyPressListener",
156                 new ListenerAttributeMetaData(
157                         ListenersTools.KEY_PRESS_LISTENER_TYPE));
158         ATTRIBUTES_METADATA.put("keyUpListener", new ListenerAttributeMetaData(
159                 ListenersTools.KEY_UP_LISTENER_TYPE));
160         ATTRIBUTES_METADATA.put("loadListener", new ListenerAttributeMetaData(
161                 ListenersTools.LOAD_LISTENER_TYPE));
162         ATTRIBUTES_METADATA.put("errorListener", new ListenerAttributeMetaData(
163                 ListenersTools.ERROR_LISTENER_TYPE));
164         ATTRIBUTES_METADATA.put("validationListener",
165                 new ListenerAttributeMetaData(
166                         ListenersTools.VALIDATION_LISTENER_TYPE));
167         ATTRIBUTES_METADATA.put("menuListener", new ListenerAttributeMetaData(
168                 ListenersTools.MENU_LISTENER_TYPE));
169         ATTRIBUTES_METADATA.put("mouseOutListener",
170                 new ListenerAttributeMetaData(
171                         ListenersTools.MOUSE_OUT_LISTENER_TYPE));
172         ATTRIBUTES_METADATA.put("mouseOverListener",
173                 new ListenerAttributeMetaData(
174                         ListenersTools.MOUSE_OVER_LISTENER_TYPE));
175         ATTRIBUTES_METADATA.put("propertyChangeListener",
176                 new ListenerAttributeMetaData(
177                         ListenersTools.PROPERTY_CHANGE_LISTENER_TYPE));
178         ATTRIBUTES_METADATA.put("resetListener", new ListenerAttributeMetaData(
179                 ListenersTools.RESET_LISTENER_TYPE));
180         ATTRIBUTES_METADATA.put("selectionListener",
181                 new ListenerAttributeMetaData(
182                         ListenersTools.SELECTION_LISTENER_TYPE));
183         ATTRIBUTES_METADATA.put("serviceEventListener",
184                 new ListenerAttributeMetaData(
185                         ListenersTools.SERVICE_EVENT_LISTENER_TYPE));
186         ATTRIBUTES_METADATA.put("sortListener", new ListenerAttributeMetaData(
187                 ListenersTools.SORT_LISTENER_TYPE));
188         ATTRIBUTES_METADATA.put("suggestionListener",
189                 new ListenerAttributeMetaData(
190                         ListenersTools.SUGGESTION_LISTENER_TYPE));
191         ATTRIBUTES_METADATA.put("userEventListener",
192                 new ListenerAttributeMetaData(
193                         ListenersTools.USER_EVENT_LISTENER_TYPE));
194         ATTRIBUTES_METADATA.put("valueChangeListener",
195                 new ListenerAttributeMetaData(
196                         ListenersTools.VALUE_CHANGE_LISTENER_TYPE));
197         ATTRIBUTES_METADATA.put("expandListener",
198                 new ListenerAttributeMetaData(
199                         ListenersTools.EXPAND_LISTENER_TYPE));
200         ATTRIBUTES_METADATA.put("preSelectionListener",
201                 new ListenerAttributeMetaData(
202                         ListenersTools.PRE_SELECTION_LISTENER_TYPE));
203         ATTRIBUTES_METADATA.put("dragListener",
204                 new ListenerAttributeMetaData(
205                         ListenersTools.DRAG_LISTENER_TYPE));
206         ATTRIBUTES_METADATA.put("dropListener",
207                 new ListenerAttributeMetaData(
208                         ListenersTools.DROP_LISTENER_TYPE));
209         ATTRIBUTES_METADATA.put("dropCompleteListener",
210                 new ListenerAttributeMetaData(
211                         ListenersTools.DROP_COMPLETE_LISTENER_TYPE));
212 
213         ATTRIBUTES_METADATA.put("action", new IAttributeMetaData() {
214             private static final String REVISION = "$Revision: 1.14.2.2 $";
215 
216             public Metadata processAttribute(final String expression,
217                     final IListenerType defaultListenerType,
218                     String attributeName, final TagAttribute tagAttribute) {
219                 return new Metadata() {
220                     public void applyMetadata(FaceletContext ctx,
221                             Object instance) {
222 
223                         actionApplyMetaData(ctx, (UIComponent) instance,
224                                 expression, defaultListenerType, tagAttribute);
225                     }
226                 };
227             }
228         });
229 
230         ATTRIBUTES_METADATA.put("hiddenMode", ENUMERATION_ATTRIBUTE_METADATA);
231         ATTRIBUTES_METADATA.put("asyncRenderMode",
232                 ENUMERATION_ATTRIBUTE_METADATA);
233         ATTRIBUTES_METADATA.put("checkCardinality",
234                 ENUMERATION_ATTRIBUTE_METADATA);
235         ATTRIBUTES_METADATA.put("selectionCardinality",
236                 ENUMERATION_ATTRIBUTE_METADATA);
237         ATTRIBUTES_METADATA.put("textPosition", ENUMERATION_ATTRIBUTE_METADATA);
238         ATTRIBUTES_METADATA.put("order", ENUMERATION_ATTRIBUTE_METADATA);
239         ATTRIBUTES_METADATA.put("mode", ENUMERATION_ATTRIBUTE_METADATA);
240         ATTRIBUTES_METADATA
241                 .put("literalLocale", ENUMERATION_ATTRIBUTE_METADATA);
242         ATTRIBUTES_METADATA.put("literalTimeZone",
243                 ENUMERATION_ATTRIBUTE_METADATA);
244         ATTRIBUTES_METADATA.put("componentLocale",
245                 ENUMERATION_ATTRIBUTE_METADATA);
246         ATTRIBUTES_METADATA.put("componentTimeZone",
247                 ENUMERATION_ATTRIBUTE_METADATA);
248         ATTRIBUTES_METADATA.put("clientDatesStrategy",
249                 ENUMERATION_ATTRIBUTE_METADATA);
250         ATTRIBUTES_METADATA.put("numberFormatType",
251                 ENUMERATION_ATTRIBUTE_METADATA);
252         ATTRIBUTES_METADATA.put("disabledWeekDays",
253                 ENUMERATION_ATTRIBUTE_METADATA);
254         ATTRIBUTES_METADATA.put("inputType", ENUMERATION_ATTRIBUTE_METADATA);
255 
256         ATTRIBUTES_METADATA.put("date", ENUMERATION_ATTRIBUTE_METADATA);
257         ATTRIBUTES_METADATA.put("maxDate", ENUMERATION_ATTRIBUTE_METADATA);
258         ATTRIBUTES_METADATA.put("minDate", ENUMERATION_ATTRIBUTE_METADATA);
259         ATTRIBUTES_METADATA.put("defaultDate", ENUMERATION_ATTRIBUTE_METADATA);
260 
261         ATTRIBUTES_METADATA.put("time", ENUMERATION_ATTRIBUTE_METADATA);
262         ATTRIBUTES_METADATA.put("maxTime", ENUMERATION_ATTRIBUTE_METADATA);
263         ATTRIBUTES_METADATA.put("minTime", ENUMERATION_ATTRIBUTE_METADATA);
264         ATTRIBUTES_METADATA.put("defaultTime", ENUMERATION_ATTRIBUTE_METADATA);
265 
266         ATTRIBUTES_METADATA.put("dragEffects", ENUMERATION_ATTRIBUTE_METADATA);
267         ATTRIBUTES_METADATA.put("dropEffects", ENUMERATION_ATTRIBUTE_METADATA);
268         ATTRIBUTES_METADATA.put("dragTypes", ENUMERATION_ATTRIBUTE_METADATA);
269         ATTRIBUTES_METADATA.put("dropTypes", ENUMERATION_ATTRIBUTE_METADATA);
270         ATTRIBUTES_METADATA.put("rowDragTypes", ENUMERATION_ATTRIBUTE_METADATA);
271         ATTRIBUTES_METADATA.put("rowDropTypes", ENUMERATION_ATTRIBUTE_METADATA);
272         
273         
274     }
275 
276     public CameliaComponentHandler(ComponentConfig config) {
277         super(config);
278     }
279 
280     protected MetaRuleset createMetaRuleset(Class type) {
281         MetaRuleset metaRuleset = super.createMetaRuleset(type);
282 
283         metaRuleset.addRule(new ComponentMetaRule(getDefaultListenerType()));
284 
285         return metaRuleset;
286     }
287 
288     protected IListenerType getDefaultListenerType() {
289         return null;
290     }
291 
292     protected final void setTextBody(FaceletContext ctx, UIComponent c) {
293         StringAppender content = null;
294         Iterator iter = findNextByType(TextHandler.class);
295         while (iter.hasNext()) {
296             TextHandler text = (TextHandler) iter.next();
297 
298             if (content == null) {
299                 content = new StringAppender();
300             }
301             content.append(text.getText(ctx));
302         }
303 
304         if (content != null && content.length() > 0) {
305             c.getAttributes().put("text", content.toString());
306         }
307     }
308 
309     /**
310      * 
311      * @author Olivier Oeuillot (latest modification by $Author: jbmeslin $)
312      * @version $Revision: 1.14.2.2 $ $Date: 2011/02/02 14:59:21 $
313      */
314     private static class ComponentMetaRule extends MetaRule {
315         private static final String REVISION = "$Revision: 1.14.2.2 $";
316 
317         private final IListenerType defaultListenerType;
318 
319         protected ComponentMetaRule(IListenerType defaultListenerType) {
320             this.defaultListenerType = defaultListenerType;
321         }
322 
323         public Metadata applyRule(String name, TagAttribute attribute,
324                 MetadataTarget meta) {
325 
326             if (LOG.isDebugEnabled()) {
327                 LOG.debug("Apply AttributeMetaData rule for attribute '" + name
328                         + "', tagAttribute='" + attribute + "', meta='" + meta
329                         + "', defaultListenerType='" + defaultListenerType
330                         + "'.");
331             }
332 
333             final String expression = attribute.getValue();
334             if (expression == null) {
335                 return null;
336             }
337 
338             IAttributeMetaData attributeMetaData = (IAttributeMetaData) ATTRIBUTES_METADATA
339                     .get(name);
340 
341             if (attributeMetaData == null) {
342                 if (LOG.isDebugEnabled()) {
343                     if (name.endsWith("Listener")) {
344                         LOG.error("No attributeMetaData for attribute '" + name
345                                 + "'");
346                     } else {
347                         LOG.debug("No attributeMetaData for attribute '" + name
348                                 + "'");
349                     }
350                 }
351                 return null;
352             }
353 
354             if (LOG.isDebugEnabled()) {
355                 LOG.debug("AttributeMetaData for attribute '" + name + "' => "
356                         + attributeMetaData);
357             }
358 
359             return attributeMetaData.processAttribute(expression,
360                     defaultListenerType, name, attribute);
361         }
362     }
363 }