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