Coverage Report - org.apache.myfaces.application.ApplicationImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
ApplicationImpl
0%
0/845
0%
0/446
4.028
ApplicationImpl$1
0%
0/2
N/A
4.028
ApplicationImpl$SystemListenerEntry
0%
0/40
0%
0/38
4.028
 
 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.application;
 20  
 
 21  
 import java.beans.BeanDescriptor;
 22  
 import java.beans.BeanInfo;
 23  
 import java.lang.reflect.Constructor;
 24  
 import java.util.ArrayList;
 25  
 import java.util.Arrays;
 26  
 import java.util.Collection;
 27  
 import java.util.Collections;
 28  
 import java.util.HashMap;
 29  
 import java.util.Iterator;
 30  
 import java.util.List;
 31  
 import java.util.Locale;
 32  
 import java.util.Map;
 33  
 import java.util.MissingResourceException;
 34  
 import java.util.TimeZone;
 35  
 import java.util.concurrent.ConcurrentHashMap;
 36  
 import java.util.concurrent.CopyOnWriteArrayList;
 37  
 import java.util.logging.Level;
 38  
 import java.util.logging.Logger;
 39  
 
 40  
 import javax.el.CompositeELResolver;
 41  
 import javax.el.ELContext;
 42  
 import javax.el.ELContextListener;
 43  
 import javax.el.ELException;
 44  
 import javax.el.ELResolver;
 45  
 import javax.el.ExpressionFactory;
 46  
 import javax.el.MethodExpression;
 47  
 import javax.el.ValueExpression;
 48  
 import javax.faces.FacesException;
 49  
 import javax.faces.application.Application;
 50  
 import javax.faces.application.NavigationHandler;
 51  
 import javax.faces.application.ProjectStage;
 52  
 import javax.faces.application.Resource;
 53  
 import javax.faces.application.ResourceDependencies;
 54  
 import javax.faces.application.ResourceDependency;
 55  
 import javax.faces.application.ResourceHandler;
 56  
 import javax.faces.application.StateManager;
 57  
 import javax.faces.application.ViewHandler;
 58  
 import javax.faces.component.UIComponent;
 59  
 import javax.faces.component.UIComponentBase;
 60  
 import javax.faces.component.UINamingContainer;
 61  
 import javax.faces.component.UIOutput;
 62  
 import javax.faces.component.UIViewRoot;
 63  
 import javax.faces.component.behavior.Behavior;
 64  
 import javax.faces.component.behavior.ClientBehaviorBase;
 65  
 import javax.faces.context.FacesContext;
 66  
 import javax.faces.convert.Converter;
 67  
 import javax.faces.convert.DateTimeConverter;
 68  
 import javax.faces.el.MethodBinding;
 69  
 import javax.faces.el.PropertyResolver;
 70  
 import javax.faces.el.ReferenceSyntaxException;
 71  
 import javax.faces.el.ValueBinding;
 72  
 import javax.faces.el.VariableResolver;
 73  
 import javax.faces.event.AbortProcessingException;
 74  
 import javax.faces.event.ActionListener;
 75  
 import javax.faces.event.ComponentSystemEventListener;
 76  
 import javax.faces.event.ListenerFor;
 77  
 import javax.faces.event.ListenersFor;
 78  
 import javax.faces.event.SystemEvent;
 79  
 import javax.faces.event.SystemEventListener;
 80  
 import javax.faces.event.SystemEventListenerHolder;
 81  
 import javax.faces.flow.FlowHandler;
 82  
 import javax.faces.render.ClientBehaviorRenderer;
 83  
 import javax.faces.render.RenderKit;
 84  
 import javax.faces.render.Renderer;
 85  
 import javax.faces.render.RendererWrapper;
 86  
 import javax.faces.validator.Validator;
 87  
 import javax.faces.view.ViewDeclarationLanguage;
 88  
 import javax.naming.Context;
 89  
 import javax.naming.InitialContext;
 90  
 import javax.naming.NamingException;
 91  
 
 92  
 import org.apache.commons.beanutils.BeanUtils;
 93  
 import org.apache.myfaces.application.cdi.ConverterWrapper;
 94  
 import org.apache.myfaces.cdi.util.ExternalArtifactResolver;
 95  
 import org.apache.myfaces.application.cdi.ValidatorWrapper;
 96  
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFWebConfigParam;
 97  
 import org.apache.myfaces.config.RuntimeConfig;
 98  
 import org.apache.myfaces.config.element.Property;
 99  
 import org.apache.myfaces.config.element.ResourceBundle;
 100  
 import org.apache.myfaces.context.RequestViewContext;
 101  
 import org.apache.myfaces.context.RequestViewMetadata;
 102  
 import org.apache.myfaces.el.PropertyResolverImpl;
 103  
 import org.apache.myfaces.el.VariableResolverToApplicationELResolverAdapter;
 104  
 import org.apache.myfaces.el.convert.MethodExpressionToMethodBinding;
 105  
 import org.apache.myfaces.el.convert.ValueBindingToValueExpression;
 106  
 import org.apache.myfaces.el.convert.ValueExpressionToValueBinding;
 107  
 import org.apache.myfaces.el.unified.ELResolverBuilder;
 108  
 import org.apache.myfaces.el.unified.ResolverBuilderForFaces;
 109  
 import org.apache.myfaces.el.unified.resolver.FacesCompositeELResolver;
 110  
 import org.apache.myfaces.el.unified.resolver.FacesCompositeELResolver.Scope;
 111  
 import org.apache.myfaces.flow.FlowHandlerImpl;
 112  
 import org.apache.myfaces.lifecycle.LifecycleImpl;
 113  
 import org.apache.myfaces.shared.config.MyfacesConfig;
 114  
 import org.apache.myfaces.shared.util.ClassUtils;
 115  
 import org.apache.myfaces.util.ExternalSpecifications;
 116  
 import org.apache.myfaces.view.facelets.FaceletCompositionContext;
 117  
 import org.apache.myfaces.view.facelets.el.ELText;
 118  
 
 119  
 /**
 120  
  * DOCUMENT ME!
 121  
  * 
 122  
  * @author Manfred Geiler (latest modification by $Author$)
 123  
  * @author Anton Koinov
 124  
  * @author Thomas Spiegl
 125  
  * @author Stan Silvert
 126  
  * @version $Revision$ $Date$
 127  
  */
 128  
 @SuppressWarnings("deprecation")
 129  0
 public class ApplicationImpl extends Application
 130  
 {
 131  
     //private static final Log log = LogFactory.getLog(ApplicationImpl.class);
 132  0
     private static final Logger log = Logger.getLogger(ApplicationImpl.class.getName());
 133  
 
 134  0
     private final static VariableResolver VARIABLERESOLVER = new VariableResolverToApplicationELResolverAdapter();
 135  
 
 136  0
     private final static PropertyResolver PROPERTYRESOLVER = new PropertyResolverImpl();
 137  
 
 138  
     // the name for the system property which specifies the current ProjectStage (see MYFACES-2545 for details)
 139  
     public final static String PROJECT_STAGE_SYSTEM_PROPERTY_NAME = "faces.PROJECT_STAGE";
 140  
     
 141  
     // MyFaces specific System Property to set the ProjectStage, if not present via the standard way
 142  
     @Deprecated
 143  
     public final static String MYFACES_PROJECT_STAGE_SYSTEM_PROPERTY_NAME = "org.apache.myfaces.PROJECT_STAGE";
 144  
     
 145  
     /**
 146  
      * Indicate the stage of the initialized application.
 147  
      */
 148  
     @JSFWebConfigParam(defaultValue="Production",
 149  
             expectedValues="Development, Production, SystemTest, UnitTest",
 150  
             since="2.0")
 151  
     private static final String PROJECT_STAGE_PARAM_NAME = "javax.faces.PROJECT_STAGE";
 152  
 
 153  
     /**
 154  
      * Indicate if the classes associated to components, converters, validators or behaviors
 155  
      * should be loaded as soon as they are added to the current application instance or instead
 156  
      * loaded in a lazy way.
 157  
      */
 158  
     @JSFWebConfigParam(defaultValue="true",since="2.0",tags="performance")
 159  
     private static final String LAZY_LOAD_CONFIG_OBJECTS_PARAM_NAME = "org.apache.myfaces.LAZY_LOAD_CONFIG_OBJECTS";
 160  
     private static final boolean LAZY_LOAD_CONFIG_OBJECTS_DEFAULT_VALUE = true;
 161  0
     private Boolean _lazyLoadConfigObjects = null;
 162  
     
 163  
     
 164  
     /**
 165  
      * Key under UIViewRoot to generated unique ids for components added 
 166  
      * by @ResourceDependency effect.
 167  
      */
 168  
     private static final String RESOURCE_DEPENDENCY_UNIQUE_ID_KEY =
 169  
               "oam.view.resourceDependencyUniqueId";
 170  
 
 171  
     // ~ Instance fields
 172  
     // --------------------------------------------------------------------------
 173  
     // --
 174  
 
 175  0
     private Collection<Locale> _supportedLocales = Collections.emptySet();
 176  
     private Locale _defaultLocale;
 177  
     private String _messageBundle;
 178  
 
 179  
     private ViewHandler _viewHandler;
 180  
     private NavigationHandler _navigationHandler;
 181  
     private ActionListener _actionListener;
 182  
     private String _defaultRenderKitId;
 183  
     private ResourceHandler _resourceHandler;
 184  
     private StateManager _stateManager;
 185  
     private FlowHandler _flowHandler;
 186  
 
 187  
     private ArrayList<ELContextListener> _elContextListeners;
 188  
 
 189  
     // components, converters, and validators can be added at runtime--must
 190  
     // synchronize, uses ConcurrentHashMap to allow concurrent read of map
 191  0
     private final Map<String, Object> _converterIdToClassMap = new ConcurrentHashMap<String, Object>();
 192  
 
 193  0
     private final Map<Class<?>, Object> _converterTargetClassToConverterClassMap
 194  
             = new ConcurrentHashMap<Class<?>, Object>();
 195  
     
 196  0
     private final Map<String, Object> _componentClassMap = new ConcurrentHashMap<String, Object>();
 197  
 
 198  0
     private final Map<String, Object> _validatorClassMap = new ConcurrentHashMap<String, Object>();
 199  
 
 200  0
     private final Map<Class<? extends SystemEvent>, SystemListenerEntry> _systemEventListenerClassMap
 201  
             = new ConcurrentHashMap<Class<? extends SystemEvent>, SystemListenerEntry>();
 202  
 
 203  0
     private final Map<String, String> _defaultValidatorsIds = new HashMap<String, String>();
 204  
     
 205  0
     private volatile Map<String, String> _cachedDefaultValidatorsIds = null;
 206  
     
 207  0
     private final Map<String, Object> _behaviorClassMap = new ConcurrentHashMap<String, Object>();
 208  
 
 209  
     private final RuntimeConfig _runtimeConfig;
 210  
 
 211  
     private ELResolver elResolver;
 212  
 
 213  
     private ELResolverBuilder resolverBuilderForFaces;
 214  
 
 215  
     private ProjectStage _projectStage;
 216  
 
 217  0
     private volatile boolean _firstRequestProcessed = false;
 218  
     
 219  
     // MYFACES-3442 If HashMap or other non thread-safe structure is used, it is
 220  
     // possible to fall in a infinite loop under heavy load unless a synchronized block
 221  
     // is used to modify it or a ConcurrentHashMap.
 222  0
     private final Map<Class<?>, List<ListenerFor>> _classToListenerForMap
 223  
             = new ConcurrentHashMap<Class<?>, List<ListenerFor>>() ;
 224  
 
 225  0
     private final Map<Class<?>, List<ResourceDependency>> _classToResourceDependencyMap
 226  
             = new ConcurrentHashMap<Class<?>, List<ResourceDependency>>() ;
 227  
     
 228  0
     private List<Class<? extends Converter>> _noArgConstructorConverterClasses 
 229  
             = new CopyOnWriteArrayList<Class<? extends Converter>>();
 230  
     
 231  
     /** Value of javax.faces.DATETIMECONVERTER_DEFAULT_TIMEZONE_IS_SYSTEM_TIMEZONE parameter */
 232  0
     private boolean _dateTimeConverterDefaultTimeZoneIsSystemTimeZone = false; 
 233  
     
 234  
     private final ExternalArtifactResolver _externalArtifactResolver;
 235  
     
 236  
     /**
 237  
      * Represents semantic null in _componentClassMap. 
 238  
      */
 239  0
     private static final UIComponent NOTHING = new UIComponentBase()
 240  0
     {
 241  
         @Override
 242  
         public String getFamily()
 243  
         {
 244  0
             return null;
 245  
         }
 246  
     };
 247  
     
 248  
     // ~ Constructors
 249  
     // --------------------------------------------------------------------------
 250  
     // -----
 251  
 
 252  
     public ApplicationImpl()
 253  
     {
 254  0
         this(getRuntimeConfig());
 255  0
     }
 256  
 
 257  
     private static RuntimeConfig getRuntimeConfig()
 258  
     {
 259  0
         return RuntimeConfig.getCurrentInstance(
 260  
                 FacesContext.getCurrentInstance().getExternalContext());
 261  
     }
 262  
 
 263  
     ApplicationImpl(final RuntimeConfig runtimeConfig)
 264  0
     {
 265  0
         if (runtimeConfig == null)
 266  
         {
 267  0
             throw new IllegalArgumentException("runtimeConfig must mot be null");
 268  
         }
 269  
         // set default implementation in constructor
 270  
         // pragmatic approach, no syncronizing will be needed in get methods
 271  0
         _viewHandler = new ViewHandlerImpl();
 272  0
         _navigationHandler = new NavigationHandlerImpl();
 273  0
         _actionListener = new ActionListenerImpl();
 274  0
         _defaultRenderKitId = "HTML_BASIC";
 275  0
         _stateManager = new StateManagerImpl();
 276  0
         _elContextListeners = new ArrayList<ELContextListener>();
 277  0
         _resourceHandler = new ResourceHandlerImpl();
 278  0
         _flowHandler = new FlowHandlerImpl();
 279  0
         _runtimeConfig = runtimeConfig;
 280  
 
 281  0
         if (log.isLoggable(Level.FINEST))
 282  
         {
 283  0
             log.finest("New Application instance created");
 284  
         }
 285  
         
 286  0
         String configParam = getFaceContext().getExternalContext().
 287  
                 getInitParameter(Converter.DATETIMECONVERTER_DEFAULT_TIMEZONE_IS_SYSTEM_TIMEZONE_PARAM_NAME);
 288  0
         if (configParam != null && configParam.toLowerCase().equals("true"))
 289  
         {
 290  0
             _dateTimeConverterDefaultTimeZoneIsSystemTimeZone = true;
 291  
         }
 292  
         
 293  0
         if (ExternalSpecifications.isCDIAvailable(getFaceContext().getExternalContext()))
 294  
         {
 295  0
             _externalArtifactResolver = (ExternalArtifactResolver) 
 296  
                 ClassUtils.newInstance(
 297  
                     "org.apache.myfaces.cdi.util.CDIExternalArtifactResolver");
 298  
         }
 299  
         else
 300  
         {
 301  0
             _externalArtifactResolver = null;
 302  
         }
 303  0
     }
 304  
 
 305  
     // ~ Methods
 306  
     // --------------------------------------------------------------------------
 307  
     // ----------
 308  
 
 309  
     @Override
 310  
     public final void addELResolver(final ELResolver resolver)
 311  
     {
 312  0
         if (isFirstRequestProcessed())
 313  
         {
 314  0
             throw new IllegalStateException("It is illegal to add a resolver after the first request is processed");
 315  
         }
 316  0
         if (resolver != null)
 317  
         {
 318  0
             _runtimeConfig.addApplicationElResolver(resolver);
 319  
         }
 320  0
     }
 321  
 
 322  
     @Override
 323  
     public void addDefaultValidatorId(String validatorId)
 324  
     {
 325  0
         if (_validatorClassMap.containsKey(validatorId))
 326  
         {
 327  0
             Class<? extends Validator> validatorClass =
 328  
                     getObjectFromClassMap(validatorId, _validatorClassMap);
 329  
 
 330  
             // Ensure atomicity between _defaultValidatorsIds and _cachedDefaultValidatorsIds
 331  0
             synchronized(_defaultValidatorsIds)
 332  
             {
 333  0
                 _defaultValidatorsIds.put(validatorId, validatorClass.getName());
 334  0
                 _cachedDefaultValidatorsIds = null;
 335  0
             }
 336  
         }
 337  0
     }
 338  
 
 339  
     @Override
 340  
     public Map<String, String> getDefaultValidatorInfo()
 341  
     {
 342  
         // cachedMap ensures we will not return null if after the check for null
 343  
         // _cachedDefaultValidatorsIds is set to null. In theory the unmodifiable map
 344  
         // always has a reference to _defaultValidatorsIds, so any instance set
 345  
         // in _cachedDefaultValidatorsIds is always the same.
 346  0
         Map<String, String> cachedMap = _cachedDefaultValidatorsIds;
 347  0
         if (cachedMap == null)
 348  
         {
 349  0
             synchronized(_defaultValidatorsIds)
 350  
             {
 351  0
                 if (_cachedDefaultValidatorsIds == null)
 352  
                 {
 353  0
                     _cachedDefaultValidatorsIds = Collections.unmodifiableMap(_defaultValidatorsIds);
 354  
                 }
 355  0
                 cachedMap = _cachedDefaultValidatorsIds;
 356  0
             }
 357  
         }
 358  0
         return cachedMap;
 359  
     }
 360  
 
 361  
     @Override
 362  
     public final ELResolver getELResolver()
 363  
     {
 364  
         // we don't need synchronization here since it is ok to have multiple
 365  
         // instances of the elresolver
 366  0
         if (elResolver == null)
 367  
         {
 368  0
             elResolver = createFacesResolver();
 369  
         }
 370  0
         return elResolver;
 371  
     }
 372  
 
 373  
     private ELResolver createFacesResolver()
 374  
     {
 375  0
         boolean supportJSPAndFacesEL = MyfacesConfig.getCurrentInstance(
 376  
                                 getFaceContext().getExternalContext()).isSupportJSPAndFacesEL();
 377  
         CompositeELResolver resolver;
 378  0
         if (supportJSPAndFacesEL)
 379  
         {
 380  0
             resolver = new FacesCompositeELResolver(Scope.Faces);
 381  
         }
 382  
         else
 383  
         {
 384  0
             resolver = new CompositeELResolver();
 385  
         }
 386  0
         getResolverBuilderForFaces().build(resolver);
 387  0
         return resolver;
 388  
     }
 389  
 
 390  
     protected final ELResolverBuilder getResolverBuilderForFaces()
 391  
     {
 392  0
         if (resolverBuilderForFaces == null)
 393  
         {
 394  0
             resolverBuilderForFaces = new ResolverBuilderForFaces(_runtimeConfig);
 395  
         }
 396  0
         return resolverBuilderForFaces;
 397  
     }
 398  
 
 399  
     public final void setResolverBuilderForFaces(final ELResolverBuilder factory)
 400  
     {
 401  0
         resolverBuilderForFaces = factory;
 402  0
     }
 403  
 
 404  
     @Override
 405  
     public final java.util.ResourceBundle getResourceBundle(final FacesContext facesContext, final String name)
 406  
             throws FacesException, NullPointerException
 407  
     {
 408  
 
 409  0
         checkNull(facesContext, "facesContext");
 410  0
         checkNull(name, "name");
 411  
 
 412  0
         final String bundleName = getBundleName(facesContext, name);
 413  
 
 414  0
         if (bundleName == null)
 415  
         {
 416  0
             return null;
 417  
         }
 418  
 
 419  0
         Locale locale = Locale.getDefault();
 420  
 
 421  0
         final UIViewRoot viewRoot = facesContext.getViewRoot();
 422  0
         if (viewRoot != null && viewRoot.getLocale() != null)
 423  
         {
 424  0
             locale = viewRoot.getLocale();
 425  
         }
 426  
 
 427  
         try
 428  
         {
 429  0
             return getResourceBundle(bundleName, locale, getClassLoader());
 430  
         }
 431  0
         catch (MissingResourceException e)
 432  
         {
 433  
             try
 434  
             {
 435  0
                 return getResourceBundle(bundleName, locale, this.getClass().getClassLoader());
 436  
             }
 437  0
             catch (MissingResourceException e1)
 438  
             {            
 439  0
                 throw new FacesException("Could not load resource bundle for name '"
 440  
                                          + name + "': " + e.getMessage(), e1);
 441  
             }
 442  
         }
 443  
     }
 444  
 
 445  
     private ClassLoader getClassLoader()
 446  
     {
 447  0
         return ClassUtils.getContextClassLoader();
 448  
     }
 449  
 
 450  
     String getBundleName(final FacesContext facesContext, final String name)
 451  
     {
 452  0
         ResourceBundle bundle = getRuntimeConfig(facesContext).getResourceBundle(name);
 453  0
         return bundle != null ? bundle.getBaseName() : null;
 454  
     }
 455  
 
 456  
     java.util.ResourceBundle getResourceBundle(final String name, final Locale locale, final ClassLoader loader)
 457  
             throws MissingResourceException
 458  
     {
 459  0
         return java.util.ResourceBundle.getBundle(name, locale, loader);
 460  
     }
 461  
 
 462  
     final RuntimeConfig getRuntimeConfig(final FacesContext facesContext)
 463  
     {
 464  0
         return RuntimeConfig.getCurrentInstance(facesContext.getExternalContext());
 465  
     }
 466  
 
 467  
     final FacesContext getFaceContext()
 468  
     {
 469  0
         return FacesContext.getCurrentInstance();
 470  
     }
 471  
 
 472  
     @Override
 473  
     public final UIComponent createComponent(final ValueExpression componentExpression,
 474  
                                              final FacesContext facesContext, final String componentType)
 475  
             throws FacesException, NullPointerException
 476  
     {
 477  
 
 478  
         /*
 479  
          * Before the component instance is returned, it must be inspected for the presence of a ListenerFor (or
 480  
          * ListenersFor) or ResourceDependency (or ResourceDependencies) annotation. If any of these annotations are
 481  
          * present, the action listed in ListenerFor or ResourceDependency must be taken on the component, 
 482  
          * before it is
 483  
          * returned from this method. This variant of createComponent must not inspect the Renderer for the 
 484  
          * component to
 485  
          * be returned for any of the afore mentioned annotations. Such inspection is the province of
 486  
          */
 487  
 
 488  0
         checkNull(componentExpression, "componentExpression");
 489  0
         checkNull(facesContext, "facesContext");
 490  0
         checkNull(componentType, "componentType");
 491  
 
 492  0
         ELContext elContext = facesContext.getELContext();
 493  
 
 494  
         try
 495  
         {
 496  0
             Object retVal = componentExpression.getValue(elContext);
 497  
 
 498  
             UIComponent createdComponent;
 499  
 
 500  0
             if (retVal instanceof UIComponent)
 501  
             {
 502  0
                 createdComponent = (UIComponent) retVal;
 503  0
                 _handleAnnotations(facesContext, createdComponent, createdComponent);
 504  
             }
 505  
             else
 506  
             {
 507  0
                 createdComponent = createComponent(facesContext, componentType);
 508  0
                 componentExpression.setValue(elContext, createdComponent);
 509  
             }
 510  
 
 511  0
             return createdComponent;
 512  
         }
 513  0
         catch (FacesException e)
 514  
         {
 515  0
             throw e;
 516  
         }
 517  0
         catch (Exception e)
 518  
         {
 519  0
             throw new FacesException(e);
 520  
         }
 521  
     }
 522  
 
 523  
     @Override
 524  
     public UIComponent createComponent(ValueExpression componentExpression, FacesContext context, 
 525  
                                        String componentType, String rendererType)
 526  
     {
 527  
         // Like createComponent(ValueExpression, FacesContext, String)
 528  0
         UIComponent component = createComponent(componentExpression, context, componentType);
 529  
 
 530  0
         if (rendererType != null)
 531  
         {
 532  0
             _inspectRenderer(context, component, componentType, rendererType);
 533  
         }
 534  
 
 535  0
         return component;
 536  
     }
 537  
 
 538  
     @Override
 539  
     public final ExpressionFactory getExpressionFactory()
 540  
     {
 541  0
         return _runtimeConfig.getExpressionFactory();
 542  
     }
 543  
 
 544  
     @SuppressWarnings("unchecked")
 545  
     @Override
 546  
     public final <T> T evaluateExpressionGet(final FacesContext context, final String expression,
 547  
                                              final Class<? extends T> expectedType) throws ELException
 548  
     {
 549  0
         ELContext elContext = context.getELContext();
 550  
 
 551  0
         ExpressionFactory factory = getExpressionFactory();
 552  
 
 553  0
         return (T) factory.createValueExpression(elContext, expression, expectedType).getValue(elContext);
 554  
     }
 555  
 
 556  
     @Override
 557  
     public final void addELContextListener(final ELContextListener listener)
 558  
     {
 559  0
         synchronized (_elContextListeners)
 560  
         {
 561  0
             _elContextListeners.add(listener);
 562  0
         }
 563  0
     }
 564  
 
 565  
     @Override
 566  
     public void publishEvent(FacesContext facesContext, Class<? extends SystemEvent> systemEventClass,
 567  
                              Class<?> sourceBaseType, Object source)
 568  
     {
 569  0
         checkNull(systemEventClass, "systemEventClass");
 570  0
         checkNull(source, "source");
 571  
         
 572  
         //Call events only if event processing is enabled.
 573  0
         if (!facesContext.isProcessingEvents())
 574  
         {
 575  0
             return;
 576  
         }
 577  
         
 578  
         // spec: If this argument is null the return from source.getClass() must be used as the sourceBaseType. 
 579  0
         if (sourceBaseType == null)
 580  
         {
 581  0
             sourceBaseType = source.getClass();
 582  
         }
 583  
         
 584  
         try
 585  
         {
 586  0
             SystemEvent event = null;
 587  0
             if (source instanceof SystemEventListenerHolder)
 588  
             {
 589  0
                 SystemEventListenerHolder holder = (SystemEventListenerHolder) source;
 590  
 
 591  
                 // If the source argument implements SystemEventListenerHolder, call
 592  
                 // SystemEventListenerHolder.getListenersForEventClass(java.lang.Class) on it, passing the
 593  
                 // systemEventClass
 594  
                 // argument. If the list is not empty, perform algorithm traverseListenerList on the list.
 595  0
                 event = _traverseListenerList(holder.getListenersForEventClass(systemEventClass), systemEventClass,
 596  
                                               source, event);
 597  
             }
 598  
             
 599  0
             UIViewRoot uiViewRoot = facesContext.getViewRoot();
 600  0
             if (uiViewRoot != null)
 601  
             {
 602  
                 //Call listeners on view level
 603  0
                 event = _traverseListenerListWithCopy(uiViewRoot.getViewListenersForEventClass(systemEventClass), 
 604  
                         systemEventClass, source, event);
 605  
             }
 606  
 
 607  0
             SystemListenerEntry systemListenerEntry = _systemEventListenerClassMap.get(systemEventClass);
 608  0
             if (systemListenerEntry != null)
 609  
             {
 610  0
                 systemListenerEntry.publish(systemEventClass, sourceBaseType, source, event);
 611  
             }
 612  
         }
 613  0
         catch (AbortProcessingException e)
 614  
         {
 615  
             // If the act of invoking the processListener method causes an AbortProcessingException to be thrown,
 616  
             // processing of the listeners must be aborted, no further processing of the listeners for this event must
 617  
             // take place, and the exception must be logged with Level.SEVERE.
 618  0
             log.log(Level.SEVERE, "Event processing was aborted", e);
 619  0
         }
 620  0
     }
 621  
 
 622  
     @Override
 623  
     public void publishEvent(FacesContext facesContext, Class<? extends SystemEvent> systemEventClass, Object source)
 624  
     {
 625  0
         publishEvent(facesContext, systemEventClass, source.getClass(), source);
 626  0
     }
 627  
 
 628  
     @Override
 629  
     public final void removeELContextListener(final ELContextListener listener)
 630  
     {
 631  0
         synchronized (_elContextListeners)
 632  
         {
 633  0
             _elContextListeners.remove(listener);
 634  0
         }
 635  0
     }
 636  
 
 637  
     @Override
 638  
     public final ELContextListener[] getELContextListeners()
 639  
     {
 640  
         // this gets called on every request, so I can't afford to synchronize
 641  
         // I just have to trust that toArray() with do the right thing if the
 642  
         // list is changing (not likely)
 643  0
         return _elContextListeners.toArray(new ELContextListener[_elContextListeners.size()]);
 644  
     }
 645  
 
 646  
     @Override
 647  
     public final void setActionListener(final ActionListener actionListener)
 648  
     {
 649  0
         checkNull(actionListener, "actionListener");
 650  
 
 651  0
         _actionListener = actionListener;
 652  0
         if (log.isLoggable(Level.FINEST))
 653  
         {
 654  0
             log.finest("set actionListener = " + actionListener.getClass().getName());
 655  
         }
 656  0
     }
 657  
 
 658  
     @Override
 659  
     public final ActionListener getActionListener()
 660  
     {
 661  0
         return _actionListener;
 662  
     }
 663  
 
 664  
     @Override
 665  
     public Iterator<String> getBehaviorIds()
 666  
     {
 667  0
         return _behaviorClassMap.keySet().iterator();
 668  
     }
 669  
 
 670  
     @Override
 671  
     public final Iterator<String> getComponentTypes()
 672  
     {
 673  0
         return _componentClassMap.keySet().iterator();
 674  
     }
 675  
 
 676  
     @Override
 677  
     public final Iterator<String> getConverterIds()
 678  
     {
 679  0
         return _converterIdToClassMap.keySet().iterator();
 680  
     }
 681  
 
 682  
     @Override
 683  
     public final Iterator<Class<?>> getConverterTypes()
 684  
     {
 685  0
         return _converterTargetClassToConverterClassMap.keySet().iterator();
 686  
     }
 687  
 
 688  
     @Override
 689  
     public final void setDefaultLocale(final Locale locale)
 690  
     {
 691  0
         checkNull(locale, "locale");
 692  
 
 693  0
         _defaultLocale = locale;
 694  0
         if (log.isLoggable(Level.FINEST))
 695  
         {
 696  0
             log.finest("set defaultLocale = " + locale.getCountry() + " " + locale.getLanguage());
 697  
         }
 698  0
     }
 699  
 
 700  
     @Override
 701  
     public final Locale getDefaultLocale()
 702  
     {
 703  0
         return _defaultLocale;
 704  
     }
 705  
 
 706  
     @Override
 707  
     public final void setMessageBundle(final String messageBundle)
 708  
     {
 709  0
         checkNull(messageBundle, "messageBundle");
 710  
 
 711  0
         _messageBundle = messageBundle;
 712  0
         if (log.isLoggable(Level.FINEST))
 713  
         {
 714  0
             log.finest("set MessageBundle = " + messageBundle);
 715  
         }
 716  0
     }
 717  
 
 718  
     @Override
 719  
     public final String getMessageBundle()
 720  
     {
 721  0
         return _messageBundle;
 722  
     }
 723  
 
 724  
     @Override
 725  
     public final void setNavigationHandler(final NavigationHandler navigationHandler)
 726  
     {
 727  0
         checkNull(navigationHandler, "navigationHandler");
 728  
 
 729  0
         _navigationHandler = navigationHandler;
 730  0
         if (log.isLoggable(Level.FINEST))
 731  
         {
 732  0
             log.finest("set NavigationHandler = " + navigationHandler.getClass().getName());
 733  
         }
 734  0
     }
 735  
 
 736  
     @Override
 737  
     public final NavigationHandler getNavigationHandler()
 738  
     {
 739  0
         return _navigationHandler;
 740  
     }
 741  
 
 742  
     /**
 743  
      * @deprecated
 744  
      */
 745  
     @Deprecated
 746  
     @Override
 747  
     public final void setPropertyResolver(final PropertyResolver propertyResolver)
 748  
     {
 749  0
         checkNull(propertyResolver, "propertyResolver");
 750  
 
 751  0
         if (getFaceContext() != null)
 752  
         {
 753  0
             throw new IllegalStateException("propertyResolver must be defined before request processing");
 754  
         }
 755  
 
 756  0
         _runtimeConfig.setPropertyResolver(propertyResolver);
 757  
 
 758  0
         if (log.isLoggable(Level.FINEST))
 759  
         {
 760  0
             log.finest("set PropertyResolver = " + propertyResolver.getClass().getName());
 761  
         }
 762  0
     }
 763  
 
 764  
     @Override
 765  
     public ProjectStage getProjectStage()
 766  
     {
 767  
         // If the value has already been determined by a previous call to this
 768  
         // method, simply return that value.
 769  0
         if (_projectStage == null)
 770  
         {
 771  0
             String stageName = null;
 772  
             
 773  
             // try to obtain the ProjectStage from the system property
 774  
             // faces.PROJECT_STAGE as proposed by Ed Burns
 775  0
             stageName = System.getProperty(PROJECT_STAGE_SYSTEM_PROPERTY_NAME);
 776  
             
 777  0
             if (stageName == null)
 778  
             {
 779  
                 // if not found check for the "old" System Property
 780  
                 // and print a warning message to the log (just to be 
 781  
                 // sure that everyone recognizes the change in the name).
 782  0
                 stageName = System.getProperty(MYFACES_PROJECT_STAGE_SYSTEM_PROPERTY_NAME);
 783  0
                 if (stageName != null)
 784  
                 {
 785  0
                     log.log(Level.WARNING, "The system property " + MYFACES_PROJECT_STAGE_SYSTEM_PROPERTY_NAME
 786  
                             + " has been replaced by " + PROJECT_STAGE_SYSTEM_PROPERTY_NAME + "!"
 787  
                             + " Please change your settings.");
 788  
                 }
 789  
             }
 790  
             
 791  0
             if (stageName == null)
 792  
             {
 793  
                 // Look for a JNDI environment entry under the key given by the
 794  
                 // value of ProjectStage.PROJECT_STAGE_JNDI_NAME (return type of
 795  
                 // java.lang.String).
 796  
                 try
 797  
                 {
 798  0
                     Context ctx = new InitialContext();
 799  0
                     Object temp = ctx.lookup(ProjectStage.PROJECT_STAGE_JNDI_NAME);
 800  0
                     if (temp != null)
 801  
                     {
 802  0
                         if (temp instanceof String)
 803  
                         {
 804  0
                             stageName = (String) temp;
 805  
                         }
 806  
                         else
 807  
                         {
 808  0
                             log.severe("JNDI lookup for key " + ProjectStage.PROJECT_STAGE_JNDI_NAME
 809  
                                     + " should return a java.lang.String value");
 810  
                         }
 811  
                     }
 812  
                 }
 813  0
                 catch (NamingException e)
 814  
                 {
 815  
                     // no-op
 816  
                 }
 817  0
                 catch (NoClassDefFoundError er)
 818  
                 {
 819  
                     //On Google App Engine, javax.naming.Context is a restricted class.
 820  
                     //In that case, NoClassDefFoundError is thrown. stageName needs to be configured
 821  
                     //below by context parameter.
 822  
                     //It can be done with changing the order to look first at
 823  
                     // context param, but it is defined in the spec.
 824  
                     //http://java.sun.com/javaee/6/docs/api/javax/faces/application/Application.html#getProjectStage()
 825  
                     //no-op
 826  0
                 }
 827  
             }
 828  
 
 829  
             /*
 830  
              * If found, continue with the algorithm below, otherwise, look for an entry in the initParamMap of the
 831  
              * ExternalContext from the current FacesContext with the key ProjectStage.PROJECT_STAGE_PARAM_NAME
 832  
              */
 833  0
             if (stageName == null)
 834  
             {
 835  0
                 FacesContext context = FacesContext.getCurrentInstance();
 836  0
                 stageName = context.getExternalContext().getInitParameter(ProjectStage.PROJECT_STAGE_PARAM_NAME);
 837  
             }
 838  
 
 839  
             // If a value is found
 840  0
             if (stageName != null)
 841  
             {
 842  
                 /*
 843  
                  * see if an enum constant can be obtained by calling ProjectStage.valueOf(), passing 
 844  
                  * the value from the initParamMap. If this succeeds without exception, save the value 
 845  
                  * and return it.
 846  
                  */
 847  
                 try
 848  
                 {
 849  0
                     _projectStage = ProjectStage.valueOf(stageName);
 850  0
                     return _projectStage;
 851  
                 }
 852  0
                 catch (IllegalArgumentException e)
 853  
                 {
 854  0
                     log.log(Level.INFO, "Couldn't discover the current project stage: "+stageName);
 855  0
                 }
 856  
             }
 857  
             else
 858  
             {
 859  0
                 if (log.isLoggable(Level.INFO))
 860  
                 {
 861  0
                     log.info("Couldn't discover the current project stage, using " + ProjectStage.Production);
 862  
                 }
 863  
             }
 864  
 
 865  
             /*
 866  
              * If not found, or any of the previous attempts to discover the enum constant value have failed, log a
 867  
              * descriptive error message, assign the value as ProjectStage.Production and return it.
 868  
              */
 869  
             
 870  0
             _projectStage = ProjectStage.Production;
 871  
         }
 872  
 
 873  0
         return _projectStage;
 874  
     }
 875  
 
 876  
     /**
 877  
      * @deprecated
 878  
      */
 879  
     @Deprecated
 880  
     @Override
 881  
     public final PropertyResolver getPropertyResolver()
 882  
     {
 883  0
         return PROPERTYRESOLVER;
 884  
     }
 885  
 
 886  
     @Override
 887  
     public final void setResourceHandler(ResourceHandler resourceHandler)
 888  
     {
 889  0
         checkNull(resourceHandler, "resourceHandler");
 890  
 
 891  0
         if(isFirstRequestProcessed())
 892  
         {
 893  0
             throw new IllegalStateException(
 894  
                     "setResourceHandler may not be executed after a lifecycle request has been completed");
 895  
         }
 896  0
         _resourceHandler = resourceHandler;
 897  0
     }
 898  
 
 899  
     @Override
 900  
     public final ResourceHandler getResourceHandler()
 901  
     {
 902  0
         return _resourceHandler;
 903  
     }
 904  
 
 905  
     @Override
 906  
     public final void setSupportedLocales(final Collection<Locale> locales)
 907  
     {
 908  0
         checkNull(locales, "locales");
 909  
 
 910  0
         _supportedLocales = locales;
 911  0
         if (log.isLoggable(Level.FINEST))
 912  
         {
 913  0
             log.finest("set SupportedLocales");
 914  
         }
 915  0
     }
 916  
 
 917  
     @Override
 918  
     public final Iterator<Locale> getSupportedLocales()
 919  
     {
 920  0
         return _supportedLocales.iterator();
 921  
     }
 922  
 
 923  
     @Override
 924  
     public final Iterator<String> getValidatorIds()
 925  
     {
 926  0
         return _validatorClassMap.keySet().iterator();
 927  
     }
 928  
 
 929  
     /**
 930  
      * @deprecated
 931  
      */
 932  
     @Deprecated
 933  
     @Override
 934  
     public final void setVariableResolver(final VariableResolver variableResolver)
 935  
     {
 936  0
         checkNull(variableResolver, "variableResolver");
 937  
 
 938  0
         if (isFirstRequestProcessed())
 939  
         {
 940  0
             throw new IllegalStateException("variableResolver must be defined before request processing");
 941  
         }
 942  
 
 943  0
         _runtimeConfig.setVariableResolver(variableResolver);
 944  
 
 945  0
         if (log.isLoggable(Level.FINEST))
 946  
         {
 947  0
             log.finest("set VariableResolver = " + variableResolver.getClass().getName());
 948  
         }
 949  0
     }
 950  
 
 951  
     /**
 952  
      * @deprecated
 953  
      */
 954  
     @Deprecated
 955  
     @Override
 956  
     public final VariableResolver getVariableResolver()
 957  
     {
 958  0
         return VARIABLERESOLVER;
 959  
     }
 960  
 
 961  
     @Override
 962  
     public final void setViewHandler(final ViewHandler viewHandler)
 963  
     {
 964  0
         checkNull(viewHandler, "viewHandler");
 965  
 
 966  0
         if(isFirstRequestProcessed())
 967  
         {
 968  0
             throw new IllegalStateException(
 969  
                     "setViewHandler may not be executed after a lifecycle request has been completed");
 970  
         }
 971  0
         _viewHandler = viewHandler;
 972  0
         if (log.isLoggable(Level.FINEST))
 973  
         {
 974  0
             log.finest("set ViewHandler = " + viewHandler.getClass().getName());
 975  
         }
 976  0
     }
 977  
     
 978  
     @Override
 979  
     public void subscribeToEvent(Class<? extends SystemEvent> systemEventClass, SystemEventListener listener)
 980  
     {
 981  0
         subscribeToEvent(systemEventClass, null, listener);
 982  0
     }
 983  
 
 984  
     @Override
 985  
     public void subscribeToEvent(Class<? extends SystemEvent> systemEventClass, Class<?> sourceClass,
 986  
                                  SystemEventListener listener)
 987  
     {
 988  0
         checkNull(systemEventClass, "systemEventClass");
 989  0
         checkNull(listener, "listener");
 990  
 
 991  
         SystemListenerEntry systemListenerEntry;
 992  0
         synchronized (_systemEventListenerClassMap)
 993  
         {
 994  0
             systemListenerEntry = _systemEventListenerClassMap.get(systemEventClass);
 995  0
             if (systemListenerEntry == null)
 996  
             {
 997  0
                 systemListenerEntry = new SystemListenerEntry();
 998  0
                 _systemEventListenerClassMap.put(systemEventClass, systemListenerEntry);
 999  
             }
 1000  0
         }
 1001  
 
 1002  0
         systemListenerEntry.addListener(listener, sourceClass);
 1003  0
     }
 1004  
     
 1005  
     @Override
 1006  
     public void unsubscribeFromEvent(Class<? extends SystemEvent> systemEventClass, SystemEventListener listener)
 1007  
     {
 1008  0
         unsubscribeFromEvent(systemEventClass, null, listener);
 1009  0
     }
 1010  
 
 1011  
     @Override
 1012  
     public void unsubscribeFromEvent(Class<? extends SystemEvent> systemEventClass, Class<?> sourceClass,
 1013  
                                      SystemEventListener listener)
 1014  
     {
 1015  0
         checkNull(systemEventClass, "systemEventClass");
 1016  0
         checkNull(listener, "listener");
 1017  
 
 1018  0
         SystemListenerEntry systemListenerEntry = _systemEventListenerClassMap.get(systemEventClass);
 1019  0
         if (systemListenerEntry != null)
 1020  
         {
 1021  0
             systemListenerEntry.removeListener(listener, sourceClass);
 1022  
         }
 1023  0
     }
 1024  
 
 1025  
     @Override
 1026  
     public final ViewHandler getViewHandler()
 1027  
     {
 1028  0
         return _viewHandler;
 1029  
     }
 1030  
 
 1031  
     @Override
 1032  
     public void addBehavior(String behaviorId, String behaviorClass)
 1033  
     {
 1034  0
         checkNull(behaviorId, "behaviorId");
 1035  0
         checkEmpty(behaviorId, "behaviorId");
 1036  0
         checkNull(behaviorClass, "behaviorClass");
 1037  0
         checkEmpty(behaviorClass, "behaviorClass");
 1038  
 
 1039  
         try
 1040  
         {
 1041  0
             if(isLazyLoadConfigObjects())
 1042  
             {
 1043  0
                 _behaviorClassMap.put(behaviorId, behaviorClass);
 1044  
             }
 1045  
             else
 1046  
             {
 1047  0
                 _behaviorClassMap.put(behaviorId, ClassUtils.simpleClassForName(behaviorClass));
 1048  
             }
 1049  
             
 1050  0
             if (log.isLoggable(Level.FINEST))
 1051  
             {
 1052  0
                 log.finest("add Behavior class = " + behaviorClass + " for id = " + behaviorId);
 1053  
             }
 1054  
         }
 1055  0
         catch (Exception e)
 1056  
         {
 1057  0
             log.log(Level.SEVERE, "Behavior class " + behaviorClass + " not found", e);
 1058  0
         }
 1059  
 
 1060  0
     }
 1061  
 
 1062  
     @Override
 1063  
     public final void addComponent(final String componentType, final String componentClassName)
 1064  
     {
 1065  0
         checkNull(componentType, "componentType");
 1066  0
         checkEmpty(componentType, "componentType");
 1067  0
         checkNull(componentClassName, "componentClassName");
 1068  0
         checkEmpty(componentClassName, "componentClassName");
 1069  
 
 1070  
         try
 1071  
         {
 1072  0
             if(isLazyLoadConfigObjects())
 1073  
             {
 1074  0
                 _componentClassMap.put(componentType, componentClassName);
 1075  
             }
 1076  
             else
 1077  
             {
 1078  0
                 _componentClassMap.put(componentType, ClassUtils.simpleClassForName(componentClassName));
 1079  
             }
 1080  
             
 1081  0
             if (log.isLoggable(Level.FINEST))
 1082  
             {
 1083  0
                 log.finest("add Component class = " + componentClassName + " for type = " + componentType);
 1084  
             }
 1085  
         }
 1086  0
         catch (Exception e)
 1087  
         {
 1088  0
             log.log(Level.SEVERE, "Component class " + componentClassName + " not found", e);
 1089  0
         }
 1090  0
     }
 1091  
 
 1092  
     @Override
 1093  
     public final void addConverter(final String converterId, final String converterClass)
 1094  
     {
 1095  0
         checkNull(converterId, "converterId");
 1096  0
         checkEmpty(converterId, "converterId");
 1097  0
         checkNull(converterClass, "converterClass");
 1098  0
         checkEmpty(converterClass, "converterClass");
 1099  
 
 1100  
         try
 1101  
         {
 1102  0
             if(isLazyLoadConfigObjects())
 1103  
             {
 1104  0
                 _converterIdToClassMap.put(converterId, converterClass);
 1105  
             }
 1106  
             else
 1107  
             {
 1108  0
                 _converterIdToClassMap.put(converterId, ClassUtils.simpleClassForName(converterClass));
 1109  
             }
 1110  0
             if (log.isLoggable(Level.FINEST))
 1111  
             {
 1112  0
                 log.finest("add Converter id = " + converterId + " converterClass = " + converterClass);
 1113  
             }
 1114  
         }
 1115  0
         catch (Exception e)
 1116  
         {
 1117  0
             log.log(Level.SEVERE, "Converter class " + converterClass + " not found", e);
 1118  0
         }
 1119  0
     }
 1120  
 
 1121  
     @Override
 1122  
     public final void addConverter(final Class<?> targetClass, final String converterClass)
 1123  
     {
 1124  0
         checkNull(targetClass, "targetClass");
 1125  0
         checkNull(converterClass, "converterClass");
 1126  0
         checkEmpty(converterClass, "converterClass");
 1127  
 
 1128  
         try
 1129  
         {
 1130  0
             if(isLazyLoadConfigObjects())
 1131  
             {
 1132  0
                 _converterTargetClassToConverterClassMap.put(targetClass, converterClass);
 1133  
             }
 1134  
             else
 1135  
             {
 1136  0
                 _converterTargetClassToConverterClassMap.put(targetClass,
 1137  
                                                              ClassUtils.simpleClassForName(converterClass));
 1138  
             }
 1139  
 
 1140  0
             if (log.isLoggable(Level.FINEST))
 1141  
             {
 1142  0
                 log.finest("add Converter for class = " + targetClass + " converterClass = " + converterClass);
 1143  
             }
 1144  
         }
 1145  0
         catch (Exception e)
 1146  
         {
 1147  0
             log.log(Level.SEVERE, "Converter class " + converterClass + " not found", e);
 1148  0
         }
 1149  0
     }
 1150  
 
 1151  
     @Override
 1152  
     public final void addValidator(final String validatorId, final String validatorClass)
 1153  
     {
 1154  0
         checkNull(validatorId, "validatorId");
 1155  0
         checkEmpty(validatorId, "validatorId");
 1156  0
         checkNull(validatorClass, "validatorClass");
 1157  0
         checkEmpty(validatorClass, "validatorClass");
 1158  
 
 1159  
         try
 1160  
         {
 1161  0
             if(isLazyLoadConfigObjects())
 1162  
             {
 1163  0
                 _validatorClassMap.put(validatorId, validatorClass);
 1164  
             }
 1165  
             else
 1166  
             {
 1167  0
                 _validatorClassMap.put(validatorId, ClassUtils.simpleClassForName(validatorClass));
 1168  
             }
 1169  
             
 1170  0
             if (log.isLoggable(Level.FINEST))
 1171  
             {
 1172  0
                 log.finest("add Validator id = " + validatorId + " class = " + validatorClass);
 1173  
             }
 1174  
         }
 1175  0
         catch (Exception e)
 1176  
         {
 1177  0
             log.log(Level.SEVERE, "Validator class " + validatorClass + " not found", e);
 1178  0
         }
 1179  0
     }
 1180  
 
 1181  
     @Override
 1182  
     public Behavior createBehavior(String behaviorId) throws FacesException
 1183  
     {
 1184  0
         checkNull(behaviorId, "behaviorId");
 1185  0
         checkEmpty(behaviorId, "behaviorId");
 1186  
 
 1187  0
         final Class<? extends Behavior> behaviorClass =
 1188  
                 getObjectFromClassMap(behaviorId, _behaviorClassMap);
 1189  
         
 1190  0
         if (behaviorClass == null)
 1191  
         {
 1192  0
             throw new FacesException("Could not find any registered behavior-class for behaviorId : " + behaviorId);
 1193  
         }
 1194  
         
 1195  
         try
 1196  
         {
 1197  0
             Behavior behavior = behaviorClass.newInstance();
 1198  0
             FacesContext facesContext = FacesContext.getCurrentInstance();
 1199  0
             _handleAttachedResourceDependencyAnnotations(facesContext, behavior);
 1200  
 
 1201  0
             if (behavior instanceof ClientBehaviorBase)
 1202  
             {
 1203  0
               ClientBehaviorBase clientBehavior = (ClientBehaviorBase) behavior;
 1204  0
               String renderType = clientBehavior.getRendererType();
 1205  0
               if (renderType != null)
 1206  
               {
 1207  0
                 ClientBehaviorRenderer cbr = facesContext.getRenderKit().getClientBehaviorRenderer(renderType);
 1208  0
                 _handleAttachedResourceDependencyAnnotations(facesContext, cbr);
 1209  
               }
 1210  
             }
 1211  
 
 1212  0
             return behavior;
 1213  
         }
 1214  0
         catch (Exception e)
 1215  
         {
 1216  0
             log.log(Level.SEVERE, "Could not instantiate behavior " + behaviorClass, e);
 1217  0
             throw new FacesException("Could not instantiate behavior: " + behaviorClass, e);
 1218  
         }
 1219  
     }
 1220  
 
 1221  
     @Override
 1222  
     public UIComponent createComponent(FacesContext context, Resource componentResource)
 1223  
     {
 1224  0
         checkNull(context, "context");
 1225  0
         checkNull(componentResource, "componentResource");
 1226  
         
 1227  0
         UIComponent component = null;
 1228  
         Resource resource;
 1229  
         String fqcn;
 1230  0
         Class<? extends UIComponent> componentClass = null;
 1231  
 
 1232  
         /*
 1233  
          * Obtain a reference to the ViewDeclarationLanguage for this Application instance by calling
 1234  
          * ViewHandler.getViewDeclarationLanguage(javax.faces.context.FacesContext, java.lang.String), passing the
 1235  
          * viewId found by calling UIViewRoot.getViewId() on the UIViewRoot in the argument FacesContext.
 1236  
          */
 1237  0
         UIViewRoot view = context.getViewRoot();
 1238  0
         Application application = context.getApplication();
 1239  0
         ViewDeclarationLanguage vdl
 1240  
                 = application.getViewHandler().getViewDeclarationLanguage(context, view.getViewId());
 1241  
 
 1242  
         /*
 1243  
          * Obtain a reference to the composite component metadata for this composite component by calling
 1244  
          * ViewDeclarationLanguage.getComponentMetadata(javax.faces.context.FacesContext,
 1245  
          * javax.faces.application.Resource), passing the facesContext and componentResource arguments to this method.
 1246  
          * This version of JSF specification uses JavaBeans as the API to the component metadata.
 1247  
          */
 1248  0
         BeanInfo metadata = vdl.getComponentMetadata(context, componentResource);
 1249  0
         if (metadata == null)
 1250  
         {
 1251  0
             throw new FacesException("Could not get component metadata for " 
 1252  
                     + componentResource.getResourceName()
 1253  
                     + ". Did you forget to specify <composite:interface>?");
 1254  
         }
 1255  
 
 1256  
         /*
 1257  
          * Determine if the component author declared a component-type for this component instance by obtaining the
 1258  
          * BeanDescriptor from the component metadata and calling its getValue() method, passing
 1259  
          * UIComponent.COMPOSITE_COMPONENT_TYPE_KEY as the argument. If non-null, the result must be a ValueExpression
 1260  
          * whose value is the component-type of the UIComponent to be created for this Resource component. Call through
 1261  
          * to createComponent(java.lang.String) to create the component.
 1262  
          */
 1263  0
         BeanDescriptor descriptor = metadata.getBeanDescriptor();
 1264  0
         ValueExpression componentType = (ValueExpression) descriptor.getValue(
 1265  
                 UIComponent.COMPOSITE_COMPONENT_TYPE_KEY);
 1266  0
         boolean annotationsApplied = false;
 1267  0
         if (componentType != null)
 1268  
         {
 1269  0
             component = application.createComponent((String) componentType.getValue(context.getELContext()));
 1270  0
             annotationsApplied = true;
 1271  
         }
 1272  
         else
 1273  
         {
 1274  
             /*
 1275  
              * Otherwise, determine if a script based component for this Resource can be found by calling
 1276  
              * ViewDeclarationLanguage.getScriptComponentResource(javax.faces.context.FacesContext,
 1277  
              * javax.faces.application.Resource). If the result is non-null, and is a script written in one of the
 1278  
              * languages listed in JSF 4.3 of the specification prose document, create a UIComponent instance from the
 1279  
              * script resource.
 1280  
              */
 1281  0
             resource = vdl.getScriptComponentResource(context, componentResource);
 1282  0
             if (resource != null)
 1283  
             {
 1284  0
                 String name = resource.getResourceName();
 1285  0
                 String className = name.substring(0, name.lastIndexOf('.'));
 1286  
 
 1287  0
                 component = (UIComponent)ClassUtils.newInstance(className);
 1288  0
             }
 1289  
             else
 1290  
             {
 1291  
                 /*
 1292  
                  * Otherwise, let library-name be the return from calling Resource.getLibraryName() on the argument
 1293  
                  * componentResource and resource-name be the return from calling Resource.getResourceName() on the
 1294  
                  * argument componentResource. Create a fully qualified Java class name by removing any file extension
 1295  
                  * from resource-name and let fqcn be library-name + "." + resource-name. If a class with the name of
 1296  
                  * fqcn cannot be found, take no action and continue to the next step. If any of 
 1297  
                  * InstantiationException,
 1298  
                  * IllegalAccessException, or ClassCastException are thrown, wrap the exception in a FacesException and
 1299  
                  * re-throw it. If any other exception is thrown, log the exception and continue to the next step.
 1300  
                  */
 1301  
 
 1302  0
                 boolean isProduction = FacesContext.getCurrentInstance().isProjectStage(ProjectStage.Production);
 1303  0
                 String name = componentResource.getResourceName();
 1304  0
                 String className = name.substring(0, name.lastIndexOf('.'));
 1305  0
                 fqcn = componentResource.getLibraryName() + "." + className;
 1306  
                 
 1307  0
                 if (isProduction)
 1308  
                 {
 1309  0
                     componentClass = (Class<? extends UIComponent>) _componentClassMap.get(fqcn);
 1310  
                 }
 1311  0
                 if (componentClass == null)
 1312  
                 {
 1313  
                     try
 1314  
                     {
 1315  0
                         componentClass = ClassUtils.classForName(fqcn);
 1316  0
                         if (isProduction)
 1317  
                         {
 1318  0
                             _componentClassMap.put(fqcn, componentClass);
 1319  
                         }
 1320  
                     }
 1321  0
                     catch (ClassNotFoundException e)
 1322  
                     {
 1323  
                         // Remember here that classForName did not find Class
 1324  0
                         if (isProduction)
 1325  
                         {
 1326  0
                             _componentClassMap.put(fqcn, NOTHING.getClass());
 1327  
                         }
 1328  0
                     }
 1329  
                 }
 1330  
 
 1331  0
                 if (componentClass != null && NOTHING.getClass() != componentClass)
 1332  
                 {
 1333  
                     try
 1334  
                     {
 1335  0
                         component = componentClass.newInstance();
 1336  
                     }
 1337  0
                     catch (InstantiationException e)
 1338  
                     {
 1339  0
                         log.log(Level.SEVERE, "Could not instantiate component class name = " + fqcn, e);
 1340  0
                         throw new FacesException("Could not instantiate component class name = " + fqcn, e);
 1341  
                     }
 1342  0
                     catch (IllegalAccessException e)
 1343  
                     {
 1344  0
                         log.log(Level.SEVERE, "Could not instantiate component class name = " + fqcn, e);
 1345  0
                         throw new FacesException("Could not instantiate component class name = " + fqcn, e);
 1346  
                     }
 1347  0
                     catch (Exception e)
 1348  
                     {
 1349  0
                         log.log(Level.SEVERE, "Could not instantiate component class name = " + fqcn, e);
 1350  0
                     }
 1351  
                 }
 1352  
 
 1353  
                 /*
 1354  
                  * If none of the previous steps have yielded a UIComponent instance, call
 1355  
                  * createComponent(java.lang.String) passing "javax.faces.NamingContainer" as the argument.
 1356  
                  */
 1357  0
                 if (component == null)
 1358  
                 {
 1359  0
                     component = application.createComponent(context, UINamingContainer.COMPONENT_TYPE, null);
 1360  0
                     annotationsApplied = true;
 1361  
                 }
 1362  
             }
 1363  
         }
 1364  
 
 1365  
         /*
 1366  
          * Call UIComponent.setRendererType(java.lang.String) on the UIComponent instance, passing
 1367  
          * "javax.faces.Composite" as the argument.
 1368  
          */
 1369  0
         component.setRendererType("javax.faces.Composite");
 1370  
 
 1371  
         /*
 1372  
          * Store the argument Resource in the attributes Map of the UIComponent under the key,
 1373  
          * Resource.COMPONENT_RESOURCE_KEY.
 1374  
          */
 1375  0
         component.getAttributes().put(Resource.COMPONENT_RESOURCE_KEY, componentResource);
 1376  
 
 1377  
         /*
 1378  
          * Store composite component metadata in the attributes Map of the UIComponent under the key,
 1379  
          * UIComponent.BEANINFO_KEY.
 1380  
          */
 1381  0
         component.getAttributes().put(UIComponent.BEANINFO_KEY, metadata);
 1382  
 
 1383  
         /*
 1384  
          * Before the component instance is returned, it must be inspected for the presence of a 
 1385  
          * ListenerFor annotation.
 1386  
          * If this annotation is present, the action listed in ListenerFor must be taken on the component, 
 1387  
          * before it is
 1388  
          * returned from this method.
 1389  
          */
 1390  0
         if (!annotationsApplied)
 1391  
         {
 1392  0
             _handleAnnotations(context, component, component);
 1393  
         }
 1394  
 
 1395  0
         return component;
 1396  
     }
 1397  
 
 1398  
     @Override
 1399  
     public UIComponent createComponent(FacesContext context, String componentType, String rendererType)
 1400  
     {
 1401  0
         checkNull(context, "context");
 1402  0
         checkNull(componentType, "componentType");
 1403  
 
 1404  
         // Like createComponent(String)
 1405  0
         UIComponent component = createComponent(context, componentType);
 1406  
 
 1407  
         // A null value on this field is valid! If that so, no need to do any log
 1408  
         // or look on RenderKit map for a inexistent renderer!
 1409  0
         if (rendererType != null)
 1410  
         {
 1411  0
             _inspectRenderer(context, component, componentType, rendererType);
 1412  
         }
 1413  
 
 1414  0
         return component;
 1415  
     }
 1416  
 
 1417  
     /**
 1418  
      * This works just like createComponent(String componentType), but without call
 1419  
      * FacesContext.getCurrentInstance()
 1420  
      * 
 1421  
      * @param facesContext
 1422  
      * @param componentType
 1423  
      * @return
 1424  
      * @throws FacesException 
 1425  
      */
 1426  
     private final UIComponent createComponent(FacesContext facesContext, 
 1427  
             final String componentType) throws FacesException
 1428  
     {
 1429  0
         checkNull(componentType, "componentType");
 1430  0
         checkEmpty(componentType, "componentType");
 1431  
 
 1432  0
         final Class<? extends UIComponent> componentClass =
 1433  
                 getObjectFromClassMap(componentType, _componentClassMap);
 1434  0
         if (componentClass == null)
 1435  
         {
 1436  0
             log.log(Level.SEVERE, "Undefined component type " + componentType);
 1437  0
             throw new FacesException("Undefined component type " + componentType);
 1438  
         }
 1439  
 
 1440  
         try
 1441  
         {
 1442  0
             UIComponent component = componentClass.newInstance();
 1443  0
             _handleAnnotations(facesContext, component, component);
 1444  0
             return component;
 1445  
         }
 1446  0
         catch (Exception e)
 1447  
         {
 1448  0
             log.log(Level.SEVERE, "Could not instantiate component componentType = " + componentType, e);
 1449  0
             throw new FacesException("Could not instantiate component componentType = " + componentType, e);
 1450  
         }
 1451  
     }
 1452  
     
 1453  
     @Override
 1454  
     public final UIComponent createComponent(final String componentType) throws FacesException
 1455  
     {
 1456  0
         checkNull(componentType, "componentType");
 1457  0
         checkEmpty(componentType, "componentType");
 1458  
 
 1459  0
         final Class<? extends UIComponent> componentClass =
 1460  
                 getObjectFromClassMap(componentType, _componentClassMap);
 1461  0
         if (componentClass == null)
 1462  
         {
 1463  0
             log.log(Level.SEVERE, "Undefined component type " + componentType);
 1464  0
             throw new FacesException("Undefined component type " + componentType);
 1465  
         }
 1466  
 
 1467  
         try
 1468  
         {
 1469  0
             UIComponent component = componentClass.newInstance();
 1470  0
             _handleAnnotations(FacesContext.getCurrentInstance(), component, component);
 1471  0
             return component;
 1472  
         }
 1473  0
         catch (Exception e)
 1474  
         {
 1475  0
             log.log(Level.SEVERE, "Could not instantiate component componentType = " + componentType, e);
 1476  0
             throw new FacesException("Could not instantiate component componentType = " + componentType, e);
 1477  
         }
 1478  
     }
 1479  
 
 1480  
     /**
 1481  
      * @deprecated Use createComponent(ValueExpression, FacesContext, String) instead.
 1482  
      */
 1483  
     @Deprecated
 1484  
     @Override
 1485  
     public final UIComponent createComponent(final ValueBinding valueBinding, final FacesContext facesContext,
 1486  
                                              final String componentType) throws FacesException
 1487  
     {
 1488  
 
 1489  0
         checkNull(valueBinding, "valueBinding");
 1490  0
         checkNull(facesContext, "facesContext");
 1491  0
         checkNull(componentType, "componentType");
 1492  0
         checkEmpty(componentType, "componentType");
 1493  
 
 1494  0
         final ValueExpression valExpression = new ValueBindingToValueExpression(valueBinding);
 1495  
 
 1496  0
         return createComponent(valExpression, facesContext, componentType);
 1497  
     }
 1498  
 
 1499  
     /**
 1500  
      * Return an instance of the converter class that has been registered under the specified id.
 1501  
      * <p>
 1502  
      * Converters are registered via faces-config.xml files, and can also be registered via the addConverter(String id,
 1503  
      * Class converterClass) method on this class. Here the the appropriate Class definition is found, then an instance
 1504  
      * is created and returned.
 1505  
      * <p>
 1506  
      * A converter registered via a config file can have any number of nested attribute or property tags. The JSF
 1507  
      * specification is very vague about what effect these nested tags have. This method ignores nested attribute
 1508  
      * definitions, but for each nested property tag the corresponding setter is invoked on the new Converter instance
 1509  
      * passing the property's defaultValuer. Basic typeconversion is done so the target properties on the Converter
 1510  
      * instance can be String, int, boolean, etc. Note that:
 1511  
      * <ol>
 1512  
      * <li>the Sun Mojarra JSF implemenation ignores nested property tags completely, so this behaviour cannot be 
 1513  
      * relied on across implementations.
 1514  
      * <li>there is no equivalent functionality for converter classes registered via the Application.addConverter api
 1515  
      * method.
 1516  
      * </ol>
 1517  
      * <p>
 1518  
      * Note that this method is most commonly called from the standard f:attribute tag. As an alternative, most
 1519  
      * components provide a "converter" attribute which uses an EL expression to create a Converter instance, in which
 1520  
      * case this method is not invoked at all. The converter attribute allows the returned Converter instance to be
 1521  
      * configured via normal dependency-injection, and is generally a better choice than using this method.
 1522  
      */
 1523  
     @Override
 1524  
     public final Converter createConverter(final String converterId)
 1525  
     {
 1526  0
         checkNull(converterId, "converterId");
 1527  0
         checkEmpty(converterId, "converterId");
 1528  
 
 1529  0
         final Class<? extends Converter> converterClass =
 1530  
                 getObjectFromClassMap(converterId, _converterIdToClassMap);
 1531  0
         if (converterClass == null)
 1532  
         {
 1533  0
             throw new FacesException("Could not find any registered converter-class by converterId : " + converterId);
 1534  
         }
 1535  
 
 1536  
         try
 1537  
         {
 1538  0
             final Converter converter = createConverterInstance(converterClass);
 1539  
 
 1540  0
             setConverterProperties(converterClass, converter);
 1541  
             
 1542  0
             _handleAttachedResourceDependencyAnnotations(FacesContext.getCurrentInstance(), converter);
 1543  
 
 1544  0
             return converter;
 1545  
         }
 1546  0
         catch (Exception e)
 1547  
         {
 1548  0
             log.log(Level.SEVERE, "Could not instantiate converter " + converterClass, e);
 1549  0
             throw new FacesException("Could not instantiate converter: " + converterClass, e);
 1550  
         }
 1551  
     }
 1552  
 
 1553  
     private Converter createConverterInstance(Class<? extends Converter> converterClass)
 1554  
             throws InstantiationException, IllegalAccessException
 1555  
     {
 1556  0
         Converter result = _externalArtifactResolver != null ? 
 1557  
             _externalArtifactResolver.resolveManagedConverter(converterClass) : null;
 1558  
 
 1559  0
         if (result == null)
 1560  
         {
 1561  0
             return converterClass.newInstance();
 1562  
         }
 1563  
         else
 1564  
         {
 1565  0
             return new ConverterWrapper(result);
 1566  
         }
 1567  
     }
 1568  
 
 1569  
     @Override
 1570  
     public final Converter createConverter(final Class<?> targetClass)
 1571  
     {
 1572  0
         checkNull(targetClass, "targetClass");
 1573  
 
 1574  0
         return internalCreateConverter(targetClass);
 1575  
     }
 1576  
 
 1577  
     @SuppressWarnings("unchecked")
 1578  
     private Converter internalCreateConverter(final Class<?> targetClass)
 1579  
     {
 1580  
         // Locate a Converter registered for the target class itself.
 1581  0
         Object converterClassOrClassName = _converterTargetClassToConverterClassMap.get(targetClass);
 1582  
         
 1583  
         // Locate a Converter registered for interfaces that are
 1584  
         // implemented by the target class (directly or indirectly).
 1585  
         // Skip if class is String, for performance reasons 
 1586  
         // (save 3 additional lookups over a concurrent map per request). 
 1587  0
         if (converterClassOrClassName == null && !String.class.equals(targetClass))
 1588  
         {
 1589  0
             final Class<?> interfaces[] = targetClass.getInterfaces();
 1590  0
             if (interfaces != null)
 1591  
             {
 1592  0
                 for (int i = 0, len = interfaces.length; i < len; i++)
 1593  
                 {
 1594  
                     // search all superinterfaces for a matching converter,
 1595  
                     // create it
 1596  0
                     final Converter converter = internalCreateConverter(interfaces[i]);
 1597  0
                     if (converter != null)
 1598  
                     {
 1599  0
                         return converter;
 1600  
                     }
 1601  
                 }
 1602  
             }
 1603  
         }
 1604  
 
 1605  
         // Get EnumConverter for enum classes with no special converter, check
 1606  
         // here as recursive call with java.lang.Enum will not work
 1607  0
         if (converterClassOrClassName == null && targetClass.isEnum())
 1608  
         {
 1609  0
             converterClassOrClassName = _converterTargetClassToConverterClassMap.get(Enum.class);
 1610  
         }
 1611  
 
 1612  0
         if (converterClassOrClassName != null)
 1613  
         {
 1614  
             try
 1615  
             {
 1616  0
                 Class<? extends Converter> converterClass = null;
 1617  0
                 if (converterClassOrClassName instanceof Class<?>)
 1618  
                 {
 1619  0
                     converterClass = (Class<? extends Converter>) converterClassOrClassName;
 1620  
                 }
 1621  0
                 else if (converterClassOrClassName instanceof String)
 1622  
                 {
 1623  0
                     converterClass = ClassUtils.simpleClassForName((String) converterClassOrClassName);
 1624  0
                     _converterTargetClassToConverterClassMap.put(targetClass, converterClass);
 1625  
                 }
 1626  
                 else
 1627  
                 {
 1628  
                     //object stored in the map for this id is an invalid type.  remove it and return null
 1629  0
                     _converterTargetClassToConverterClassMap.remove(targetClass);
 1630  
                 }
 1631  
                 
 1632  0
                 Converter converter = null;
 1633  
                 
 1634  
                 // check cached constructor information
 1635  0
                 if (!_noArgConstructorConverterClasses.contains(converterClass))
 1636  
                 {
 1637  
                     // the converter class either supports the one-arg constructor
 1638  
                     // or has never been processed before
 1639  
                     try
 1640  
                     {
 1641  
                         // look for a constructor that takes a single Class object
 1642  
                         // See JSF 1.2 javadoc for Converter
 1643  0
                         Constructor<? extends Converter> constructor = converterClass
 1644  
                                 .getConstructor(new Class[] { Class.class });
 1645  
 
 1646  0
                         converter = constructor.newInstance(new Object[] { targetClass });
 1647  
                     }
 1648  0
                     catch (Exception e)
 1649  
                     {
 1650  
                         // the constructor does not exist
 1651  
                         // add the class to the no-arg constructor classes cache
 1652  0
                         _noArgConstructorConverterClasses.add(converterClass);
 1653  
                         
 1654  
                         // use no-arg constructor
 1655  0
                         converter = createConverterInstance(converterClass);
 1656  0
                     }
 1657  
                 }
 1658  
                 else
 1659  
                 {
 1660  
                     // use no-arg constructor
 1661  0
                     converter = createConverterInstance(converterClass);
 1662  
                 }
 1663  
 
 1664  0
                 setConverterProperties(converterClass, converter);
 1665  
 
 1666  0
                 return converter;
 1667  
             }
 1668  0
             catch (Exception e)
 1669  
             {
 1670  0
                 log.log(Level.SEVERE, "Could not instantiate converter " + converterClassOrClassName.toString(), e);
 1671  0
                 throw new FacesException("Could not instantiate converter: " + converterClassOrClassName.toString(), e);
 1672  
             }
 1673  
         }
 1674  
 
 1675  
         // locate converter for primitive types
 1676  0
         if (targetClass == Long.TYPE)
 1677  
         {
 1678  0
             return internalCreateConverter(Long.class);
 1679  
         }
 1680  0
         else if (targetClass == Boolean.TYPE)
 1681  
         {
 1682  0
             return internalCreateConverter(Boolean.class);
 1683  
         }
 1684  0
         else if (targetClass == Double.TYPE)
 1685  
         {
 1686  0
             return internalCreateConverter(Double.class);
 1687  
         }
 1688  0
         else if (targetClass == Byte.TYPE)
 1689  
         {
 1690  0
             return internalCreateConverter(Byte.class);
 1691  
         }
 1692  0
         else if (targetClass == Short.TYPE)
 1693  
         {
 1694  0
             return internalCreateConverter(Short.class);
 1695  
         }
 1696  0
         else if (targetClass == Integer.TYPE)
 1697  
         {
 1698  0
             return internalCreateConverter(Integer.class);
 1699  
         }
 1700  0
         else if (targetClass == Float.TYPE)
 1701  
         {
 1702  0
             return internalCreateConverter(Float.class);
 1703  
         }
 1704  0
         else if (targetClass == Character.TYPE)
 1705  
         {
 1706  0
             return internalCreateConverter(Character.class);
 1707  
         }
 1708  
 
 1709  
         // Locate a Converter registered for the superclass (if any) of the
 1710  
         // target class,
 1711  
         // recursively working up the inheritance hierarchy.
 1712  0
         Class<?> superClazz = targetClass.getSuperclass();
 1713  
 
 1714  0
         return superClazz != null ? internalCreateConverter(superClazz) : null;
 1715  
 
 1716  
     }
 1717  
 
 1718  
     private void setConverterProperties(final Class<?> converterClass, final Converter converter)
 1719  
     {
 1720  0
         final org.apache.myfaces.config.element.Converter converterConfig = _runtimeConfig
 1721  
                 .getConverterConfiguration(converterClass.getName());
 1722  
         
 1723  
         // if the converter is a DataTimeConverter, check the init param for the default timezone (since 2.0)
 1724  0
         if (converter instanceof DateTimeConverter && _dateTimeConverterDefaultTimeZoneIsSystemTimeZone)
 1725  
         {    
 1726  0
             ((DateTimeConverter) converter).setTimeZone(TimeZone.getDefault());
 1727  
         }
 1728  
 
 1729  0
         if (converterConfig != null && converterConfig.getProperties().size() > 0)
 1730  
         {
 1731  0
             for (Property property : converterConfig.getProperties())
 1732  
             {
 1733  
                 try
 1734  
                 {
 1735  0
                     BeanUtils.setProperty(converter, property.getPropertyName(), property.getDefaultValue());
 1736  
                 }
 1737  0
                 catch (Throwable th)
 1738  
                 {
 1739  0
                     log.log(Level.SEVERE, "Initializing converter : " + converterClass.getName() + " with property : "
 1740  
                             + property.getPropertyName() + " and value : " + property.getDefaultValue() + " failed.");
 1741  0
                 }
 1742  0
             }
 1743  
         }
 1744  0
     }
 1745  
     
 1746  
     private void _handleAttachedResourceDependencyAnnotations(FacesContext context, Object inspected)
 1747  
     {
 1748  0
         if (inspected == null)
 1749  
         {
 1750  0
             return;
 1751  
         }
 1752  
         
 1753  
         // This and only this method handles @ResourceDependency and @ResourceDependencies annotations
 1754  
         // The source of these annotations is Class<?> inspectedClass.
 1755  
         // Because Class<?> and its annotations cannot change
 1756  
         // during request/response, it is sufficient to process Class<?> only once per view.
 1757  0
         RequestViewContext rvc = RequestViewContext.getCurrentInstance(context);
 1758  0
         Class<?> inspectedClass = inspected.getClass();
 1759  0
         if (rvc.isClassAlreadyProcessed(inspectedClass))
 1760  
         {
 1761  0
             return;
 1762  
         }
 1763  0
         boolean classAlreadyProcessed = false;
 1764  
 
 1765  
         
 1766  0
         List<ResourceDependency> dependencyList = null;
 1767  0
         boolean isCachedList = false;
 1768  
         
 1769  0
         if(context.isProjectStage(ProjectStage.Production) && _classToResourceDependencyMap.containsKey(inspectedClass))
 1770  
         {
 1771  0
             dependencyList = _classToResourceDependencyMap.get(inspectedClass);
 1772  0
             if(dependencyList == null)
 1773  
             {
 1774  0
                 return; //class has been inspected and did not contain any resource dependency annotations
 1775  
             }
 1776  0
             else if (dependencyList.isEmpty())
 1777  
             {
 1778  0
                 return;
 1779  
             }
 1780  
             
 1781  0
             isCachedList = true;    // else annotations were found in the cache
 1782  
         }
 1783  
         
 1784  0
         if(dependencyList == null)  //not in production or the class hasn't been inspected yet
 1785  
         {   
 1786  0
             ResourceDependency dependency = inspectedClass.getAnnotation(ResourceDependency.class);
 1787  0
             ResourceDependencies dependencies = inspectedClass.getAnnotation(ResourceDependencies.class);
 1788  0
             if(dependency != null || dependencies != null)
 1789  
             {
 1790  
                 //resource dependencies were found using one or both annotations, create and build a new list
 1791  0
                 dependencyList = new ArrayList<ResourceDependency>();
 1792  
                 
 1793  0
                 if(dependency != null)
 1794  
                 {
 1795  0
                     dependencyList.add(dependency);
 1796  
                 }
 1797  
                 
 1798  0
                 if(dependencies != null)
 1799  
                 {
 1800  0
                     dependencyList.addAll(Arrays.asList(dependencies.value()));
 1801  
                 }
 1802  
             }
 1803  
             else
 1804  
             {
 1805  0
                 dependencyList = Collections.emptyList();
 1806  
             }
 1807  
         }
 1808  
 
 1809  
         //resource dependencies were found through inspection or from cache, handle them
 1810  0
         if (dependencyList != null && !dependencyList.isEmpty()) 
 1811  
         {
 1812  0
             for (int i = 0, size = dependencyList.size(); i < size; i++)
 1813  
             {
 1814  0
                 ResourceDependency dependency = dependencyList.get(i);
 1815  0
                 if (!rvc.isResourceDependencyAlreadyProcessed(dependency))
 1816  
                 {
 1817  0
                     _handleAttachedResourceDependency(context, dependency, inspectedClass);
 1818  0
                     rvc.setResourceDependencyAsProcessed(dependency);
 1819  
                 }
 1820  
             }
 1821  
         }
 1822  
         
 1823  
         //if we're in production and the list is not yet cached, store it
 1824  0
         if(context.isProjectStage(ProjectStage.Production) && !isCachedList && dependencyList != null)
 1825  
         {
 1826  
             // Note at this point dependencyList cannot be null, but just let this
 1827  
             // as a sanity check.
 1828  0
             _classToResourceDependencyMap.put(inspectedClass, dependencyList);
 1829  
         }
 1830  
         
 1831  0
         if (!classAlreadyProcessed)
 1832  
         {
 1833  0
             rvc.setClassProcessed(inspectedClass);
 1834  
         }
 1835  0
     }
 1836  
 
 1837  
     /**
 1838  
      * If the ResourceDependency component is created under facelets processing, it should receive
 1839  
      * an special unique component id. This method check if there is a FaceletCompositionContext
 1840  
      * and if that so, set the id. Components added by the effect of ResourceDependency are special,
 1841  
      * because they do not have state, but they depends on the view structure, so with PSS, 
 1842  
      * each time the view is built they are "recalculated", so they work as if they were transient
 1843  
      * components that needs to be created at each request, but there are some cases were the 
 1844  
      * components needs to be saved and restored fully. If a component is created outside facelets 
 1845  
      * control (render response phase) it is expected to use the default implementation of 
 1846  
      * createUniqueId(), but in that case, note that this happens after markInitialState() is 
 1847  
      * called, and the component in this case is saved and restored fully, as expected.
 1848  
      * 
 1849  
      * This code cannot be called from facelets component tag handler, because in cases where a
 1850  
      * component subtree is created using binding property, facelets lost control over component
 1851  
      * creation and delegates it to the user, but since the binding code is executed each time the
 1852  
      * view is created, the effect over ResourceDependency persists and the binding code takes into
 1853  
      * account in the recalculation step, even if later the node related to the binding property
 1854  
      * is dropped and recreated from the state fully. 
 1855  
      * 
 1856  
      * @param facesContext
 1857  
      * @param component 
 1858  
      */
 1859  
     private void setResourceIdOnFaceletsMode(FacesContext facesContext, UIComponent component,
 1860  
             Class<?> inspectedClass)
 1861  
     {
 1862  0
         if (component.getId() == null)
 1863  
         {
 1864  0
             FaceletCompositionContext mctx = FaceletCompositionContext.getCurrentInstance(facesContext);
 1865  0
             if (mctx != null)
 1866  
             {
 1867  0
                 UIViewRoot root = facesContext.getViewRoot();
 1868  0
                 root.getAttributes().put(RESOURCE_DEPENDENCY_UNIQUE_ID_KEY, Boolean.TRUE);
 1869  
                 try
 1870  
                 {
 1871  0
                     String uid = root.createUniqueId(facesContext, null);
 1872  0
                     component.setId(uid);
 1873  
                 }
 1874  
                 finally
 1875  
                 {
 1876  0
                     root.getAttributes().put(RESOURCE_DEPENDENCY_UNIQUE_ID_KEY, Boolean.FALSE);
 1877  0
                 }
 1878  0
                 if (!mctx.isUsingPSSOnThisView())
 1879  
                 {
 1880  
                     // Now set the identifier that will help to know which classes has been already inspected.
 1881  0
                     component.getAttributes().put(
 1882  
                             RequestViewContext.RESOURCE_DEPENDENCY_INSPECTED_CLASS, inspectedClass);
 1883  
                 }
 1884  0
                 else if (mctx.isRefreshTransientBuildOnPSSPreserveState())
 1885  
                 {
 1886  0
                     component.getAttributes().put(
 1887  
                             RequestViewContext.RESOURCE_DEPENDENCY_INSPECTED_CLASS, inspectedClass);
 1888  
                 }
 1889  0
             }
 1890  
             else
 1891  
             {
 1892  
                 // This happens when there is a programmatic addition, which means the user has added the
 1893  
                 // components to the tree on render response phase or earlier but outside facelets control.
 1894  
                 // In that case we need to save the dependency.
 1895  0
                 component.getAttributes().put(
 1896  
                         RequestViewContext.RESOURCE_DEPENDENCY_INSPECTED_CLASS, inspectedClass);
 1897  
             }
 1898  
         }
 1899  0
     }
 1900  
     
 1901  
     private void _handleAttachedResourceDependency(FacesContext context, ResourceDependency annotation, 
 1902  
             Class<?> inspectedClass)
 1903  
     {
 1904  
         // If this annotation is not present on the class in question, no action must be taken. 
 1905  0
         if (annotation != null)
 1906  
         {
 1907  0
             Application application = context.getApplication();
 1908  
             
 1909  
             // Create a UIOutput instance by passing javax.faces.Output. to 
 1910  
             // Application.createComponent(java.lang.String).
 1911  0
             UIOutput output = (UIOutput) application.createComponent(context, UIOutput.COMPONENT_TYPE, null);
 1912  
             
 1913  
             // Get the annotation instance from the class and obtain the values of the name, library, and 
 1914  
             // target attributes.
 1915  0
             String name = annotation.name();
 1916  0
             if (name != null && name.length() > 0)
 1917  
             {
 1918  0
                 name = ELText.parse(getExpressionFactory(),
 1919  
                                     context.getELContext(), name).toString(context.getELContext());
 1920  
             }
 1921  
             
 1922  
             // Obtain the renderer-type for the resource name by passing name to 
 1923  
             // ResourceHandler.getRendererTypeForResourceName(java.lang.String).
 1924  0
             String rendererType = application.getResourceHandler().getRendererTypeForResourceName(name);
 1925  
             
 1926  
             // Call setRendererType on the UIOutput instance, passing the renderer-type.
 1927  0
             output.setRendererType(rendererType);
 1928  
             
 1929  
             // If the @ResourceDependency was done inside facelets processing,
 1930  
             // call setId() and set a proper id from facelets
 1931  0
             setResourceIdOnFaceletsMode(context, output, inspectedClass);
 1932  
             
 1933  
             // Obtain the Map of attributes from the UIOutput component by calling UIComponent.getAttributes().
 1934  0
             Map<String, Object> attributes = output.getAttributes();
 1935  
             
 1936  
             // Store the name into the attributes Map under the key "name".
 1937  0
             attributes.put("name", name);
 1938  
             
 1939  
             // If library is the empty string, let library be null.
 1940  0
             String library = annotation.library();
 1941  0
             if (library != null && library.length() > 0)
 1942  
             {
 1943  0
                 library = ELText.parse(getExpressionFactory(),
 1944  
                                        context.getELContext(), library).toString(context.getELContext());
 1945  
                 // If library is non-null, store it under the key "library".
 1946  0
                 attributes.put("library", library);
 1947  
             }
 1948  
             
 1949  
             // Identify the resource as created by effect of a @ResourceDependency annotation.
 1950  0
             output.getAttributes().put(RequestViewMetadata.RESOURCE_DEPENDENCY_KEY, 
 1951  
                 new Object[]{annotation.library(), annotation.name()});
 1952  
             
 1953  
             // If target is the empty string, let target be null.
 1954  0
             String target = annotation.target();
 1955  0
             if (target != null && target.length() > 0)
 1956  
             {
 1957  0
                 target = ELText.parse(getExpressionFactory(),
 1958  
                                       context.getELContext(), target).toString(context.getELContext());
 1959  
                 // If target is non-null, store it under the key "target".
 1960  0
                 attributes.put("target", target);
 1961  0
                 context.getViewRoot().addComponentResource(context, output, target);
 1962  
             }
 1963  
             else
 1964  
             {
 1965  
                 // Otherwise, if target is null, call 
 1966  
                 // UIViewRoot.addComponentResource(javax.faces.context.FacesContext, 
 1967  
                 // javax.faces.component.UIComponent), passing the UIOutput instance as the second argument.
 1968  0
                 context.getViewRoot().addComponentResource(context, output);
 1969  
             }
 1970  
         }
 1971  0
     }
 1972  
 
 1973  
     // Note: this method used to be synchronized in the JSF 1.1 version. Why?
 1974  
     /**
 1975  
      * @deprecated
 1976  
      */
 1977  
     @Deprecated
 1978  
     @Override
 1979  
     public final MethodBinding createMethodBinding(final String reference, Class<?>[] params)
 1980  
             throws ReferenceSyntaxException
 1981  
     {
 1982  0
         checkNull(reference, "reference");
 1983  0
         checkEmpty(reference, "reference");
 1984  
 
 1985  
         // TODO: this check should be performed by the expression factory. It is
 1986  
         // a requirement of the TCK
 1987  0
         if (!(reference.startsWith("#{") && reference.endsWith("}")))
 1988  
         {
 1989  0
             throw new ReferenceSyntaxException("Invalid method reference: '" + reference + "'");
 1990  
         }
 1991  
 
 1992  0
         if (params == null)
 1993  
         {
 1994  0
             params = new Class[0];
 1995  
         }
 1996  
 
 1997  
         MethodExpression methodExpression;
 1998  
 
 1999  
         try
 2000  
         {
 2001  0
             methodExpression = getExpressionFactory().createMethodExpression(threadELContext(), reference,
 2002  
                                                                              Object.class, params);
 2003  
         }
 2004  0
         catch (ELException e)
 2005  
         {
 2006  0
             throw new ReferenceSyntaxException(e);
 2007  0
         }
 2008  
 
 2009  0
         return new MethodExpressionToMethodBinding(methodExpression);
 2010  
     }
 2011  
 
 2012  
     @Override
 2013  
     public final Validator createValidator(final String validatorId) throws FacesException
 2014  
     {
 2015  0
         checkNull(validatorId, "validatorId");
 2016  0
         checkEmpty(validatorId, "validatorId");
 2017  
 
 2018  0
         Class<? extends Validator> validatorClass =
 2019  
                 getObjectFromClassMap(validatorId, _validatorClassMap);
 2020  0
         if (validatorClass == null)
 2021  
         {
 2022  0
             String message = "Unknown validator id '" + validatorId + "'.";
 2023  0
             log.severe(message);
 2024  0
             throw new FacesException(message);
 2025  
         }
 2026  
 
 2027  
         try
 2028  
         {
 2029  0
             Validator validator = createValidatorInstance(validatorClass);
 2030  
             
 2031  0
             _handleAttachedResourceDependencyAnnotations(FacesContext.getCurrentInstance(), validator);
 2032  
             
 2033  0
             return validator;
 2034  
         }
 2035  0
         catch (Exception e)
 2036  
         {
 2037  0
             log.log(Level.SEVERE, "Could not instantiate validator " + validatorClass, e);
 2038  0
             throw new FacesException("Could not instantiate validator: " + validatorClass, e);
 2039  
         }
 2040  
     }
 2041  
 
 2042  
     private Validator createValidatorInstance(Class<? extends Validator> validatorClass)
 2043  
             throws InstantiationException, IllegalAccessException
 2044  
     {
 2045  0
         Validator result = _externalArtifactResolver != null ? 
 2046  
             _externalArtifactResolver.resolveManagedValidator(validatorClass) : null;
 2047  
 
 2048  0
         if (result == null)
 2049  
         {
 2050  0
             return validatorClass.newInstance();
 2051  
         }
 2052  
         else
 2053  
         {
 2054  0
             return new ValidatorWrapper(result);
 2055  
         }
 2056  
     }
 2057  
 
 2058  
     /**
 2059  
      * @deprecated
 2060  
      */
 2061  
     @Override
 2062  
     public final ValueBinding createValueBinding(final String reference) throws ReferenceSyntaxException
 2063  
     {
 2064  0
         checkNull(reference, "reference");
 2065  0
         checkEmpty(reference, "reference");
 2066  
 
 2067  
         ValueExpression valueExpression;
 2068  
 
 2069  
         try
 2070  
         {
 2071  0
             valueExpression = getExpressionFactory().createValueExpression(
 2072  
                     threadELContext(), reference, Object.class);
 2073  
         }
 2074  0
         catch (ELException e)
 2075  
         {
 2076  0
             throw new ReferenceSyntaxException(e);
 2077  0
         }
 2078  
 
 2079  0
         return new ValueExpressionToValueBinding(valueExpression);
 2080  
     }
 2081  
 
 2082  
     // gets the elContext from the current FacesContext()
 2083  
     private final ELContext threadELContext()
 2084  
     {
 2085  0
         return getFaceContext().getELContext();
 2086  
     }
 2087  
 
 2088  
     @Override
 2089  
     public final String getDefaultRenderKitId()
 2090  
     {
 2091  0
         return _defaultRenderKitId;
 2092  
     }
 2093  
 
 2094  
     @Override
 2095  
     public final void setDefaultRenderKitId(final String defaultRenderKitId)
 2096  
     {
 2097  0
         _defaultRenderKitId = defaultRenderKitId;
 2098  0
     }
 2099  
 
 2100  
     @Override
 2101  
     public final StateManager getStateManager()
 2102  
     {
 2103  0
         return _stateManager;
 2104  
     }
 2105  
 
 2106  
     @Override
 2107  
     public final void setStateManager(final StateManager stateManager)
 2108  
     {
 2109  0
         checkNull(stateManager, "stateManager");
 2110  
 
 2111  0
         if(isFirstRequestProcessed())
 2112  
         {
 2113  0
             throw new IllegalStateException(
 2114  
                     "setStateManager may not be executed after a lifecycle request has been completed");
 2115  
         }
 2116  
         
 2117  0
         _stateManager = stateManager;
 2118  0
     }
 2119  
     
 2120  
     @Override
 2121  
     public final void setFlowHandler(FlowHandler flowHandler)
 2122  
     {
 2123  0
         checkNull(flowHandler, "flowHandler");
 2124  
 
 2125  0
         if(isFirstRequestProcessed())
 2126  
         {
 2127  0
             throw new IllegalStateException(
 2128  
                     "setFlowHandler may not be executed after a lifecycle request has been completed");
 2129  
         }
 2130  0
         _flowHandler = flowHandler;
 2131  0
     }
 2132  
 
 2133  
     @Override
 2134  
     public final FlowHandler getFlowHandler()
 2135  
     {
 2136  0
         return _flowHandler;
 2137  
     }
 2138  
 
 2139  
     private void checkNull(final Object param, final String paramName)
 2140  
     {
 2141  0
         if (param == null)
 2142  
         {
 2143  0
             throw new NullPointerException(paramName + " cannot be null.");
 2144  
         }
 2145  0
     }
 2146  
 
 2147  
     private void checkEmpty(final String param, final String paramName)
 2148  
     {
 2149  0
         if (param.length() == 0)
 2150  
         {
 2151  0
             throw new NullPointerException("String " + paramName + " cannot be empty.");
 2152  
         }
 2153  0
     }
 2154  
 
 2155  
     private static SystemEvent _createEvent(Class<? extends SystemEvent> systemEventClass, Object source,
 2156  
                                             SystemEvent event)
 2157  
     {
 2158  0
         if (event == null)
 2159  
         {
 2160  
             try
 2161  
             {
 2162  0
                 Constructor<?>[] constructors = systemEventClass.getConstructors();
 2163  0
                 Constructor<? extends SystemEvent> constructor = null;
 2164  0
                 for (Constructor<?> c : constructors)
 2165  
                 {
 2166  0
                     if (c.getParameterTypes().length == 1)
 2167  
                     {
 2168  
                         // Safe cast, since the constructor belongs
 2169  
                         // to a class of type SystemEvent
 2170  0
                         constructor = (Constructor<? extends SystemEvent>) c;
 2171  0
                         break;
 2172  
                     }
 2173  
                 }
 2174  0
                 if (constructor != null)
 2175  
                 {
 2176  0
                     event = constructor.newInstance(source);
 2177  
                 }
 2178  
 
 2179  
             }
 2180  0
             catch (Exception e)
 2181  
             {
 2182  0
                 throw new FacesException("Couldn't instanciate system event of type " + 
 2183  
                         systemEventClass.getName(), e);
 2184  0
             }
 2185  
         }
 2186  
 
 2187  0
         return event;
 2188  
     }
 2189  
 
 2190  
     private void _handleAnnotations(FacesContext context, Object inspected, UIComponent component)
 2191  
     {   
 2192  
         // determine the ProjectStage setting via the given FacesContext
 2193  
         // note that a local getProjectStage() could cause problems in wrapped environments
 2194  0
         boolean isProduction = context.isProjectStage(ProjectStage.Production);
 2195  
         
 2196  0
         Class<?> inspectedClass = inspected.getClass();
 2197  0
         _handleListenerForAnnotations(context, inspected, inspectedClass, component, isProduction);
 2198  
 
 2199  0
         _handleResourceDependencyAnnotations(context, inspectedClass, component, isProduction);
 2200  0
     }
 2201  
 
 2202  
     private void _handleRendererAnnotations(FacesContext context, Renderer inspected, UIComponent component)
 2203  
     {   
 2204  
         // determine the ProjectStage setting via the given FacesContext
 2205  
         // note that a local getProjectStage() could cause problems in wrapped environments
 2206  0
         boolean isProduction = context.isProjectStage(ProjectStage.Production);
 2207  0
         Renderer innerRenderer = inspected;
 2208  0
         while (innerRenderer != null)
 2209  
         {
 2210  0
             if (innerRenderer instanceof RendererWrapper)
 2211  
             {
 2212  0
                 Class<?> inspectedClass = innerRenderer.getClass();
 2213  0
                 _handleListenerForAnnotations(context, innerRenderer, inspectedClass, component, isProduction);
 2214  
 
 2215  0
                 _handleResourceDependencyAnnotations(context, inspectedClass, component, isProduction);
 2216  
                 
 2217  
                 // get the inner wrapper
 2218  0
                 innerRenderer = ((RendererWrapper)innerRenderer).getWrapped();
 2219  0
             }
 2220  
             else
 2221  
             {
 2222  0
                 Class<?> inspectedClass = innerRenderer.getClass();
 2223  0
                 _handleListenerForAnnotations(context, innerRenderer, inspectedClass, component, isProduction);
 2224  
 
 2225  0
                 _handleResourceDependencyAnnotations(context, inspectedClass, component, isProduction);
 2226  
                 
 2227  0
                 innerRenderer = null;
 2228  0
             }
 2229  
         }
 2230  0
     }
 2231  
 
 2232  
     private void _handleListenerForAnnotations(FacesContext context, Object inspected, Class<?> inspectedClass,
 2233  
                                                UIComponent component, boolean isProduction)
 2234  
     {
 2235  0
         List<ListenerFor> listenerForList = null;
 2236  0
         boolean isCachedList = false;
 2237  
         
 2238  0
         if(isProduction)
 2239  
         {
 2240  0
             listenerForList = _classToListenerForMap.get(inspectedClass);
 2241  
 
 2242  0
             if (listenerForList != null)
 2243  
             {
 2244  0
                 if (listenerForList.isEmpty())
 2245  
                 {
 2246  0
                     return; //class has been inspected and did not contain any listener annotations
 2247  
                 }
 2248  
                 
 2249  0
                 isCachedList = true;    // else annotations were found in the cache
 2250  
             }
 2251  
         }
 2252  
 
 2253  0
         if(listenerForList == null) //not in production or the class hasn't been inspected yet
 2254  
         {
 2255  0
             ListenerFor listener = inspectedClass.getAnnotation(ListenerFor.class);
 2256  0
             ListenersFor listeners = inspectedClass.getAnnotation(ListenersFor.class);
 2257  0
             if(listener != null || listeners != null)
 2258  
             {
 2259  
                 //listeners were found using one or both annotations, create and build a new list
 2260  0
                 listenerForList = new ArrayList<ListenerFor>();
 2261  
                 
 2262  0
                 if(listener != null)
 2263  
                 {
 2264  0
                     listenerForList.add(listener);
 2265  
                 }
 2266  
                 
 2267  0
                 if(listeners != null)
 2268  
                 {
 2269  0
                     listenerForList.addAll(Arrays.asList(listeners.value()));
 2270  
                 }
 2271  
             }
 2272  
             else
 2273  
             {
 2274  0
                 listenerForList = Collections.emptyList();
 2275  
             }
 2276  
         }        
 2277  
  
 2278  
         // listeners were found through inspection or from cache, handle them
 2279  0
         if (listenerForList != null && !listenerForList.isEmpty()) 
 2280  
         {
 2281  0
             for (int i = 0, size = listenerForList.size(); i < size; i++)
 2282  
             {
 2283  0
                 ListenerFor listenerFor = listenerForList.get(i);
 2284  0
                 _handleListenerFor(context, inspected, component, listenerFor);
 2285  
             }
 2286  
         }
 2287  
         
 2288  
         //if we're in production and the list is not yet cached, store it
 2289  0
         if(isProduction && !isCachedList && listenerForList != null) 
 2290  
         {
 2291  
             // Note at this point listenerForList cannot be null, but just let listenerForList != null
 2292  
             // as a sanity check.
 2293  0
             _classToListenerForMap.put(inspectedClass, listenerForList);
 2294  
         }
 2295  0
     }
 2296  
 
 2297  
     private void _handleListenerFor(FacesContext context, Object inspected, UIComponent component,
 2298  
                                     ListenerFor annotation)
 2299  
     {
 2300  
         // If this annotation is not present on the class in question, no action must be taken.
 2301  0
         if (annotation != null)
 2302  
         {
 2303  
             // Determine the "target" on which to call subscribeToEvent.
 2304  
             // If the class to which this annotation is attached implements ComponentSystemEventListener
 2305  0
             if (inspected instanceof ComponentSystemEventListener)
 2306  
             {
 2307  
                 // If the class to which this annotation is attached is a UIComponent instance, "target" is the
 2308  
                 // UIComponent instance.
 2309  
 
 2310  
                 // If the class to which this annotation is attached is a Renderer instance, "target" is the
 2311  
                 // UIComponent instance.
 2312  
 
 2313  
                 /*
 2314  
                  * If "target" is a UIComponent call UIComponent.subscribeToEvent(Class, ComponentSystemEventListener)
 2315  
                  * passing the systemEventClass() of the annotation as the first argument and the instance of the class
 2316  
                  * to which this annotation is attached (which must implement ComponentSystemEventListener) as the
 2317  
                  * second argument.
 2318  
                  */
 2319  0
                 component.subscribeToEvent(annotation.systemEventClass(), (ComponentSystemEventListener) inspected);
 2320  
             }
 2321  
             // If the class to which this annotation is attached implements SystemEventListener and does not implement
 2322  
             // ComponentSystemEventListener, "target" is the Application instance.
 2323  0
             else if (component instanceof SystemEventListener)
 2324  
             {
 2325  
                 // use the Application object from the FacesContext (note that a
 2326  
                 // direct use of subscribeToEvent() could cause problems if the
 2327  
                 // Application is wrapped)
 2328  0
                 Application application = context.getApplication();
 2329  
                 
 2330  
                 // If "target" is the Application instance, inspect the value of the sourceClass() annotation attribute
 2331  
                 // value.
 2332  0
                 if (Void.class.equals(annotation.sourceClass()))
 2333  
                 {
 2334  
                     /*
 2335  
                      * If the value is Void.class, call Application.subscribeToEvent(Class, SystemEventListener),
 2336  
                      * passing the value of systemEventClass() as the first argument and the instance of the class to
 2337  
                      * which this annotation is attached (which must implement SystemEventListener) as the second
 2338  
                      * argument.
 2339  
                      */
 2340  0
                     application.subscribeToEvent(annotation.systemEventClass(), (SystemEventListener) inspected);
 2341  
                 }
 2342  
                 else
 2343  
                 {
 2344  
                     /*
 2345  
                      * Otherwise, call Application.subscribeToEvent(Class, Class, SystemEventListener), passing the
 2346  
                      * value of systemEventClass() as the first argument, the value of sourceClass() as the second
 2347  
                      * argument, and the instance of the class to which this annotation is attached (which must
 2348  
                      * implement SystemEventListener) as the third argument.
 2349  
                      */
 2350  0
                     application.subscribeToEvent(annotation.systemEventClass(), annotation.sourceClass(),
 2351  
                                      (SystemEventListener) inspected);
 2352  
                 }
 2353  
             }
 2354  
 
 2355  
             /*
 2356  
              * If the class to which this annotation is attached implements ComponentSystemEventListener and is neither
 2357  
              * an instance of Renderer nor UIComponent, the action taken is unspecified. This case must not trigger any
 2358  
              * kind of error.
 2359  
              */
 2360  
         }
 2361  0
     }
 2362  
 
 2363  
     private void _handleResourceDependencyAnnotations(FacesContext context, Class<?> inspectedClass,
 2364  
                                                       UIComponent component, boolean isProduction)
 2365  
     {
 2366  
         // This and only this method handles @ResourceDependency and @ResourceDependencies annotations
 2367  
         // The source of these annotations is Class<?> inspectedClass.
 2368  
         // Because Class<?> and its annotations cannot change
 2369  
         // during request/response, it is sufficient to process Class<?> only once per view.
 2370  0
         RequestViewContext rvc = RequestViewContext.getCurrentInstance(context);
 2371  0
         if (rvc.isClassAlreadyProcessed(inspectedClass))
 2372  
         {
 2373  0
             return;
 2374  
         }
 2375  0
         boolean classAlreadyProcessed = false;
 2376  
 
 2377  
         
 2378  0
         List<ResourceDependency> dependencyList = null;
 2379  0
         boolean isCachedList = false;
 2380  
         
 2381  0
         if(isProduction)
 2382  
         {
 2383  0
             dependencyList = _classToResourceDependencyMap.get(inspectedClass);
 2384  
 
 2385  0
             if (dependencyList != null)
 2386  
             {
 2387  0
                 if (dependencyList.isEmpty())
 2388  
                 {
 2389  0
                     return; //class has been inspected and did not contain any resource dependency annotations
 2390  
                 }
 2391  
                 
 2392  0
                 isCachedList = true;    // else annotations were found in the cache
 2393  
             }
 2394  
         }
 2395  
         
 2396  0
         if(dependencyList == null)  //not in production or the class hasn't been inspected yet
 2397  
         {   
 2398  0
             ResourceDependency dependency = inspectedClass.getAnnotation(ResourceDependency.class);
 2399  0
             ResourceDependencies dependencies = inspectedClass.getAnnotation(ResourceDependencies.class);
 2400  0
             if(dependency != null || dependencies != null)
 2401  
             {
 2402  
                 //resource dependencies were found using one or both annotations, create and build a new list
 2403  0
                 dependencyList = new ArrayList<ResourceDependency>();
 2404  
                 
 2405  0
                 if(dependency != null)
 2406  
                 {
 2407  0
                     dependencyList.add(dependency);
 2408  
                 }
 2409  
                 
 2410  0
                 if(dependencies != null)
 2411  
                 {
 2412  0
                     dependencyList.addAll(Arrays.asList(dependencies.value()));
 2413  
                 }
 2414  
             }
 2415  
             else
 2416  
             {
 2417  0
                 dependencyList = Collections.emptyList();
 2418  
             }
 2419  
         }        
 2420  
  
 2421  
         // resource dependencies were found through inspection or from cache, handle them
 2422  0
         if (dependencyList != null && !dependencyList.isEmpty()) 
 2423  
         {
 2424  0
             for (int i = 0, size = dependencyList.size(); i < size; i++)
 2425  
             {
 2426  0
                 ResourceDependency dependency = dependencyList.get(i);
 2427  0
                 if (!rvc.isResourceDependencyAlreadyProcessed(dependency))
 2428  
                 {
 2429  0
                     _handleResourceDependency(context, component, dependency, inspectedClass);
 2430  0
                     rvc.setResourceDependencyAsProcessed(dependency);
 2431  
                 }
 2432  
             }
 2433  
         }
 2434  
         
 2435  
         //if we're in production and the list is not yet cached, store it
 2436  0
         if(isProduction && !isCachedList && dependencyList != null)   
 2437  
         {
 2438  
             // Note at this point listenerForList cannot be null, but just let dependencyList != null
 2439  
             // as a sanity check.
 2440  0
             _classToResourceDependencyMap.put(inspectedClass, dependencyList);
 2441  
         }
 2442  
         
 2443  0
         if (!classAlreadyProcessed)
 2444  
         {
 2445  0
             rvc.setClassProcessed(inspectedClass);
 2446  
         }
 2447  0
     }
 2448  
     
 2449  
     private void _handleResourceDependency(FacesContext context, UIComponent component, ResourceDependency annotation,
 2450  
             Class<?> inspectedClass)
 2451  
     {
 2452  
         // If this annotation is not present on the class in question, no action must be taken.
 2453  0
         if (annotation != null)
 2454  
         {
 2455  
             // Create a UIOutput instance by passing javax.faces.Output. to
 2456  
             // Application.createComponent(java.lang.String).
 2457  0
             UIOutput output = (UIOutput) createComponent(context, UIOutput.COMPONENT_TYPE, null);
 2458  
 
 2459  
             // Get the annotation instance from the class and obtain the values of the name, library, and
 2460  
             // target attributes.
 2461  0
             String name = annotation.name();
 2462  0
             if (name != null && name.length() > 0)
 2463  
             {
 2464  0
                 name = ELText.parse(getExpressionFactory(),
 2465  
                                     context.getELContext(), name).toString(context.getELContext());
 2466  
             }
 2467  
 
 2468  
             // Obtain the renderer-type for the resource name by passing name to
 2469  
             // ResourceHandler.getRendererTypeForResourceName(java.lang.String).
 2470  
             // (note that we can not use this.getResourceHandler(), because the Application might be wrapped)
 2471  0
             String rendererType = context.getApplication().getResourceHandler().getRendererTypeForResourceName(name);
 2472  
 
 2473  
             // Call setRendererType on the UIOutput instance, passing the renderer-type.
 2474  0
             output.setRendererType(rendererType);
 2475  
             
 2476  
             // If the @ResourceDependency was done inside facelets processing,
 2477  
             // call setId() and set a proper id from facelets
 2478  0
             setResourceIdOnFaceletsMode(context, output, inspectedClass);
 2479  
 
 2480  
             // Obtain the Map of attributes from the UIOutput component by calling UIComponent.getAttributes().
 2481  0
             Map<String, Object> attributes = output.getAttributes();
 2482  
 
 2483  
             // Store the name into the attributes Map under the key "name".
 2484  0
             attributes.put("name", name);
 2485  
 
 2486  
             // If library is the empty string, let library be null.
 2487  0
             String library = annotation.library();
 2488  0
             if (library != null && library.length() > 0)
 2489  
             {
 2490  0
                 library = ELText.parse(getExpressionFactory(),
 2491  
                                        context.getELContext(), library).toString(context.getELContext());
 2492  
                 // If library is non-null, store it under the key "library".
 2493  0
                 if ("this".equals(library))
 2494  
                 {
 2495  
                     // Special "this" behavior
 2496  0
                     Resource resource = (Resource)component.getAttributes().get(Resource.COMPONENT_RESOURCE_KEY);
 2497  0
                     if (resource != null)
 2498  
                     {
 2499  0
                         attributes.put("library", resource.getLibraryName());
 2500  
                     }
 2501  0
                 }
 2502  
                 else
 2503  
                 {
 2504  0
                     attributes.put("library", library);
 2505  
                 }
 2506  
             }
 2507  
             
 2508  
             // Identify the resource as created by effect of a @ResourceDependency annotation.
 2509  0
             output.getAttributes().put(RequestViewMetadata.RESOURCE_DEPENDENCY_KEY, 
 2510  
                 new Object[]{annotation.library(), annotation.name()});
 2511  
 
 2512  
             // If target is the empty string, let target be null.
 2513  0
             String target = annotation.target();
 2514  0
             if (target != null && target.length() > 0)
 2515  
             {
 2516  0
                 target = ELText.parse(getExpressionFactory(),
 2517  
                                       context.getELContext(), target).toString(context.getELContext());
 2518  
                 // If target is non-null, store it under the key "target".
 2519  0
                 attributes.put("target", target);
 2520  0
                 context.getViewRoot().addComponentResource(context, output, target);
 2521  
             }
 2522  
             else
 2523  
             {
 2524  
                 // Otherwise, if target is null, call UIViewRoot.addComponentResource(javax.faces.context.FacesContext,
 2525  
                 // javax.faces.component.UIComponent), passing the UIOutput instance as the second argument.
 2526  0
                 context.getViewRoot().addComponentResource(context, output);
 2527  
             }
 2528  
         }
 2529  0
     }
 2530  
     
 2531  
     private void _inspectRenderer(FacesContext context, UIComponent component,
 2532  
                                   String componentType, String rendererType)
 2533  
     {
 2534  
         /*
 2535  
          * The Renderer instance to inspect must be obtained by calling FacesContext.getRenderKit() and calling
 2536  
          * RenderKit.getRenderer(java.lang.String, java.lang.String) on the result, passing the argument componentFamily
 2537  
          * of the newly created component as the first argument and the argument rendererType as the second argument.
 2538  
          */
 2539  0
         RenderKit renderKit = context.getRenderKit();
 2540  0
         if (renderKit == null)
 2541  
         {
 2542  
             // If no renderKit is set, it means we are on initialization step, skip this step.
 2543  0
             return;
 2544  
         }
 2545  0
         Renderer renderer = renderKit.getRenderer(component.getFamily(), rendererType);
 2546  0
         if (renderer == null)
 2547  
         {
 2548  
             // If no such Renderer can be found, a message must be logged with a helpful error message.
 2549  0
             log.severe("renderer cannot be found for component type " + componentType + " and renderer type "
 2550  
                     + rendererType);
 2551  
         }
 2552  
         else
 2553  
         {
 2554  
             // Otherwise, UIComponent.setRendererType(java.lang.String) must be called on the newly created
 2555  
             // UIComponent instance, passing the argument rendererType as the argument.
 2556  0
             component.setRendererType(rendererType);
 2557  
 
 2558  
             /*
 2559  
              * except the Renderer for the component to be returned must be inspected for the annotations mentioned in
 2560  
              * createComponent(ValueExpression, FacesContext, String) as specified in the documentation for that method.
 2561  
              */
 2562  0
             _handleRendererAnnotations(context, renderer, component);
 2563  
         }
 2564  0
     }
 2565  
 
 2566  
     private static SystemEvent _traverseListenerList(List<? extends SystemEventListener> listeners,
 2567  
                                                      Class<? extends SystemEvent> systemEventClass, Object source,
 2568  
                                                      SystemEvent event)
 2569  
     {
 2570  0
         if (listeners != null && !listeners.isEmpty())
 2571  
         {
 2572  
             // perf: org.apache.myfaces.application.ApplicationImpl.
 2573  
             //    SystemListenerEntry.getSpecificSourceListenersNotNull(Class<?>)
 2574  
             // or javax.faces.component.UIComponent.subscribeToEvent(
 2575  
             //      Class<? extends SystemEvent>, ComponentSystemEventListener)
 2576  
             // creates a ArrayList:
 2577  0
             for (int i  = 0, size = listeners.size(); i < size; i++)
 2578  
             {
 2579  0
                 SystemEventListener listener = listeners.get(i);
 2580  
                 // Call SystemEventListener.isListenerForSource(java.lang.Object), passing the source argument.
 2581  
                 // If this returns false, take no action on the listener.
 2582  0
                 if (listener.isListenerForSource(source))
 2583  
                 {
 2584  
                     // Otherwise, if the event to be passed to the listener instances has not yet been constructed,
 2585  
                     // construct the event, passing source as the argument to the one-argument constructor that takes
 2586  
                     // an Object. This same event instance must be passed to all listener instances.
 2587  0
                     event = _createEvent(systemEventClass, source, event);
 2588  
 
 2589  
                     // Call SystemEvent.isAppropriateListener(javax.faces.event.FacesListener), passing the listener
 2590  
                     // instance as the argument. If this returns false, take no action on the listener.
 2591  0
                     if (event.isAppropriateListener(listener))
 2592  
                     {
 2593  
                         // Call SystemEvent.processListener(javax.faces.event.FacesListener), passing the listener
 2594  
                         // instance.
 2595  0
                         event.processListener(listener);
 2596  
                     }
 2597  
                 }
 2598  
             }
 2599  
         }
 2600  
 
 2601  0
         return event;
 2602  
     }
 2603  
     
 2604  
     private static SystemEvent _traverseListenerListWithCopy(List<? extends SystemEventListener> listeners,
 2605  
             Class<? extends SystemEvent> systemEventClass, Object source,
 2606  
             SystemEvent event)
 2607  
     {
 2608  0
         if (listeners != null && !listeners.isEmpty())
 2609  
         {
 2610  0
             List<SystemEventListener> listenersCopy = new ArrayList<SystemEventListener>();
 2611  0
             int processedListenerIndex = 0;
 2612  
             
 2613  0
             for (int i = 0; i < listeners.size(); i++)
 2614  
             {
 2615  0
                 listenersCopy.add(listeners.get(i));
 2616  
             }
 2617  
             
 2618  
             // If the inner for is succesful, processedListenerIndex == listenersCopy.size()
 2619  
             // and the loop will be complete.
 2620  0
             while (processedListenerIndex < listenersCopy.size())
 2621  
             {                
 2622  0
                 for (; processedListenerIndex < listenersCopy.size(); processedListenerIndex++ )
 2623  
                 {
 2624  0
                     SystemEventListener listener = listenersCopy.get(processedListenerIndex);
 2625  
                     // Call SystemEventListener.isListenerForSource(java.lang.Object), passing the source argument.
 2626  
                     // If this returns false, take no action on the listener.
 2627  0
                     if (listener.isListenerForSource(source))
 2628  
                     {
 2629  
                         // Otherwise, if the event to be passed to the listener instances has not yet been constructed,
 2630  
                         // construct the event, passing source as the argument
 2631  
                         // to the one-argument constructor that takes
 2632  
                         // an Object. This same event instance must be passed to all listener instances.
 2633  0
                         event = _createEvent(systemEventClass, source, event);
 2634  
     
 2635  
                         // Call SystemEvent.isAppropriateListener(javax.faces.event.FacesListener), passing the listener
 2636  
                         // instance as the argument. If this returns false, take no action on the listener.
 2637  0
                         if (event.isAppropriateListener(listener))
 2638  
                         {
 2639  
                             // Call SystemEvent.processListener(javax.faces.event.FacesListener), passing the listener
 2640  
                             // instance.
 2641  0
                             event.processListener(listener);
 2642  
                         }
 2643  
                     }
 2644  
                 }
 2645  
                 
 2646  0
                 boolean listChanged = false;
 2647  0
                 if (listeners.size() == listenersCopy.size())
 2648  
                 {
 2649  0
                     for (int i = 0; i < listenersCopy.size(); i++)
 2650  
                     {
 2651  0
                         if (listenersCopy.get(i) != listeners.get(i))
 2652  
                         {
 2653  0
                             listChanged = true;
 2654  0
                             break;
 2655  
                         }
 2656  
                     }
 2657  
                 }
 2658  
                 else
 2659  
                 {
 2660  0
                     listChanged = true;
 2661  
                 }
 2662  
                 
 2663  0
                 if (listChanged)
 2664  
                 {
 2665  0
                     for (int i = 0; i < listeners.size(); i++)
 2666  
                     {
 2667  0
                         SystemEventListener listener = listeners.get(i);
 2668  
                         
 2669  
                         // check if listenersCopy.get(i) is valid
 2670  0
                         if (i < listenersCopy.size())
 2671  
                         {
 2672  
                             // The normal case is a listener was added, 
 2673  
                             // so as heuristic, check first
 2674  
                             // if we can find it at the same location
 2675  0
                             if (!listener.equals(listenersCopy.get(i)) &&
 2676  
                                 !listenersCopy.contains(listener))
 2677  
                             {
 2678  0
                                 listenersCopy.add(listener);
 2679  
                             }
 2680  
                         }
 2681  
                         else
 2682  
                         {
 2683  0
                             if (!listenersCopy.contains(listener))
 2684  
                             {
 2685  0
                                 listenersCopy.add(listener);
 2686  
                             }
 2687  
                         }
 2688  
                     }
 2689  
                 }
 2690  0
             }
 2691  
         }
 2692  
 
 2693  0
         return event;
 2694  
     }
 2695  
 
 2696  
     /**
 2697  
      * Method to handle determining if the first request has 
 2698  
      * been handled by the associated LifecycleImpl.
 2699  
      * @return true if the first request has already been processed, false otherwise
 2700  
      */
 2701  
     private boolean isFirstRequestProcessed()
 2702  
     {
 2703  0
         FacesContext context = FacesContext.getCurrentInstance();
 2704  
         
 2705  
         //if firstRequestProcessed is not set, check the application map
 2706  0
         if(!_firstRequestProcessed && context != null 
 2707  
                 && Boolean.TRUE.equals(context.getExternalContext().getApplicationMap()
 2708  
                         .containsKey(LifecycleImpl.FIRST_REQUEST_PROCESSED_PARAM)))
 2709  
         {
 2710  0
             _firstRequestProcessed = true;
 2711  
         }
 2712  0
         return _firstRequestProcessed;
 2713  
     }
 2714  
     
 2715  0
     private static class SystemListenerEntry
 2716  
     {
 2717  
         private List<SystemEventListener> _lstSystemEventListener;
 2718  
         private Map<Class<?>, List<SystemEventListener>> _sourceClassMap;
 2719  
 
 2720  
         public SystemListenerEntry()
 2721  0
         {
 2722  0
         }
 2723  
 
 2724  
         public void addListener(SystemEventListener listener)
 2725  
         {
 2726  0
             assert listener != null;
 2727  
 
 2728  0
             addListenerNoDuplicate(getAnySourceListenersNotNull(), listener);
 2729  0
         }
 2730  
 
 2731  
         public void addListener(SystemEventListener listener, Class<?> source)
 2732  
         {
 2733  0
             assert listener != null;
 2734  
 
 2735  0
             if (source == null)
 2736  
             {
 2737  0
                 addListener(listener);
 2738  
             }
 2739  
             else
 2740  
             {
 2741  0
                 addListenerNoDuplicate(getSpecificSourceListenersNotNull(source), listener);
 2742  
             }
 2743  0
         }
 2744  
 
 2745  
         public void removeListener(SystemEventListener listener)
 2746  
         {
 2747  0
             assert listener != null;
 2748  
 
 2749  0
             if (_lstSystemEventListener != null)
 2750  
             {
 2751  0
                 _lstSystemEventListener.remove(listener);
 2752  
             }
 2753  0
         }
 2754  
 
 2755  
         public void removeListener(SystemEventListener listener, Class<?> sourceClass)
 2756  
         {
 2757  0
             assert listener != null;
 2758  
 
 2759  0
             if (sourceClass == null)
 2760  
             {
 2761  0
                 removeListener(listener);
 2762  
             }
 2763  
             else
 2764  
             {
 2765  0
                 if (_sourceClassMap != null)
 2766  
                 {
 2767  0
                     List<SystemEventListener> listeners = _sourceClassMap.get(sourceClass);
 2768  0
                     if (listeners != null)
 2769  
                     {
 2770  0
                         listeners.remove(listener);
 2771  
                     }
 2772  
                 }
 2773  
             }
 2774  0
         }
 2775  
 
 2776  
         public void publish(Class<? extends SystemEvent> systemEventClass, Class<?> classSource, Object source,
 2777  
                             SystemEvent event)
 2778  
         {
 2779  0
             if (source != null && _sourceClassMap != null)
 2780  
             {
 2781  0
                 event = _traverseListenerList(_sourceClassMap.get(classSource), systemEventClass, source, event);
 2782  
             }
 2783  
 
 2784  0
             _traverseListenerList(_lstSystemEventListener, systemEventClass, source, event);
 2785  0
         }
 2786  
 
 2787  
         private void addListenerNoDuplicate(List<SystemEventListener> listeners, SystemEventListener listener)
 2788  
         {
 2789  0
             if (!listeners.contains(listener))
 2790  
             {
 2791  0
                 listeners.add(listener);
 2792  
             }
 2793  0
         }
 2794  
 
 2795  
         private synchronized List<SystemEventListener> getAnySourceListenersNotNull()
 2796  
         {
 2797  0
             if (_lstSystemEventListener == null)
 2798  
             {
 2799  
                 /*
 2800  
                  * TODO: Check if modification occurs often or not, might have to use a synchronized list instead.
 2801  
                  * 
 2802  
                  * Registrations found:
 2803  
                  */
 2804  0
                 _lstSystemEventListener = new CopyOnWriteArrayList<SystemEventListener>();
 2805  
             }
 2806  
 
 2807  0
             return _lstSystemEventListener;
 2808  
         }
 2809  
 
 2810  
         private synchronized List<SystemEventListener> getSpecificSourceListenersNotNull(Class<?> sourceClass)
 2811  
         {
 2812  0
             if (_sourceClassMap == null)
 2813  
             {
 2814  0
                 _sourceClassMap = new ConcurrentHashMap<Class<?>, List<SystemEventListener>>();
 2815  
             }
 2816  
 
 2817  0
             List<SystemEventListener> list = _sourceClassMap.get(sourceClass);
 2818  0
             if (list == null)
 2819  
             {
 2820  
                 /*
 2821  
                  * TODO: Check if modification occurs often or not, might have to use a synchronized list instead.
 2822  
                  * 
 2823  
                  * Registrations found:
 2824  
                  */
 2825  0
                 list = new CopyOnWriteArrayList<SystemEventListener>();
 2826  0
                 _sourceClassMap.put(sourceClass, list);
 2827  
             }
 2828  
 
 2829  0
             return list;
 2830  
         }
 2831  
     }
 2832  
     
 2833  
     /*
 2834  
      * private method to look for config objects on a classmap.  The objects can be either a type string
 2835  
      * or a Class<?> object.  This is done to facilitate lazy loading of config objects.   
 2836  
      * @param id 
 2837  
      * @param classMap 
 2838  
      * @return
 2839  
      */
 2840  
     private <T> Class<? extends T> getObjectFromClassMap(String id, Map<String, Object> classMap)
 2841  
     {
 2842  0
         Object obj = classMap.get(id);
 2843  
         
 2844  0
         if(obj == null)
 2845  
         {
 2846  0
             return null;    //object for this id wasn't found on the map
 2847  
         }
 2848  
         
 2849  0
         if(obj instanceof Class<?>)
 2850  
         {
 2851  0
             return (Class<? extends T>)obj;
 2852  
         }
 2853  0
         else if (obj instanceof String )
 2854  
         {
 2855  0
             Class<?> clazz = ClassUtils.simpleClassForName((String)obj);
 2856  0
             classMap.put(id, clazz);
 2857  0
             return (Class<? extends T>)clazz;
 2858  
         }
 2859  
         
 2860  
         //object stored in the map for this id is an invalid type.  remove it and return null
 2861  0
         classMap.remove(id);
 2862  0
         return null;        
 2863  
     }
 2864  
     
 2865  
     private boolean isLazyLoadConfigObjects()
 2866  
     {
 2867  0
         if (_lazyLoadConfigObjects == null)
 2868  
         {
 2869  0
             String configParam
 2870  
                     = getFaceContext().getExternalContext().getInitParameter(LAZY_LOAD_CONFIG_OBJECTS_PARAM_NAME);
 2871  0
             _lazyLoadConfigObjects = configParam == null
 2872  
                                      ? LAZY_LOAD_CONFIG_OBJECTS_DEFAULT_VALUE
 2873  
                                      : Boolean.parseBoolean(configParam);
 2874  
         }
 2875  0
         return _lazyLoadConfigObjects;
 2876  
     }
 2877  
 }