View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
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  
48  import org.apache.myfaces.config.impl.digester.elements.Application;
49  import org.apache.myfaces.config.impl.digester.elements.Behavior;
50  import org.apache.myfaces.config.impl.digester.elements.Converter;
51  import org.apache.myfaces.config.impl.digester.elements.FacesConfig;
52  import org.apache.myfaces.spi.AnnotationProvider;
53  import org.apache.myfaces.spi.AnnotationProviderFactory;
54  
55  /**
56   * Configure all annotations that needs to be defined at startup.
57   * 
58   * <ul>
59   * <li>{@link javax.faces.component.FacesComponent}</li>
60   * <li>{@link javax.faces.convert.FacesConverter}</li>
61   * <li>{@link javax.faces.validator.FacesValidator}</li>
62   * <li>{@link javax.faces.render.FacesRenderer}</li>
63   * <li>{@link javax.faces.bean.ManagedBean}</li>
64   * <li>{@link javax.faces.bean.ManagedProperty}</li>
65   * <li>{@link javax.faces.render.FacesBehaviorRenderer}</li>
66   * </ul>
67   * <p>
68   * Some parts copied from org.apache.shale.tiger.view.faces.LifecycleListener2
69   * </p>
70   * 
71   * @since 2.0
72   * @author Leonardo Uribe (latest modification by $Author: lu4242 $)
73   * @version $Revision: 1179403 $ $Date: 2011-10-05 14:53:21 -0500 (Wed, 05 Oct 2011) $
74   */
75  public class AnnotationConfigurator
76  {
77      //private static final Log log = LogFactory.getLog(AnnotationConfigurator.class);
78      private static final Logger log = Logger.getLogger(AnnotationConfigurator.class.getName());
79  
80      /**
81       * <p>The render kit factory for this application.</p>
82       */
83      private RenderKitFactory rkFactory = null;
84  
85      public AnnotationConfigurator()
86      {
87      }
88  
89      public FacesConfig createFacesConfig(ExternalContext _externalContext, boolean metadataComplete)
90      {
91          if (!metadataComplete)
92          {
93              AnnotationProvider provider = AnnotationProviderFactory.getAnnotationProviderFactory(_externalContext).getAnnotationProvider(_externalContext);
94              Map<Class<? extends Annotation>,Set<Class<?>>> map = provider.getAnnotatedClasses(_externalContext);
95              return createFacesConfig(map);
96          }
97          return null;
98      }
99      /*
100     public void configure(final Application application, 
101             final FacesConfigDispenser<FacesConfig> dispenser,
102             boolean metadataComplete) throws FacesException
103     {
104         AnnotationProvider provider = AnnotationProviderFactory.getAnnotationProviderFactory(_externalContext).createAnnotationProvider(_externalContext);
105         Map<Class<? extends Annotation>,Set<Class<?>>> map = provider.getAnnotatedClasses(_externalContext);
106         configureClasses(application, dispenser, map);
107     }*/
108     
109     protected FacesConfig createFacesConfig(Map< Class<? extends Annotation>, Set<Class<?>> > map)
110     {
111         FacesConfig facesConfig = new FacesConfig();
112         
113         Set<Class<?>> classes = map.get(FacesComponent.class);
114         
115         if (classes != null && !classes.isEmpty())
116         {
117             for (Class<?> clazz : classes)
118             {
119                 FacesComponent comp = (FacesComponent) clazz
120                         .getAnnotation(FacesComponent.class);
121                 if (comp != null)
122                 {
123                     if (log.isLoggable(Level.FINEST))
124                     {
125                         log.finest("addComponent(" + comp.value() + ","
126                                 + clazz.getName() + ")");
127                     }
128                     
129                     facesConfig.addComponent(comp.value(), clazz.getName());
130                 }
131             }
132         }
133         
134         classes = map.get(FacesConverter.class);
135         if (classes != null && !classes.isEmpty())
136         {
137             for (Class<?> clazz : classes)
138             {
139                 FacesConverter conv = (FacesConverter) clazz
140                         .getAnnotation(FacesConverter.class);
141                 if (conv != null)
142                 {
143                     if (log.isLoggable(Level.FINEST))
144                     {
145                         log.finest("addConverter(" + conv.value() + ","
146                                 + clazz.getName() + ")");
147                     }
148                     //If there is a previous entry on Application Configuration Resources,
149                     //the entry there takes precedence
150                     boolean hasForClass = !Object.class.equals(conv.forClass());
151                     boolean hasValue = conv.value().length() > 0;
152                     if (hasForClass || hasValue)
153                     {
154                         Converter converter = new Converter();
155                         if (hasForClass)
156                         {
157                             converter.setForClass(conv.forClass().getName());
158                         }
159                         if (hasValue) {
160                             converter.setConverterId(conv.value());
161                         }
162                         converter.setConverterClass(clazz.getName());
163                         facesConfig.addConverter(converter);
164                     }
165                     else
166                     {   
167                         // TODO MartinKoci MYFACES-3053
168                         throw new FacesException("@FacesConverter must have value, forClass or both. Check annotation @FacesConverter on class: "  + clazz.getName());
169                     }
170                 }                
171             }
172         }
173         
174         classes = map.get(FacesValidator.class);
175         if (classes != null && !classes.isEmpty())
176         {
177             for (Class<?> clazz : classes)
178             {
179                 FacesValidator val = (FacesValidator) clazz
180                 .getAnnotation(FacesValidator.class);
181                 if (val != null)
182                 {
183                     if (log.isLoggable(Level.FINEST))
184                     {
185                         log.finest("addValidator(" + val.value() + "," + clazz.getName()
186                                 + ")");
187                     }
188                     facesConfig.addValidator(val.value(), clazz.getName());
189                     if (val.isDefault())
190                     {
191                         Application app = null;
192                         if(facesConfig.getApplications().isEmpty())
193                         {
194                             app = new Application();
195                         }
196                         else
197                         {
198                             app = (Application) facesConfig.getApplications().get(0);
199                         }
200                         app.addDefaultValidatorId(val.value());
201                     }
202                 }
203             }
204         }
205 
206         classes = map.get(FacesRenderer.class);
207         if (classes != null && !classes.isEmpty())
208         {
209             for (Class<?> clazz : classes)
210             {
211                 FacesRenderer rend = (FacesRenderer) clazz
212                 .getAnnotation(FacesRenderer.class);
213                 if (rend != null)
214                 {
215                     String renderKitId = rend.renderKitId();
216                     if (renderKitId == null)
217                     {
218                         renderKitId = RenderKitFactory.HTML_BASIC_RENDER_KIT;
219                     }
220                     if (log.isLoggable(Level.FINEST))
221                     {
222                         log.finest("addRenderer(" + renderKitId + ", "
223                                 + rend.componentFamily() + ", " + rend.rendererType()
224                                 + ", " + clazz.getName() + ")");
225                     }
226                     
227                     org.apache.myfaces.config.impl.digester.elements.RenderKit renderKit =
228                        (org.apache.myfaces.config.impl.digester.elements.RenderKit) facesConfig.getRenderKit(renderKitId);
229                     if (renderKit == null)
230                     {
231                         renderKit = new org.apache.myfaces.config.impl.digester.elements.RenderKit();
232                         facesConfig.addRenderKit(renderKit);
233                     }
234                     
235                     org.apache.myfaces.config.impl.digester.elements.Renderer renderer =
236                         new org.apache.myfaces.config.impl.digester.elements.Renderer();
237                     renderer.setComponentFamily(rend.componentFamily());
238                     renderer.setRendererClass(clazz.getName());
239                     renderer.setRendererType(rend.rendererType());
240                     renderKit.addRenderer(renderer);
241                 }        
242             }
243         }
244 
245         classes = map.get(ManagedBean.class);
246         if (classes != null && !classes.isEmpty())
247         {
248             for (Class<?> clazz : classes)
249             {
250                 javax.faces.bean.ManagedBean bean = 
251                     (javax.faces.bean.ManagedBean) clazz.getAnnotation(javax.faces.bean.ManagedBean.class);
252         
253                 if (bean != null)
254                 {
255                     if (log.isLoggable(Level.FINE))
256                     {
257                         log.fine("Class '" + clazz.getName() + "' has an @ManagedBean annotation");
258                     }
259                     
260                     org.apache.myfaces.config.impl.digester.elements.ManagedBean mbc =
261                         new org.apache.myfaces.config.impl.digester.elements.ManagedBean();
262                     String beanName = bean.name();
263                     
264                     if ((beanName == null) || beanName.equals ("")) {
265                         int index;
266                         
267                         // Missing name attribute algorithm: take the unqualified name and make the
268                         // first character lowercase.
269                         
270                         beanName = clazz.getName();
271                         index = beanName.lastIndexOf (".");
272                         
273                         if (index != -1) {
274                             beanName = beanName.substring (index + 1);
275                         }
276                         
277                         beanName = Character.toLowerCase (beanName.charAt (0)) +
278                             beanName.substring (1);
279                     }
280                     
281                     mbc.setName(beanName);
282                     mbc.setEager(Boolean.toString(bean.eager()));
283                     mbc.setBeanClass(clazz.getName());
284                     
285                     ApplicationScoped appScoped = (ApplicationScoped) clazz.getAnnotation(ApplicationScoped.class);
286                     if (appScoped != null)
287                     {
288                         mbc.setScope("application");
289                     }
290                     
291                     else
292                     {
293                         NoneScoped noneScoped = (NoneScoped) clazz.getAnnotation(NoneScoped.class);
294                         if (noneScoped != null)
295                         {
296                             mbc.setScope("none");
297                         }
298                         
299                         else
300                         {
301                             RequestScoped requestScoped = (RequestScoped) clazz.getAnnotation(RequestScoped.class);
302                             if (requestScoped != null)
303                             {
304                                 mbc.setScope("request");
305                             }
306                             
307                             else
308                             {
309                                 SessionScoped sessionScoped = (SessionScoped) clazz.getAnnotation(SessionScoped.class);
310                                 if (sessionScoped != null)
311                                 {
312                                     mbc.setScope("session");
313                                 }
314                                 
315                                 else
316                                 {
317                                     ViewScoped viewScoped = (ViewScoped) clazz.getAnnotation(ViewScoped.class);
318                                     if (viewScoped != null)
319                                     {
320                                         mbc.setScope("view");
321                                     }
322                                     
323                                     else {
324                                         CustomScoped customScoped = (CustomScoped) clazz.getAnnotation(CustomScoped.class);
325                                         if (customScoped != null)
326                                         {
327                                             mbc.setScope(customScoped.value());
328                                         }
329                                         
330                                         else
331                                         {
332                                             // No scope annotation means default of "request".
333                                             
334                                             mbc.setScope ("request");
335                                         }
336                                     }
337                                 }
338                             }
339                         }
340                     }
341                     
342                     Field[] fields = fields(clazz);
343                     for (Field field : fields)
344                     {
345                         if (log.isLoggable(Level.FINEST))
346                         {
347                             log.finest("  Scanning field '" + field.getName() + "'");
348                         }
349                         javax.faces.bean.ManagedProperty property = (javax.faces.bean.ManagedProperty) field
350                                 .getAnnotation(javax.faces.bean.ManagedProperty.class);
351                         if (property != null)
352                         {
353                             if (log.isLoggable(Level.FINE))
354                             {
355                                 log.fine("  Field '" + field.getName()
356                                         + "' has a @ManagedProperty annotation");
357                             }
358                             org.apache.myfaces.config.impl.digester.elements.ManagedProperty mpc = 
359                                 new org.apache.myfaces.config.impl.digester.elements.ManagedProperty();
360                             String name = property.name();
361                             if ((name == null) || "".equals(name))
362                             {
363                                 name = field.getName();
364                             }
365                             mpc.setPropertyName(name);
366                             mpc.setPropertyClass(field.getType().getName()); // FIXME - primitives, arrays, etc.
367                             mpc.setValue(property.value());
368                             mbc.addProperty(mpc);
369                             continue;
370                         }
371                     }
372                     facesConfig.addManagedBean(mbc);
373                 }        
374             }
375         }
376 
377         classes = map.get(NamedEvent.class);
378         if (classes != null && !classes.isEmpty())
379         {
380             for (Class<?> clazz : classes)
381             {
382                 NamedEvent namedEvent = (NamedEvent) clazz.getAnnotation (NamedEvent.class);
383         
384                 if (namedEvent != null) {
385                     // Can only apply @NamedEvent to ComponentSystemEvent subclasses.
386                     
387                     if (!ComponentSystemEvent.class.isAssignableFrom (clazz)) {
388                         // Just log this.  We'll catch it later in the runtime.
389                         
390                         if (log.isLoggable(Level.WARNING)) {
391                             log.warning (clazz.getName() + " is annotated with @javax.faces.event.NamedEvent, but does " +
392                                 "not extend javax.faces.event.ComponentSystemEvent");
393                         }
394                     }
395                     // Have to register @NamedEvent annotations with the NamedEventManager class since
396                     // we need to get access to this info later and can't from the dispenser (it's not a
397                     // singleton).
398                     org.apache.myfaces.config.impl.digester.elements.NamedEvent namedEventConfig = 
399                         new org.apache.myfaces.config.impl.digester.elements.NamedEvent();
400                     namedEventConfig.setEventClass(clazz.getName());
401                     namedEventConfig.setShortName(namedEvent.shortName());
402                     facesConfig.addNamedEvent(namedEventConfig);
403                 }
404             }
405         }
406     
407         classes = map.get(FacesBehavior.class);
408         if (classes != null && !classes.isEmpty())
409         {
410             for (Class<?> clazz : classes)
411             {
412                 FacesBehavior facesBehavior = (FacesBehavior) clazz.getAnnotation (FacesBehavior.class);
413         
414                 if (facesBehavior != null) {
415                     // Can only apply @FacesBehavior to Behavior implementors.
416                     
417                     if (!javax.faces.component.behavior.Behavior.class.isAssignableFrom (clazz)) {
418                         // Just log this.  We'll catch it later in the runtime.
419                         
420                         if (log.isLoggable(Level.WARNING)) {
421                             log.warning (clazz.getName() + " is annotated with @javax.faces.component.behavior.FacesBehavior, " +
422                                     "but does not implement javax.faces.component.behavior.Behavior");
423                         }
424                     }
425                     
426                     if (log.isLoggable(Level.FINEST)) {
427                         log.finest ("addBehavior(" + facesBehavior.value() + ", " + clazz.getName() + ")");
428                     }
429                     
430                     Behavior behavior = new Behavior();
431                     behavior.setBehaviorId(facesBehavior.value());
432                     behavior.setBehaviorClass(clazz.getName());
433                     facesConfig.addBehavior(behavior);
434                 }
435                 
436             }
437         }
438     
439         classes = map.get(FacesBehaviorRenderer.class);
440         if (classes != null && !classes.isEmpty())
441         {
442             for (Class<?> clazz : classes)
443             {
444                 FacesBehaviorRenderer facesBehaviorRenderer = (FacesBehaviorRenderer) clazz.getAnnotation (FacesBehaviorRenderer.class);
445         
446                 if (facesBehaviorRenderer != null) {
447                     String renderKitId = facesBehaviorRenderer.renderKitId();
448                     //RenderKit renderKit;
449                     
450                     if (log.isLoggable(Level.FINEST)) {
451                         log.finest ("addClientBehaviorRenderer(" + renderKitId + ", " + facesBehaviorRenderer.rendererType() + ", " +
452                              clazz.getName() + ")");
453                     }
454                     
455                     org.apache.myfaces.config.impl.digester.elements.RenderKit renderKit =
456                         (org.apache.myfaces.config.impl.digester.elements.RenderKit) facesConfig.getRenderKit(renderKitId);
457                     if (renderKit == null)
458                     {
459                         renderKit = new org.apache.myfaces.config.impl.digester.elements.RenderKit();
460                         facesConfig.addRenderKit(renderKit);
461                     }
462                     
463                     org.apache.myfaces.config.impl.digester.elements.ClientBehaviorRenderer cbr = 
464                         new org.apache.myfaces.config.impl.digester.elements.ClientBehaviorRenderer();
465                     cbr.setRendererType(facesBehaviorRenderer.rendererType());
466                     cbr.setRendererClass(clazz.getName());
467                     renderKit.addClientBehaviorRenderer(cbr);
468                 }
469             }
470         }
471         return facesConfig;
472     }
473     
474     /*
475     protected void configureClasses( Application application, 
476             FacesConfigDispenser<FacesConfig> dispenser, 
477             Map< Class<? extends Annotation>, Set<Class<?>> > map)
478     {
479         Set<Class<?>> classes = map.get(FacesComponent.class);
480         
481         if (classes != null && !classes.isEmpty())
482         {
483             for (Class<?> clazz : classes)
484             {
485                 FacesComponent comp = (FacesComponent) clazz
486                         .getAnnotation(FacesComponent.class);
487                 if (comp != null)
488                 {
489                     if (log.isLoggable(Level.FINEST))
490                     {
491                         log.finest("addComponent(" + comp.value() + ","
492                                 + clazz.getName() + ")");
493                     }
494                     
495                     //If there is a previous entry on Application Configuration Resources,
496                     //the entry there takes precedence
497                     if (dispenser.getComponentClass(comp.value()) == null)
498                     {
499                         application.addComponent(comp.value(), clazz.getName());                
500                     }
501                 }
502             }
503         }
504         
505         classes = map.get(FacesConverter.class);
506         if (classes != null && !classes.isEmpty())
507         {
508             for (Class<?> clazz : classes)
509             {
510                 FacesConverter conv = (FacesConverter) clazz
511                         .getAnnotation(FacesConverter.class);
512                 if (conv != null)
513                 {
514                     if (log.isLoggable(Level.FINEST))
515                     {
516                         log.finest("addConverter(" + conv.value() + ","
517                                 + clazz.getName() + ")");
518                     }
519                     //If there is a previous entry on Application Configuration Resources,
520                     //the entry there takes precedence
521                     if (!Object.class.equals(conv.forClass()))
522                     {
523                         application.addConverter(conv.forClass(), clazz.getName());
524                     }
525                     if (dispenser.getConverterClassById(conv.value()) == null &&
526                             conv.value() != null && !"".equals(conv.value()))
527                     {
528                         application.addConverter(conv.value(), clazz.getName());
529                     }
530                 }                
531             }
532         }
533         
534         classes = map.get(FacesValidator.class);
535         if (classes != null && !classes.isEmpty())
536         {
537             for (Class<?> clazz : classes)
538             {
539                 FacesValidator val = (FacesValidator) clazz
540                 .getAnnotation(FacesValidator.class);
541                 if (val != null)
542                 {
543                     if (log.isLoggable(Level.FINEST))
544                     {
545                         log.finest("addValidator(" + val.value() + "," + clazz.getName()
546                                 + ")");
547                     }
548                     //If there is a previous entry on Application Configuration Resources,
549                     //the entry there takes precedence
550                     if (dispenser.getValidatorClass(val.value()) == null)
551                     {
552                         application.addValidator(val.value(), clazz.getName());
553                         if (val.isDefault())
554                         {
555                             application.addDefaultValidatorId(val.value());
556                         }
557                     }
558                 }
559             }
560         }
561 
562         classes = map.get(FacesRenderer.class);
563         if (classes != null && !classes.isEmpty())
564         {
565             for (Class<?> clazz : classes)
566             {
567                 FacesRenderer rend = (FacesRenderer) clazz
568                 .getAnnotation(FacesRenderer.class);
569                 if (rend != null)
570                 {
571                     String renderKitId = rend.renderKitId();
572                     if (renderKitId == null)
573                     {
574                         renderKitId = RenderKitFactory.HTML_BASIC_RENDER_KIT;
575                     }
576                     if (log.isLoggable(Level.FINEST))
577                     {
578                         log.finest("addRenderer(" + renderKitId + ", "
579                                 + rend.componentFamily() + ", " + rend.rendererType()
580                                 + ", " + clazz.getName() + ")");
581                     }
582                     try
583                     {
584                         RenderKit rk = renderKitFactory().getRenderKit(null,
585                                 renderKitId);
586                         if (rk == null)
587                         {
588                             if (log.isLoggable(Level.SEVERE))
589                             {
590                                 log.severe("RenderKit "+renderKitId+" not found when adding @FacesRenderer annotation");
591                             }
592                             throw new FacesException("RenderKit "+renderKitId+" not found when adding @FacesRenderer annotation");
593                         }
594                         rk.addRenderer(rend.componentFamily(), rend.rendererType(),
595                                 (Renderer) clazz.newInstance());
596                     }
597                     catch (Exception e)
598                     {
599                         throw new FacesException(e);
600                     }
601                 }        
602             }
603         }
604 
605         classes = map.get(ManagedBean.class);
606         if (classes != null && !classes.isEmpty())
607         {
608             for (Class<?> clazz : classes)
609             {
610                 javax.faces.bean.ManagedBean bean = 
611                     (javax.faces.bean.ManagedBean) clazz.getAnnotation(javax.faces.bean.ManagedBean.class);
612         
613                 if (bean != null)
614                 {
615                     if (log.isLoggable(Level.FINE))
616                     {
617                         log.fine("Class '" + clazz.getName() + "' has an @ManagedBean annotation");
618                     }
619                     RuntimeConfig runtimeConfig = RuntimeConfig.getCurrentInstance(_externalContext);
620                     org.apache.myfaces.config.impl.digester.elements.ManagedBean mbc =
621                         new org.apache.myfaces.config.impl.digester.elements.ManagedBean();
622                     String beanName = bean.name();
623                     
624                     if ((beanName == null) || beanName.equals ("")) {
625                         int index;
626                         
627                         // Missing name attribute algorithm: take the unqualified name and make the
628                         // first character lowercase.
629                         
630                         beanName = clazz.getName();
631                         index = beanName.lastIndexOf (".");
632                         
633                         if (index != -1) {
634                             beanName = beanName.substring (index + 1);
635                         }
636                         
637                         beanName = Character.toLowerCase (beanName.charAt (0)) +
638                             beanName.substring (1);
639                     }
640                     
641                     mbc.setName(beanName);
642                     mbc.setEager(Boolean.toString(bean.eager()));
643                     mbc.setBeanClass(clazz.getName());
644                     
645                     ApplicationScoped appScoped = (ApplicationScoped) clazz.getAnnotation(ApplicationScoped.class);
646                     if (appScoped != null)
647                     {
648                         mbc.setScope("application");
649                     }
650                     
651                     else
652                     {
653                         NoneScoped noneScoped = (NoneScoped) clazz.getAnnotation(NoneScoped.class);
654                         if (noneScoped != null)
655                         {
656                             mbc.setScope("none");
657                         }
658                         
659                         else
660                         {
661                             RequestScoped requestScoped = (RequestScoped) clazz.getAnnotation(RequestScoped.class);
662                             if (requestScoped != null)
663                             {
664                                 mbc.setScope("request");
665                             }
666                             
667                             else
668                             {
669                                 SessionScoped sessionScoped = (SessionScoped) clazz.getAnnotation(SessionScoped.class);
670                                 if (sessionScoped != null)
671                                 {
672                                     mbc.setScope("session");
673                                 }
674                                 
675                                 else
676                                 {
677                                     ViewScoped viewScoped = (ViewScoped) clazz.getAnnotation(ViewScoped.class);
678                                     if (viewScoped != null)
679                                     {
680                                         mbc.setScope("view");
681                                     }
682                                     
683                                     else {
684                                         CustomScoped customScoped = (CustomScoped) clazz.getAnnotation(CustomScoped.class);
685                                         if (customScoped != null)
686                                         {
687                                             mbc.setScope(customScoped.value());
688                                         }
689                                         
690                                         else
691                                         {
692                                             // No scope annotation means default of "request".
693                                             
694                                             mbc.setScope ("request");
695                                         }
696                                     }
697                                 }
698                             }
699                         }
700                     }
701                     
702                     Field[] fields = fields(clazz);
703                     for (Field field : fields)
704                     {
705                         if (log.isLoggable(Level.FINEST))
706                         {
707                             log.finest("  Scanning field '" + field.getName() + "'");
708                         }
709                         javax.faces.bean.ManagedProperty property = (javax.faces.bean.ManagedProperty) field
710                                 .getAnnotation(javax.faces.bean.ManagedProperty.class);
711                         if (property != null)
712                         {
713                             if (log.isLoggable(Level.FINE))
714                             {
715                                 log.fine("  Field '" + field.getName()
716                                         + "' has a @ManagedProperty annotation");
717                             }
718                             org.apache.myfaces.config.impl.digester.elements.ManagedProperty mpc = 
719                                 new org.apache.myfaces.config.impl.digester.elements.ManagedProperty();
720                             String name = property.name();
721                             if ((name == null) || "".equals(name))
722                             {
723                                 name = field.getName();
724                             }
725                             mpc.setPropertyName(name);
726                             mpc.setPropertyClass(field.getType().getName()); // FIXME - primitives, arrays, etc.
727                             mpc.setValue(property.value());
728                             mbc.addProperty(mpc);
729                             continue;
730                         }
731                     }
732                     runtimeConfig.addManagedBean(mbc.getManagedBeanName(), mbc);
733                 }        
734             }
735         }
736 
737         classes = map.get(NamedEvent.class);
738         if (classes != null && !classes.isEmpty())
739         {
740             for (Class<?> clazz : classes)
741             {
742                 NamedEvent namedEvent = (NamedEvent) clazz.getAnnotation (NamedEvent.class);
743         
744                 if (namedEvent != null) {
745                     // Can only apply @NamedEvent to ComponentSystemEvent subclasses.
746                     
747                     if (!ComponentSystemEvent.class.isAssignableFrom (clazz)) {
748                         // Just log this.  We'll catch it later in the runtime.
749                         
750                         if (log.isLoggable(Level.WARNING)) {
751                             log.warning (clazz.getName() + " is annotated with @javax.faces.event.NamedEvent, but does " +
752                                 "not extend javax.faces.event.ComponentSystemEvent");
753                         }
754                         
755                         return;
756                     }
757                     
758                     // Have to register @NamedEvent annotations with the NamedEventManager class since
759                     // we need to get access to this info later and can't from the dispenser (it's not a
760                     // singleton).
761                     
762                     NamedEventManager.getInstance().addNamedEvent (namedEvent.shortName(),
763                         (Class<? extends ComponentSystemEvent>) clazz);
764                 }
765             }
766         }
767     
768         classes = map.get(FacesBehavior.class);
769         if (classes != null && !classes.isEmpty())
770         {
771             for (Class<?> clazz : classes)
772             {
773                 FacesBehavior facesBehavior = (FacesBehavior) clazz.getAnnotation (FacesBehavior.class);
774         
775                 if (facesBehavior != null) {
776                     // Can only apply @FacesBehavior to Behavior implementors.
777                     
778                     if (!Behavior.class.isAssignableFrom (clazz)) {
779                         // Just log this.  We'll catch it later in the runtime.
780                         
781                         if (log.isLoggable(Level.WARNING)) {
782                             log.warning (clazz.getName() + " is annotated with @javax.faces.component.behavior.FacesBehavior, " +
783                                     "but does not implement javax.faces.component.behavior.Behavior");
784                         }
785                     }
786                     
787                     if (log.isLoggable(Level.FINEST)) {
788                         log.finest ("addBehavior(" + facesBehavior.value() + ", " + clazz.getName() + ")");
789                     }
790                     
791                     application.addBehavior (facesBehavior.value(), clazz.getName());
792                 }
793                 
794             }
795         }
796     
797         classes = map.get(FacesBehaviorRenderer.class);
798         if (classes != null && !classes.isEmpty())
799         {
800             for (Class<?> clazz : classes)
801             {
802                 FacesBehaviorRenderer facesBehaviorRenderer = (FacesBehaviorRenderer) clazz.getAnnotation (FacesBehaviorRenderer.class);
803         
804                 if (facesBehaviorRenderer != null) {
805                     String renderKitId = facesBehaviorRenderer.renderKitId();
806                     RenderKit renderKit;
807                     
808                     if (log.isLoggable(Level.FINEST)) {
809                         log.finest ("addClientBehaviorRenderer(" + renderKitId + ", " + facesBehaviorRenderer.rendererType() + ", " +
810                              clazz.getName() + ")");
811                     }
812                     
813                     try {
814                         ClientBehaviorRenderer clientBehaviorRenderer;
815                         
816                         renderKit = renderKitFactory().getRenderKit (null, renderKitId);
817                         
818                         clientBehaviorRenderer = (ClientBehaviorRenderer) clazz.newInstance();
819                         
820                         renderKit.addClientBehaviorRenderer(facesBehaviorRenderer.rendererType(), clientBehaviorRenderer);
821                     }
822                     
823                     catch (Throwable e) {
824                         throw new FacesException (e);
825                     }
826                 }
827             }
828         }
829         */
830         /*
831         ListenerFor listenerFor = (ListenerFor) clazz.getAnnotation(ListenerFor.class);
832         if (listenerFor != null)
833         {
834             processListenerFor(application, clazz, listenerFor);
835         }
836         
837         ListenersFor listenersFor = (ListenersFor) clazz.getAnnotation(ListenersFor.class);
838         if (listenersFor != null)
839         {
840             for (ListenerFor item : listenersFor.value())
841             {
842                 processListenerFor(application, clazz, item);
843             }
844         }*/
845         
846         // TODO: All annotations scanned at startup must be configured here!
847     /*
848     }
849     */
850 
851     /**
852      * <p>Return an array of all <code>Field</code>s reflecting declared
853      * fields in this class, or in any superclass other than
854      * <code>java.lang.Object</code>.</p>
855      *
856      * @param clazz Class to be analyzed
857      */
858     private Field[] fields(Class<?> clazz) {
859 
860         Map<String,Field> fields = new HashMap<String,Field>();
861         do {
862             for (Field field : clazz.getDeclaredFields()) {
863                 if (!fields.containsKey(field.getName())) {
864                     fields.put(field.getName(), field);
865                 }
866             }
867         } while ((clazz = clazz.getSuperclass()) != Object.class);
868         return (Field[]) fields.values().toArray(new Field[fields.size()]);
869 
870     }
871 
872     /**
873      * <p>Return the <code>RenderKitFactory</code> for this application.</p>
874      */
875     /*
876     private RenderKitFactory renderKitFactory()
877     {
878 
879         if (rkFactory == null)
880         {
881             rkFactory = (RenderKitFactory) FactoryFinder
882                     .getFactory(FactoryFinder.RENDER_KIT_FACTORY);
883         }
884         return rkFactory;
885 
886     }*/
887 }