1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.config.annotation;
20
21 import java.lang.annotation.Annotation;
22 import java.lang.reflect.Field;
23 import java.util.HashMap;
24 import java.util.Map;
25 import java.util.Set;
26 import java.util.logging.Level;
27 import java.util.logging.Logger;
28
29 import javax.faces.FacesException;
30 import javax.faces.bean.ApplicationScoped;
31 import javax.faces.bean.CustomScoped;
32 import javax.faces.bean.ManagedBean;
33 import javax.faces.bean.NoneScoped;
34 import javax.faces.bean.RequestScoped;
35 import javax.faces.bean.SessionScoped;
36 import javax.faces.bean.ViewScoped;
37 import javax.faces.component.FacesComponent;
38 import javax.faces.component.behavior.FacesBehavior;
39 import javax.faces.context.ExternalContext;
40 import javax.faces.convert.FacesConverter;
41 import javax.faces.event.ComponentSystemEvent;
42 import javax.faces.event.NamedEvent;
43 import javax.faces.render.FacesBehaviorRenderer;
44 import javax.faces.render.FacesRenderer;
45 import javax.faces.render.RenderKitFactory;
46 import javax.faces.validator.FacesValidator;
47 import javax.faces.view.facelets.FaceletsResourceResolver;
48
49 import org.apache.myfaces.config.impl.digester.elements.ApplicationImpl;
50 import org.apache.myfaces.config.impl.digester.elements.BehaviorImpl;
51 import org.apache.myfaces.config.impl.digester.elements.ComponentTagDeclarationImpl;
52 import org.apache.myfaces.config.impl.digester.elements.ConverterImpl;
53 import org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl;
54 import org.apache.myfaces.spi.AnnotationProvider;
55 import org.apache.myfaces.spi.AnnotationProviderFactory;
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77 public class AnnotationConfigurator
78 {
79 private static final Logger log = Logger.getLogger(AnnotationConfigurator.class.getName());
80
81 public AnnotationConfigurator()
82 {
83 }
84
85 public FacesConfigImpl createFacesConfig(ExternalContext externalcontext, boolean metadataComplete)
86 {
87 if (!metadataComplete)
88 {
89 AnnotationProvider provider = AnnotationProviderFactory.getAnnotationProviderFactory(externalcontext).
90 getAnnotationProvider(externalcontext);
91 Map<Class<? extends Annotation>, Set<Class<?>>> map = provider.getAnnotatedClasses(externalcontext);
92 return createFacesConfig(map);
93 }
94 return null;
95 }
96
97
98
99
100
101
102
103 protected FacesConfigImpl createFacesConfig(Map<Class<? extends Annotation>, Set<Class<?>>> map)
104 {
105 FacesConfigImpl facesConfig = new FacesConfigImpl();
106
107 Set<Class<?>> classes = map.get(FacesComponent.class);
108
109 if (classes != null && !classes.isEmpty())
110 {
111 for (Class<?> clazz : classes)
112 {
113 FacesComponent comp = (FacesComponent) clazz
114 .getAnnotation(FacesComponent.class);
115 if (comp != null)
116 {
117 if (log.isLoggable(Level.FINEST))
118 {
119 log.finest("addComponent(" + comp.value() + ","
120 + clazz.getName() + ")");
121 }
122 String value = comp.value();
123 if ( value == null ||
124 (value != null && value.length() <= 0))
125 {
126 String simpleName = clazz.getSimpleName();
127 value = Character.toLowerCase(simpleName.charAt(0)) + simpleName.substring(1);
128 }
129 facesConfig.addComponent(value, clazz.getName());
130
131 if (comp.createTag())
132 {
133 String tagName = comp.tagName();
134 if (tagName != null && tagName.length() > 0)
135 {
136
137 }
138 else
139 {
140 tagName = clazz.getSimpleName();
141 tagName = Character.toLowerCase(tagName.charAt(0)) + tagName.substring(1);
142 }
143 facesConfig.addComponentTagDeclaration(value,
144 new ComponentTagDeclarationImpl(value,
145 comp.namespace(), tagName));
146 }
147 }
148 }
149 }
150
151 classes = map.get(FacesConverter.class);
152 if (classes != null && !classes.isEmpty())
153 {
154 for (Class<?> clazz : classes)
155 {
156 FacesConverter conv = (FacesConverter) clazz
157 .getAnnotation(FacesConverter.class);
158 if (conv != null)
159 {
160 if (log.isLoggable(Level.FINEST))
161 {
162 log.finest("addConverter(" + conv.value() + ","
163 + clazz.getName() + ")");
164 }
165
166
167 boolean hasForClass = !Object.class.equals(conv.forClass());
168 boolean hasValue = conv.value().length() > 0;
169 if (hasForClass || hasValue)
170 {
171 ConverterImpl converter = new ConverterImpl();
172 if (hasForClass)
173 {
174 converter.setForClass(conv.forClass().getName());
175 }
176 if (hasValue)
177 {
178 converter.setConverterId(conv.value());
179 }
180 converter.setConverterClass(clazz.getName());
181 facesConfig.addConverter(converter);
182 }
183 else
184 {
185
186 throw new FacesException("@FacesConverter must have value, forClass or both. Check annotation "
187 + "@FacesConverter on class: " + clazz.getName());
188 }
189 }
190 }
191 }
192
193 classes = map.get(FacesValidator.class);
194 if (classes != null && !classes.isEmpty())
195 {
196 for (Class<?> clazz : classes)
197 {
198 FacesValidator val = (FacesValidator) clazz
199 .getAnnotation(FacesValidator.class);
200 if (val != null)
201 {
202 if (log.isLoggable(Level.FINEST))
203 {
204 log.finest("addValidator(" + val.value() + "," + clazz.getName()
205 + ")");
206 }
207 String value = val.value();
208 if ( value == null ||
209 (value != null && value.length() <= 0))
210 {
211 String simpleName = clazz.getSimpleName();
212 value = Character.toLowerCase(simpleName.charAt(0)) + simpleName.substring(1);
213 }
214 facesConfig.addValidator(value, clazz.getName());
215 if (val.isDefault())
216 {
217 ApplicationImpl app = null;
218 if (facesConfig.getApplications().isEmpty())
219 {
220 app = new ApplicationImpl();
221 }
222 else
223 {
224 app = (ApplicationImpl) facesConfig.getApplications().get(0);
225 }
226 app.addDefaultValidatorId(value);
227 }
228 }
229 }
230 }
231
232 classes = map.get(FacesRenderer.class);
233 if (classes != null && !classes.isEmpty())
234 {
235 for (Class<?> clazz : classes)
236 {
237 FacesRenderer rend = (FacesRenderer) clazz
238 .getAnnotation(FacesRenderer.class);
239 if (rend != null)
240 {
241 String renderKitId = rend.renderKitId();
242 if (renderKitId == null)
243 {
244 renderKitId = RenderKitFactory.HTML_BASIC_RENDER_KIT;
245 }
246 if (log.isLoggable(Level.FINEST))
247 {
248 log.finest("addRenderer(" + renderKitId + ", "
249 + rend.componentFamily() + ", " + rend.rendererType()
250 + ", " + clazz.getName() + ")");
251 }
252
253 org.apache.myfaces.config.impl.digester.elements.RenderKitImpl renderKit =
254 (org.apache.myfaces.config.impl.digester.elements.RenderKitImpl)
255 facesConfig.getRenderKit(renderKitId);
256 if (renderKit == null)
257 {
258 renderKit = new org.apache.myfaces.config.impl.digester.elements.RenderKitImpl();
259 renderKit.setId(renderKitId);
260 facesConfig.addRenderKit(renderKit);
261 }
262
263 org.apache.myfaces.config.impl.digester.elements.RendererImpl renderer =
264 new org.apache.myfaces.config.impl.digester.elements.RendererImpl();
265 renderer.setComponentFamily(rend.componentFamily());
266 renderer.setRendererClass(clazz.getName());
267 renderer.setRendererType(rend.rendererType());
268 renderKit.addRenderer(renderer);
269 }
270 }
271 }
272
273 classes = map.get(ManagedBean.class);
274 if (classes != null && !classes.isEmpty())
275 {
276 handleManagedBean(facesConfig, classes);
277 }
278
279 classes = map.get(NamedEvent.class);
280 if (classes != null && !classes.isEmpty())
281 {
282 handleNamedEvent(facesConfig, classes);
283 }
284
285 classes = map.get(FacesBehavior.class);
286 if (classes != null && !classes.isEmpty())
287 {
288 handleFacesBehavior(facesConfig, classes);
289 }
290
291 classes = map.get(FacesBehaviorRenderer.class);
292 if (classes != null && !classes.isEmpty())
293 {
294 handleFacesBehaviorRenderer(facesConfig, classes);
295 }
296
297 classes = map.get(FaceletsResourceResolver.class);
298 if (classes != null && !classes.isEmpty())
299 {
300 handleFaceletsResourceResolver(facesConfig, classes);
301 }
302
303 return facesConfig;
304 }
305
306 private void handleManagedBean(FacesConfigImpl facesConfig, Set<Class<?>> classes)
307 {
308 for (Class<?> clazz : classes)
309 {
310 javax.faces.bean.ManagedBean bean =
311 (javax.faces.bean.ManagedBean) clazz.getAnnotation(javax.faces.bean.ManagedBean.class);
312
313 if (bean != null)
314 {
315 if (log.isLoggable(Level.FINE))
316 {
317 log.fine("Class '" + clazz.getName() + "' has an @ManagedBean annotation");
318 }
319
320 org.apache.myfaces.config.impl.digester.elements.ManagedBeanImpl mbc =
321 new org.apache.myfaces.config.impl.digester.elements.ManagedBeanImpl();
322 String beanName = bean.name();
323
324 if ((beanName == null) || beanName.isEmpty())
325 {
326 int index;
327
328
329
330
331 beanName = clazz.getName();
332 index = beanName.lastIndexOf('.');
333
334 if (index != -1)
335 {
336 beanName = beanName.substring(index + 1);
337 }
338
339 beanName = Character.toLowerCase(beanName.charAt(0)) +
340 beanName.substring(1);
341 }
342
343 mbc.setName(beanName);
344 mbc.setEager(Boolean.toString(bean.eager()));
345 mbc.setBeanClass(clazz.getName());
346
347 ApplicationScoped appScoped = (ApplicationScoped) clazz.getAnnotation(ApplicationScoped.class);
348 if (appScoped != null)
349 {
350 mbc.setScope("application");
351 }
352
353 else
354 {
355 NoneScoped noneScoped = (NoneScoped) clazz.getAnnotation(NoneScoped.class);
356 if (noneScoped != null)
357 {
358 mbc.setScope("none");
359 }
360
361 else
362 {
363 RequestScoped requestScoped = (RequestScoped) clazz.getAnnotation(RequestScoped.class);
364 if (requestScoped != null)
365 {
366 mbc.setScope("request");
367 }
368
369 else
370 {
371 SessionScoped sessionScoped = (SessionScoped) clazz.getAnnotation(SessionScoped.class);
372 if (sessionScoped != null)
373 {
374 mbc.setScope("session");
375 }
376
377 else
378 {
379 ViewScoped viewScoped = (ViewScoped) clazz.getAnnotation(ViewScoped.class);
380 if (viewScoped != null)
381 {
382 mbc.setScope("view");
383 }
384
385 else
386 {
387 CustomScoped customScoped
388 = (CustomScoped) clazz.getAnnotation(CustomScoped.class);
389 if (customScoped != null)
390 {
391 mbc.setScope(customScoped.value());
392 }
393
394 else
395 {
396
397
398 mbc.setScope("request");
399 }
400 }
401 }
402 }
403 }
404 }
405
406 Field[] fields = fields(clazz);
407 for (Field field : fields)
408 {
409 if (log.isLoggable(Level.FINEST))
410 {
411 log.finest(" Scanning field '" + field.getName() + "'");
412 }
413 javax.faces.bean.ManagedProperty property = (javax.faces.bean.ManagedProperty) field
414 .getAnnotation(javax.faces.bean.ManagedProperty.class);
415 if (property != null)
416 {
417 if (log.isLoggable(Level.FINE))
418 {
419 log.fine(" Field '" + field.getName()
420 + "' has a @ManagedProperty annotation");
421 }
422 org.apache.myfaces.config.impl.digester.elements.ManagedPropertyImpl mpc =
423 new org.apache.myfaces.config.impl.digester.elements.ManagedPropertyImpl();
424 String name = property.name();
425 if ((name == null) || "".equals(name))
426 {
427 name = field.getName();
428 }
429 mpc.setPropertyName(name);
430 mpc.setPropertyClass(field.getType().getName());
431 mpc.setValue(property.value());
432 mbc.addProperty(mpc);
433 continue;
434 }
435 }
436 facesConfig.addManagedBean(mbc);
437 }
438 }
439 }
440
441 private void handleNamedEvent(FacesConfigImpl facesConfig, Set<Class<?>> classes)
442 {
443 for (Class<?> clazz : classes)
444 {
445 NamedEvent namedEvent = (NamedEvent) clazz.getAnnotation(NamedEvent.class);
446
447 if (namedEvent != null)
448 {
449
450
451 if (!ComponentSystemEvent.class.isAssignableFrom(clazz))
452 {
453
454
455 if (log.isLoggable(Level.WARNING))
456 {
457 log.warning(clazz.getName() + " is annotated with @javax.faces.event.NamedEvent, but does "
458 + "not extend javax.faces.event.ComponentSystemEvent");
459 }
460 }
461
462
463
464 org.apache.myfaces.config.impl.digester.elements.NamedEventImpl namedEventConfig =
465 new org.apache.myfaces.config.impl.digester.elements.NamedEventImpl();
466 namedEventConfig.setEventClass(clazz.getName());
467 namedEventConfig.setShortName(namedEvent.shortName());
468 facesConfig.addNamedEvent(namedEventConfig);
469 }
470 }
471 }
472
473 private void handleFacesBehavior(FacesConfigImpl facesConfig, Set<Class<?>> classes)
474 {
475 for (Class<?> clazz : classes)
476 {
477 FacesBehavior facesBehavior = (FacesBehavior) clazz.getAnnotation(FacesBehavior.class);
478
479 if (facesBehavior != null)
480 {
481
482
483 if (!javax.faces.component.behavior.Behavior.class.isAssignableFrom(clazz))
484 {
485
486
487 if (log.isLoggable(Level.WARNING))
488 {
489 log.warning(clazz.getName()
490 + " is annotated with @javax.faces.component.behavior.FacesBehavior, "
491 + "but does not implement javax.faces.component.behavior.Behavior");
492 }
493 }
494
495 if (log.isLoggable(Level.FINEST))
496 {
497 log.finest("addBehavior(" + facesBehavior.value() + ", " + clazz.getName() + ")");
498 }
499
500 BehaviorImpl behavior = new BehaviorImpl();
501 behavior.setBehaviorId(facesBehavior.value());
502 behavior.setBehaviorClass(clazz.getName());
503 facesConfig.addBehavior(behavior);
504 }
505
506 }
507 }
508
509 private void handleFacesBehaviorRenderer(FacesConfigImpl facesConfig, Set<Class<?>> classes)
510 {
511 for (Class<?> clazz : classes)
512 {
513 FacesBehaviorRenderer facesBehaviorRenderer
514 = (FacesBehaviorRenderer) clazz.getAnnotation(FacesBehaviorRenderer.class);
515
516 if (facesBehaviorRenderer != null)
517 {
518 String renderKitId = facesBehaviorRenderer.renderKitId();
519
520
521 if (log.isLoggable(Level.FINEST))
522 {
523 log.finest("addClientBehaviorRenderer(" + renderKitId + ", "
524 + facesBehaviorRenderer.rendererType() + ", "
525 + clazz.getName() + ")");
526 }
527
528 org.apache.myfaces.config.impl.digester.elements.RenderKitImpl renderKit =
529 (org.apache.myfaces.config.impl.digester.elements.RenderKitImpl)
530 facesConfig.getRenderKit(renderKitId);
531 if (renderKit == null)
532 {
533 renderKit = new org.apache.myfaces.config.impl.digester.elements.RenderKitImpl();
534 renderKit.setId(renderKitId);
535 facesConfig.addRenderKit(renderKit);
536 }
537
538 org.apache.myfaces.config.impl.digester.elements.ClientBehaviorRendererImpl cbr =
539 new org.apache.myfaces.config.impl.digester.elements.ClientBehaviorRendererImpl();
540 cbr.setRendererType(facesBehaviorRenderer.rendererType());
541 cbr.setRendererClass(clazz.getName());
542 renderKit.addClientBehaviorRenderer(cbr);
543 }
544 }
545 }
546
547 private void handleFaceletsResourceResolver(FacesConfigImpl facesConfig, Set<Class<?>> classes)
548 {
549 for (Class<?> clazz : classes)
550 {
551 FaceletsResourceResolver faceletsResourceResolver =
552 (FaceletsResourceResolver) clazz.getAnnotation(FaceletsResourceResolver.class);
553
554 if (faceletsResourceResolver != null)
555 {
556 facesConfig.addResourceResolver(clazz.getName());
557 }
558 }
559 }
560
561
562
563
564
565
566
567
568 private Field[] fields(Class<?> clazz)
569 {
570
571 Map<String, Field> fields = new HashMap<String, Field>();
572 do
573 {
574 for (Field field : clazz.getDeclaredFields())
575 {
576 if (!fields.containsKey(field.getName()))
577 {
578 fields.put(field.getName(), field);
579 }
580 }
581 clazz = clazz.getSuperclass();
582 }
583 while (clazz != Object.class);
584
585 return fields.values().toArray(new Field[fields.size()]);
586
587 }
588 }