1
2
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
35
36
37 public class CameliaComponentHandler extends CameliaComponentHandler0 {
38 private static final Log LOG = LogFactory
39 .getLog(CameliaComponentHandler.class);
40
41
42
43
44
45
46 private static interface IAttributeMetaData {
47 Metadata processAttribute(String expression,
48 IListenerType defaultListenerType, String attributeName,
49 TagAttribute tagAttribute);
50 }
51
52
53
54
55
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
312
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 }