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