1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.view.facelets.tag.composite;
20
21 import java.beans.IntrospectionException;
22 import java.beans.PropertyDescriptor;
23 import java.io.IOException;
24 import java.util.List;
25 import java.util.logging.Level;
26 import java.util.logging.Logger;
27
28 import javax.faces.application.ProjectStage;
29 import javax.faces.component.UIComponent;
30 import javax.faces.context.FacesContext;
31 import javax.faces.view.facelets.FaceletContext;
32 import javax.faces.view.facelets.TagAttribute;
33 import javax.faces.view.facelets.TagConfig;
34 import javax.faces.view.facelets.TagException;
35 import javax.faces.view.facelets.TagHandler;
36
37 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletAttribute;
38 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletTag;
39 import org.apache.myfaces.shared.util.ClassUtils;
40 import org.apache.myfaces.view.facelets.FaceletCompositionContext;
41
42
43
44
45
46 @JSFFaceletTag(name="composite:attribute")
47 public class AttributeHandler extends TagHandler implements InterfaceDescriptorCreator
48 {
49
50
51 private static final Logger log = Logger.getLogger(AttributeHandler.class.getName());
52
53
54
55
56
57 private static final String[] STANDARD_ATTRIBUTES_SORTED = new String[]
58 {
59 "default",
60 "displayName",
61 "expert",
62 "hidden",
63 "method-signature",
64 "name",
65 "preferred",
66 "required",
67 "shortDescription",
68 "targetAttributeName",
69 "targets",
70 "type"
71 };
72
73 @JSFFaceletAttribute(name="name",
74 className="javax.el.ValueExpression",
75 deferredValueType="java.lang.String",
76 required=true)
77 private final TagAttribute _name;
78
79 @JSFFaceletAttribute(name="targets",
80 className="javax.el.ValueExpression",
81 deferredValueType="java.lang.String")
82 private final TagAttribute _targets;
83
84
85
86
87
88
89 @JSFFaceletAttribute(name="default",
90 className="javax.el.ValueExpression",
91 deferredValueType="java.lang.String")
92 private final TagAttribute _default;
93
94
95
96
97 @JSFFaceletAttribute(name="displayName",
98 className="javax.el.ValueExpression",
99 deferredValueType="java.lang.String")
100 private final TagAttribute _displayName;
101
102
103
104
105
106
107
108 @JSFFaceletAttribute(name="required",
109 className="javax.el.ValueExpression",
110 deferredValueType="boolean")
111 private final TagAttribute _required;
112
113
114
115
116 @JSFFaceletAttribute(name="preferred",
117 className="javax.el.ValueExpression",
118 deferredValueType="boolean")
119 private final TagAttribute _preferred;
120
121
122
123
124 @JSFFaceletAttribute(name="expert",
125 className="javax.el.ValueExpression",
126 deferredValueType="boolean")
127 private final TagAttribute _expert;
128
129
130
131
132 @JSFFaceletAttribute(name="shortDescription",
133 className="javax.el.ValueExpression",
134 deferredValueType="java.lang.String")
135 private final TagAttribute _shortDescription;
136
137 @JSFFaceletAttribute(name="method-signature",
138 className="javax.el.ValueExpression",
139 deferredValueType="java.lang.String")
140 private final TagAttribute _methodSignature;
141
142 @JSFFaceletAttribute(name="type",
143 className="javax.el.ValueExpression",
144 deferredValueType="java.lang.String")
145 private final TagAttribute _type;
146
147
148
149
150
151
152 @JSFFaceletAttribute(name="hidden",
153 className="javax.el.ValueExpression",
154 deferredValueType="boolean")
155 protected final TagAttribute _hidden;
156
157 @JSFFaceletAttribute(name="targetAttributeName",
158 className="javax.el.ValueExpression",
159 deferredValueType="java.lang.String")
160 private final TagAttribute _targetAttributeName;
161
162
163
164
165
166 private boolean _cacheable;
167
168
169
170
171
172
173
174
175 private PropertyDescriptor _propertyDescriptor;
176
177 public AttributeHandler(TagConfig config)
178 {
179 super(config);
180 _name = getRequiredAttribute("name");
181 _targets = getAttribute("targets");
182 _default = getAttribute("default");
183 _displayName = getAttribute("displayName");
184 _required = getAttribute("required");
185 _preferred = getAttribute("preferred");
186 _expert = getAttribute("expert");
187 _shortDescription = getAttribute("shortDescription");
188 _methodSignature = getAttribute("method-signature");
189 _type = getAttribute("type");
190 _hidden = getAttribute("hidden");
191 _targetAttributeName = getAttribute("targetAttributeName");
192
193
194
195
196
197
198 final boolean development = FacesContext.getCurrentInstance()
199 .isProjectStage(ProjectStage.Development);
200
201 if (_name.isLiteral()
202 && (!development || _areDevelopmentAttributesLiteral()))
203 {
204
205
206
207
208
209
210 _cacheable = true;
211 if ( _targets == null && _default == null && _required == null &&
212 _methodSignature == null && _type == null && _targetAttributeName == null &&
213 !CompositeTagAttributeUtils.containsUnspecifiedAttributes(tag,
214 STANDARD_ATTRIBUTES_SORTED))
215 {
216 _propertyDescriptor = _createPropertyDescriptor(development);
217 }
218 }
219 else
220 {
221 _cacheable = false;
222 }
223 }
224
225
226
227
228
229
230 private boolean _areDevelopmentAttributesLiteral()
231 {
232 return CompositeTagAttributeUtils.areAttributesLiteral(
233 _displayName, _shortDescription, _expert, _hidden, _preferred);
234 }
235
236 public void apply(FaceletContext ctx, UIComponent parent)
237 throws IOException
238 {
239 UIComponent compositeBaseParent
240 = FaceletCompositionContext.getCurrentInstance(ctx).getCompositeComponentFromStack();
241
242 CompositeComponentBeanInfo beanInfo =
243 (CompositeComponentBeanInfo) compositeBaseParent.getAttributes()
244 .get(UIComponent.BEANINFO_KEY);
245
246 if (beanInfo == null)
247 {
248 if (log.isLoggable(Level.SEVERE))
249 {
250 log.severe("Cannot find composite bean descriptor UIComponent.BEANINFO_KEY ");
251 }
252 return;
253 }
254
255 List<PropertyDescriptor> attributeList = beanInfo.getPropertyDescriptorsList();
256
257 if (isCacheable())
258 {
259 if (_propertyDescriptor == null)
260 {
261 _propertyDescriptor = _createPropertyDescriptor(ctx);
262 }
263 attributeList.add(_propertyDescriptor);
264 }
265 else
266 {
267 PropertyDescriptor attribute = _createPropertyDescriptor(ctx);
268 attributeList.add(attribute);
269 }
270
271
272
273
274
275 }
276
277
278
279
280
281
282
283
284 private PropertyDescriptor _createPropertyDescriptor(boolean development)
285 {
286 try
287 {
288 CompositeComponentPropertyDescriptor attributeDescriptor =
289 new CompositeComponentPropertyDescriptor(_name.getValue());
290
291
292
293 if (development)
294 {
295 CompositeTagAttributeUtils.addDevelopmentAttributesLiteral(attributeDescriptor,
296 _displayName, _shortDescription, _expert, _hidden, _preferred);
297 }
298
299
300
301
302 return attributeDescriptor;
303 }
304 catch (IntrospectionException e)
305 {
306 if (log.isLoggable(Level.SEVERE))
307 {
308 log.log(Level.SEVERE, "Cannot create PropertyDescriptor for attribute ",e);
309 }
310 throw new TagException(tag,e);
311 }
312 }
313
314 private PropertyDescriptor _createPropertyDescriptor(FaceletContext ctx)
315 throws TagException, IOException
316 {
317 try
318 {
319 CompositeComponentPropertyDescriptor attributeDescriptor =
320 new CompositeComponentPropertyDescriptor(_name.getValue(ctx));
321
322
323
324 if (_targets != null)
325 {
326 attributeDescriptor.setValue("targets", _targets.getValueExpression(ctx, String.class));
327 }
328 if (_default != null)
329 {
330 if (_type != null)
331 {
332 String type = _type.getValue(ctx);
333 Class clazz = String.class;
334 if (type != null)
335 {
336 try
337 {
338 clazz = ClassUtils.javaDefaultTypeToClass(type);
339 }
340 catch (ClassNotFoundException e)
341 {
342
343 }
344 }
345
346 if (_default.isLiteral())
347 {
348
349 attributeDescriptor.setValue("default", _default.getObject(ctx, clazz));
350 }
351 else
352 {
353 attributeDescriptor.setValue("default", _default.getValueExpression(ctx, clazz));
354 }
355 }
356 else
357 {
358 attributeDescriptor.setValue("default", _default.getValueExpression(ctx, String.class));
359 }
360 }
361 if (_required != null)
362 {
363 attributeDescriptor.setValue("required", _required.getValueExpression(ctx, Boolean.class));
364 }
365 if (_methodSignature != null)
366 {
367 attributeDescriptor.setValue("method-signature",
368 _methodSignature.getValueExpression(ctx, String.class));
369 }
370 if (_type != null)
371 {
372 attributeDescriptor.setValue("type", _type.getValueExpression(ctx, String.class));
373 }
374 if (_targetAttributeName != null)
375 {
376 attributeDescriptor.setValue("targetAttributeName",
377 _targetAttributeName.getValueExpression(ctx, String.class));
378 }
379
380
381
382 if (ctx.getFacesContext().isProjectStage(ProjectStage.Development))
383 {
384 CompositeTagAttributeUtils.addDevelopmentAttributes(attributeDescriptor, ctx,
385 _displayName, _shortDescription, _expert, _hidden, _preferred);
386 }
387
388
389
390 CompositeTagAttributeUtils.addUnspecifiedAttributes(attributeDescriptor, tag,
391 STANDARD_ATTRIBUTES_SORTED, ctx);
392
393 return attributeDescriptor;
394 }
395 catch (IntrospectionException e)
396 {
397 if (log.isLoggable(Level.SEVERE))
398 {
399 log.log(Level.SEVERE, "Cannot create PropertyDescriptor for attribute ",e);
400 }
401 throw new TagException(tag,e);
402 }
403 }
404
405 public boolean isCacheable()
406 {
407 return _cacheable;
408 }
409
410 public void setCacheable(boolean cacheable)
411 {
412 _cacheable = cacheable;
413 }
414 }