Coverage Report - org.apache.myfaces.application.ApplicationImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
ApplicationImpl
0%
0/319
0%
0/104
0
 
 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.lang.reflect.Constructor;
 22  
 import java.util.ArrayList;
 23  
 import java.util.Collection;
 24  
 import java.util.Collections;
 25  
 import java.util.Iterator;
 26  
 import java.util.Locale;
 27  
 import java.util.Map;
 28  
 import java.util.MissingResourceException;
 29  
 import java.util.concurrent.ConcurrentHashMap;
 30  
 
 31  
 import javax.el.CompositeELResolver;
 32  
 import javax.el.ELContext;
 33  
 import javax.el.ELContextListener;
 34  
 import javax.el.ELException;
 35  
 import javax.el.ELResolver;
 36  
 import javax.el.ExpressionFactory;
 37  
 import javax.el.MethodExpression;
 38  
 import javax.el.ValueExpression;
 39  
 import javax.faces.FacesException;
 40  
 import javax.faces.application.Application;
 41  
 import javax.faces.application.NavigationHandler;
 42  
 import javax.faces.application.StateManager;
 43  
 import javax.faces.application.ViewHandler;
 44  
 import javax.faces.component.UIComponent;
 45  
 import javax.faces.component.UIViewRoot;
 46  
 import javax.faces.context.FacesContext;
 47  
 import javax.faces.convert.Converter;
 48  
 import javax.faces.el.MethodBinding;
 49  
 import javax.faces.el.PropertyResolver;
 50  
 import javax.faces.el.ReferenceSyntaxException;
 51  
 import javax.faces.el.ValueBinding;
 52  
 import javax.faces.el.VariableResolver;
 53  
 import javax.faces.event.ActionListener;
 54  
 import javax.faces.validator.Validator;
 55  
 
 56  
 import org.apache.commons.beanutils.BeanUtils;
 57  
 import org.apache.commons.logging.Log;
 58  
 import org.apache.commons.logging.LogFactory;
 59  
 import org.apache.myfaces.application.jsp.JspStateManagerImpl;
 60  
 import org.apache.myfaces.application.jsp.JspViewHandlerImpl;
 61  
 import org.apache.myfaces.config.RuntimeConfig;
 62  
 import org.apache.myfaces.config.impl.digester.elements.Property;
 63  
 import org.apache.myfaces.config.impl.digester.elements.ResourceBundle;
 64  
 import org.apache.myfaces.el.PropertyResolverImpl;
 65  
 import org.apache.myfaces.el.VariableResolverToApplicationELResolverAdapter;
 66  
 import org.apache.myfaces.el.convert.MethodExpressionToMethodBinding;
 67  
 import org.apache.myfaces.el.convert.ValueBindingToValueExpression;
 68  
 import org.apache.myfaces.el.convert.ValueExpressionToValueBinding;
 69  
 import org.apache.myfaces.el.unified.ELResolverBuilder;
 70  
 import org.apache.myfaces.el.unified.ResolverBuilderForFaces;
 71  
 import org.apache.myfaces.el.unified.resolver.FacesCompositeELResolver;
 72  
 import org.apache.myfaces.el.unified.resolver.FacesCompositeELResolver.Scope;
 73  
 import org.apache.myfaces.shared_impl.util.ClassUtils;
 74  
 
 75  
 /**
 76  
  * DOCUMENT ME!
 77  
  *
 78  
  * @author Manfred Geiler (latest modification by $Author: lu4242 $)
 79  
  * @author Anton Koinov
 80  
  * @author Thomas Spiegl
 81  
  * @author Stan Silvert
 82  
  * @version $Revision: 924403 $ $Date: 2010-03-17 13:28:20 -0500 (Wed, 17 Mar 2010) $
 83  
  */
 84  
 @SuppressWarnings("deprecation")
 85  
 public class ApplicationImpl extends Application
 86  
 {
 87  0
     private static final Log log = LogFactory.getLog(ApplicationImpl.class);
 88  
 
 89  0
     private final static VariableResolver VARIABLERESOLVER = new VariableResolverToApplicationELResolverAdapter();
 90  
 
 91  0
     private final static PropertyResolver PROPERTYRESOLVER = new PropertyResolverImpl();
 92  
 
 93  
     // recives the runtime config instance during initializing
 94  0
     private final static ThreadLocal<RuntimeConfig> initializingRuntimeConfig = new ThreadLocal<RuntimeConfig>();
 95  
 
 96  
     // ~ Instance fields
 97  
     // ----------------------------------------------------------------------------
 98  
 
 99  0
     private Collection<Locale> _supportedLocales = Collections.emptySet();
 100  
     private Locale _defaultLocale;
 101  
     private String _messageBundle;
 102  
 
 103  
     private ViewHandler _viewHandler;
 104  
     private NavigationHandler _navigationHandler;
 105  
     private ActionListener _actionListener;
 106  
     private String _defaultRenderKitId;
 107  
     private StateManager _stateManager;
 108  
 
 109  
     private ArrayList<ELContextListener> _elContextListeners;
 110  
 
 111  
     // components, converters, and validators can be added at runtime--must
 112  
     // synchronize, uses ConcurrentHashMap to allow concurrent read of map
 113  0
     private final Map<String, Class> _converterIdToClassMap = new ConcurrentHashMap<String, Class>();
 114  0
     private final Map<Class, String> _converterClassNameToClassMap = new ConcurrentHashMap<Class, String>();
 115  0
     private final Map<String, org.apache.myfaces.config.impl.digester.elements.Converter> _converterClassNameToConfigurationMap = new ConcurrentHashMap<String, org.apache.myfaces.config.impl.digester.elements.Converter>();
 116  0
     private final Map<String, Class> _componentClassMap = new ConcurrentHashMap<String, Class>();
 117  0
     private final Map<String, Class> _validatorClassMap = new ConcurrentHashMap<String, Class>();
 118  
 
 119  
     private final RuntimeConfig _runtimeConfig;
 120  
 
 121  
     private ELResolver elResolver;
 122  
 
 123  
     private ELResolverBuilder resolverBuilderForFaces;
 124  
 
 125  
     // ~ Constructors
 126  
     // -------------------------------------------------------------------------------
 127  
 
 128  
     public ApplicationImpl()
 129  
     {
 130  0
         this(internalGetRuntimeConfig());
 131  0
     }
 132  
 
 133  
     private static RuntimeConfig internalGetRuntimeConfig()
 134  
     {
 135  0
         if (initializingRuntimeConfig.get() == null)
 136  
         {
 137  
             //It may happen that the current thread value
 138  
             //for initializingRuntimeConfig is not set 
 139  
             //(note that this value is final, so it just 
 140  
             //allow set only once per thread).
 141  
             //So the better for this case is try to get
 142  
             //the value using RuntimeConfig.getCurrentInstance()
 143  
             //instead throw an IllegalStateException (only fails if
 144  
             //the constructor is called before setInitializingRuntimeConfig).
 145  
             //From other point of view, AbstractFacesInitializer do 
 146  
             //the same as below, so there is not problem if
 147  
             //we do this here and this is the best place to do
 148  
             //this.
 149  
             //log.info("initializingRuntimeConfig.get() == null, so loading from ExternalContext");
 150  0
             ApplicationImpl.setInitializingRuntimeConfig(
 151  
                     RuntimeConfig.getCurrentInstance(
 152  
                             FacesContext.getCurrentInstance()
 153  
                             .getExternalContext()));
 154  
 
 155  
             //throw new IllegalStateException("The runtime config instance which is created while initialize myfaces "
 156  
             //        + "must be set through ApplicationImpl.setInitializingRuntimeConfig");
 157  
         }
 158  0
         return initializingRuntimeConfig.get();
 159  
     }
 160  
 
 161  
     ApplicationImpl(final RuntimeConfig runtimeConfig)
 162  0
     {
 163  0
         if (runtimeConfig == null)
 164  
         {
 165  0
             throw new IllegalArgumentException("runtimeConfig must mot be null");
 166  
         }
 167  
         // set default implementation in constructor
 168  
         // pragmatic approach, no syncronizing will be needed in get methods
 169  0
         _viewHandler = new JspViewHandlerImpl();
 170  0
         _navigationHandler = new NavigationHandlerImpl();
 171  0
         _actionListener = new ActionListenerImpl();
 172  0
         _defaultRenderKitId = "HTML_BASIC";
 173  0
         _stateManager = new JspStateManagerImpl();
 174  0
         _elContextListeners = new ArrayList<ELContextListener>();
 175  0
         _runtimeConfig = runtimeConfig;
 176  
 
 177  0
         if (log.isTraceEnabled())
 178  0
             log.trace("New Application instance created");
 179  0
     }
 180  
 
 181  
     public static void setInitializingRuntimeConfig(RuntimeConfig config)
 182  
     {
 183  0
         initializingRuntimeConfig.set(config);
 184  0
     }
 185  
 
 186  
     // ~ Methods
 187  
     // ------------------------------------------------------------------------------------
 188  
 
 189  
     @Override
 190  
     public final void addELResolver(final ELResolver resolver)
 191  
     {
 192  0
         if (FacesContext.getCurrentInstance() != null)
 193  
         {
 194  0
             throw new IllegalStateException("It is illegal to add a resolver after the first request is processed");
 195  
         }
 196  0
         if (resolver != null)
 197  
         {
 198  0
             _runtimeConfig.addApplicationElResolver(resolver);
 199  
         }
 200  0
     }
 201  
 
 202  
     @Override
 203  
     public final ELResolver getELResolver()
 204  
     {
 205  
         // we don't need synchronization here since it is ok to have multiple instances of the elresolver
 206  0
         if (elResolver == null)
 207  
         {
 208  0
             elResolver = createFacesResolver();
 209  
         }
 210  0
         return elResolver;
 211  
     }
 212  
 
 213  
     private ELResolver createFacesResolver()
 214  
     {
 215  0
         final CompositeELResolver resolver = new FacesCompositeELResolver(Scope.Faces);
 216  0
         getResolverBuilderForFaces().build(resolver);
 217  0
         return resolver;
 218  
     }
 219  
 
 220  
     protected final ELResolverBuilder getResolverBuilderForFaces()
 221  
     {
 222  0
         if (resolverBuilderForFaces == null)
 223  
         {
 224  0
             resolverBuilderForFaces = new ResolverBuilderForFaces(_runtimeConfig);
 225  
         }
 226  0
         return resolverBuilderForFaces;
 227  
     }
 228  
 
 229  
     public final void setResolverBuilderForFaces(final ELResolverBuilder factory)
 230  
     {
 231  0
         resolverBuilderForFaces = factory;
 232  0
     }
 233  
 
 234  
     @Override
 235  
     public final java.util.ResourceBundle getResourceBundle(final FacesContext facesContext, final String name) throws FacesException,
 236  
             NullPointerException
 237  
     {
 238  
 
 239  0
         checkNull(facesContext, "facesContext");
 240  0
         checkNull(name, "name");
 241  
 
 242  0
         final String bundleName = getBundleName(facesContext, name);
 243  
 
 244  0
         if (bundleName == null)
 245  
         {
 246  0
             return null;
 247  
         }
 248  
 
 249  0
         Locale locale = Locale.getDefault();
 250  
 
 251  0
         final UIViewRoot viewRoot = facesContext.getViewRoot();
 252  0
         if (viewRoot != null && viewRoot.getLocale() != null)
 253  
         {
 254  0
             locale = viewRoot.getLocale();
 255  
         }
 256  
 
 257  
         try
 258  
         {
 259  0
             return getResourceBundle(bundleName, locale, getClassLoader());
 260  
         }
 261  0
         catch (MissingResourceException e)
 262  
         {
 263  
             try
 264  
             {
 265  0
                 return getResourceBundle(bundleName, locale, this.getClass().getClassLoader());
 266  
             }
 267  0
             catch (MissingResourceException e1)
 268  
             {            
 269  0
                 throw new FacesException("Could not load resource bundle for name '" + name + "': " + e.getMessage(), e1);
 270  
             }
 271  
         }
 272  
     }
 273  
 
 274  
     private ClassLoader getClassLoader()
 275  
     {
 276  0
         return ClassUtils.getContextClassLoader();
 277  
     }
 278  
 
 279  
     String getBundleName(final FacesContext facesContext, final String name)
 280  
     {
 281  0
         ResourceBundle bundle = getRuntimeConfig(facesContext).getResourceBundle(name);
 282  0
         return bundle != null ? bundle.getBaseName() : null;
 283  
     }
 284  
 
 285  
     java.util.ResourceBundle getResourceBundle(final String name, final Locale locale, final ClassLoader loader)
 286  
             throws MissingResourceException
 287  
     {
 288  0
         return java.util.ResourceBundle.getBundle(name, locale, loader);
 289  
     }
 290  
 
 291  
     final RuntimeConfig getRuntimeConfig(final FacesContext facesContext)
 292  
     {
 293  0
         return RuntimeConfig.getCurrentInstance(facesContext.getExternalContext());
 294  
     }
 295  
 
 296  
     final FacesContext getFaceContext()
 297  
     {
 298  0
         return FacesContext.getCurrentInstance();
 299  
     }
 300  
 
 301  
     @Override
 302  
     public final UIComponent createComponent(final ValueExpression componentExpression, final FacesContext facesContext,
 303  
             final String componentType) throws FacesException, NullPointerException
 304  
     {
 305  
 
 306  0
         checkNull(componentExpression, "componentExpression");
 307  0
         checkNull(facesContext, "facesContext");
 308  0
         checkNull(componentType, "componentType");
 309  
 
 310  0
         final ELContext elContext = facesContext.getELContext();
 311  
 
 312  
         try
 313  
         {
 314  0
             final Object retVal = componentExpression.getValue(elContext);
 315  
 
 316  
             UIComponent createdComponent;
 317  
 
 318  0
             if (retVal instanceof UIComponent)
 319  
             {
 320  0
                 createdComponent = (UIComponent) retVal;
 321  
             }
 322  
             else
 323  
             {
 324  0
                 createdComponent = createComponent(componentType);
 325  0
                 componentExpression.setValue(elContext, createdComponent);
 326  
             }
 327  
 
 328  0
             return createdComponent;
 329  
         }
 330  0
         catch (FacesException e)
 331  
         {
 332  0
             throw e;
 333  
         }
 334  0
         catch (Exception e)
 335  
         {
 336  0
             throw new FacesException(e);
 337  
         }
 338  
     }
 339  
 
 340  
     @Override
 341  
     public final ExpressionFactory getExpressionFactory()
 342  
     {
 343  0
         return _runtimeConfig.getExpressionFactory();
 344  
     }
 345  
 
 346  
     @Override
 347  
     public final Object evaluateExpressionGet(final FacesContext context, final String expression, final Class expectedType) throws ELException
 348  
     {
 349  0
         ELContext elContext = context.getELContext();
 350  0
         return getExpressionFactory().createValueExpression(elContext, expression, expectedType).getValue(elContext);
 351  
     }
 352  
 
 353  
     @Override
 354  
     public final void addELContextListener(final ELContextListener listener)
 355  
     {
 356  
 
 357  0
         synchronized (_elContextListeners)
 358  
         {
 359  0
             _elContextListeners.add(listener);
 360  0
         }
 361  0
     }
 362  
 
 363  
     @Override
 364  
     public final void removeELContextListener(final ELContextListener listener)
 365  
     {
 366  0
         synchronized (_elContextListeners)
 367  
         {
 368  0
             _elContextListeners.remove(listener);
 369  0
         }
 370  0
     }
 371  
 
 372  
     @Override
 373  
     public final ELContextListener[] getELContextListeners()
 374  
     {
 375  
         // this gets called on every request, so I can't afford to synchronize
 376  
         // I just have to trust that toArray() with do the right thing if the
 377  
         // list is changing (not likely)
 378  0
         return _elContextListeners.toArray(new ELContextListener[_elContextListeners.size()]);
 379  
     }
 380  
 
 381  
     @Override
 382  
     public final void setActionListener(final ActionListener actionListener)
 383  
     {
 384  0
         checkNull(actionListener, "actionListener");
 385  
 
 386  0
         _actionListener = actionListener;
 387  0
         if (log.isTraceEnabled())
 388  0
             log.trace("set actionListener = " + actionListener.getClass().getName());
 389  0
     }
 390  
 
 391  
     @Override
 392  
     public final ActionListener getActionListener()
 393  
     {
 394  0
         return _actionListener;
 395  
     }
 396  
 
 397  
     @Override
 398  
     public final Iterator<String> getComponentTypes()
 399  
     {
 400  0
         return _componentClassMap.keySet().iterator();
 401  
     }
 402  
 
 403  
     @Override
 404  
     public final Iterator<String> getConverterIds()
 405  
     {
 406  0
         return _converterIdToClassMap.keySet().iterator();
 407  
     }
 408  
 
 409  
     @Override
 410  
     public final Iterator<Class> getConverterTypes()
 411  
     {
 412  0
         return _converterClassNameToClassMap.keySet().iterator();
 413  
     }
 414  
 
 415  
     @Override
 416  
     public final void setDefaultLocale(final Locale locale)
 417  
     {
 418  0
         checkNull(locale, "locale");
 419  
 
 420  0
         _defaultLocale = locale;
 421  0
         if (log.isTraceEnabled())
 422  0
             log.trace("set defaultLocale = " + locale.getCountry() + " " + locale.getLanguage());
 423  0
     }
 424  
 
 425  
     @Override
 426  
     public final Locale getDefaultLocale()
 427  
     {
 428  0
         return _defaultLocale;
 429  
     }
 430  
 
 431  
     @Override
 432  
     public final void setMessageBundle(final String messageBundle)
 433  
     {
 434  0
         checkNull(messageBundle, "messageBundle");
 435  
 
 436  0
         _messageBundle = messageBundle;
 437  0
         if (log.isTraceEnabled())
 438  0
             log.trace("set MessageBundle = " + messageBundle);
 439  0
     }
 440  
 
 441  
     @Override
 442  
     public final String getMessageBundle()
 443  
     {
 444  0
         return _messageBundle;
 445  
     }
 446  
 
 447  
     @Override
 448  
     public final void setNavigationHandler(final NavigationHandler navigationHandler)
 449  
     {
 450  0
         checkNull(navigationHandler, "navigationHandler");
 451  
 
 452  0
         _navigationHandler = navigationHandler;
 453  0
         if (log.isTraceEnabled())
 454  0
             log.trace("set NavigationHandler = " + navigationHandler.getClass().getName());
 455  0
     }
 456  
 
 457  
     @Override
 458  
     public final NavigationHandler getNavigationHandler()
 459  
     {
 460  0
         return _navigationHandler;
 461  
     }
 462  
 
 463  
     /**
 464  
      * @deprecated
 465  
      */
 466  
     @Deprecated
 467  
     @Override
 468  
     public final void setPropertyResolver(final PropertyResolver propertyResolver)
 469  
     {
 470  0
         checkNull(propertyResolver, "propertyResolver");
 471  
 
 472  0
         if (getFaceContext() != null)
 473  
         {
 474  0
             throw new IllegalStateException("propertyResolver must be defined before request processing");
 475  
         }
 476  
 
 477  0
         _runtimeConfig.setPropertyResolver(propertyResolver);
 478  
 
 479  0
         if (log.isTraceEnabled())
 480  0
             log.trace("set PropertyResolver = " + propertyResolver.getClass().getName());
 481  0
     }
 482  
 
 483  
     /**
 484  
      * @deprecated
 485  
      */
 486  
     @Deprecated
 487  
     @Override
 488  
     public final PropertyResolver getPropertyResolver()
 489  
     {
 490  0
         return PROPERTYRESOLVER;
 491  
     }
 492  
 
 493  
     @Override
 494  
     public final void setSupportedLocales(final Collection<Locale> locales)
 495  
     {
 496  0
         checkNull(locales, "locales");
 497  
 
 498  0
         _supportedLocales = locales;
 499  0
         if (log.isTraceEnabled())
 500  0
             log.trace("set SupportedLocales");
 501  0
     }
 502  
 
 503  
     @Override
 504  
     public final Iterator<Locale> getSupportedLocales()
 505  
     {
 506  0
         return _supportedLocales.iterator();
 507  
     }
 508  
 
 509  
     @Override
 510  
     public final Iterator<String> getValidatorIds()
 511  
     {
 512  0
         return _validatorClassMap.keySet().iterator();
 513  
     }
 514  
 
 515  
     /**
 516  
      * @deprecated
 517  
      */
 518  
     @Deprecated
 519  
     @Override
 520  
     public final void setVariableResolver(final VariableResolver variableResolver)
 521  
     {
 522  0
         checkNull(variableResolver, "variableResolver");
 523  
 
 524  0
         if (getFaceContext() != null)
 525  
         {
 526  0
             throw new IllegalStateException("variableResolver must be defined before request processing");
 527  
         }
 528  
 
 529  0
         _runtimeConfig.setVariableResolver(variableResolver);
 530  
 
 531  0
         if (log.isTraceEnabled())
 532  0
             log.trace("set VariableResolver = " + variableResolver.getClass().getName());
 533  0
     }
 534  
 
 535  
     /**
 536  
      * @deprecated
 537  
      */
 538  
     @Deprecated
 539  
     @Override
 540  
     public final VariableResolver getVariableResolver()
 541  
     {
 542  0
         return VARIABLERESOLVER;
 543  
     }
 544  
 
 545  
     @Override
 546  
     public final void setViewHandler(final ViewHandler viewHandler)
 547  
     {
 548  0
         checkNull(viewHandler, "viewHandler");
 549  
 
 550  0
         _viewHandler = viewHandler;
 551  0
         if (log.isTraceEnabled())
 552  0
             log.trace("set ViewHandler = " + viewHandler.getClass().getName());
 553  0
     }
 554  
 
 555  
     @Override
 556  
     public final ViewHandler getViewHandler()
 557  
     {
 558  0
         return _viewHandler;
 559  
     }
 560  
 
 561  
     @Override
 562  
     public final void addComponent(final String componentType, final String componentClassName)
 563  
     {
 564  0
         checkNull(componentType, "componentType");
 565  0
         checkEmpty(componentType, "componentType");
 566  0
         checkNull(componentClassName, "componentClassName");
 567  0
         checkEmpty(componentClassName, "componentClassName");
 568  
 
 569  
         try
 570  
         {
 571  0
             _componentClassMap.put(componentType, ClassUtils.simpleClassForName(componentClassName));
 572  0
             if (log.isTraceEnabled())
 573  0
                 log.trace("add Component class = " + componentClassName + " for type = " + componentType);
 574  
         }
 575  0
         catch (Exception e)
 576  
         {
 577  0
             log.error("Component class " + componentClassName + " not found", e);
 578  0
         }
 579  0
     }
 580  
 
 581  
     @Override
 582  
     public final void addConverter(final String converterId, final String converterClass)
 583  
     {
 584  0
         checkNull(converterId, "converterId");
 585  0
         checkEmpty(converterId, "converterId");
 586  0
         checkNull(converterClass, "converterClass");
 587  0
         checkEmpty(converterClass, "converterClass");
 588  
 
 589  
         try
 590  
         {
 591  0
             _converterIdToClassMap.put(converterId, ClassUtils.simpleClassForName(converterClass));
 592  0
             if (log.isTraceEnabled())
 593  0
                 log.trace("add Converter id = " + converterId + " converterClass = " + converterClass);
 594  
         }
 595  0
         catch (Exception e)
 596  
         {
 597  0
             log.error("Converter class " + converterClass + " not found", e);
 598  0
         }
 599  0
     }
 600  
 
 601  
     @Override
 602  
     public final void addConverter(final Class targetClass, final String converterClass)
 603  
     {
 604  0
         checkNull(targetClass, "targetClass");
 605  0
         checkNull(converterClass, "converterClass");
 606  0
         checkEmpty(converterClass, "converterClass");
 607  
 
 608  
         try
 609  
         {
 610  0
             _converterClassNameToClassMap.put(targetClass, converterClass);
 611  0
             if (log.isTraceEnabled())
 612  0
                 log.trace("add Converter for class = " + targetClass + " converterClass = " + converterClass);
 613  
         }
 614  0
         catch (Exception e)
 615  
         {
 616  0
             log.error("Converter class " + converterClass + " not found", e);
 617  0
         }
 618  0
     }
 619  
 
 620  
     public final void addConverterConfiguration(final String converterClassName,
 621  
             final org.apache.myfaces.config.impl.digester.elements.Converter configuration)
 622  
     {
 623  0
         checkNull(converterClassName, "converterClassName");
 624  0
         checkEmpty(converterClassName, "converterClassName");
 625  0
         checkNull(configuration, "configuration");
 626  
 
 627  0
         _converterClassNameToConfigurationMap.put(converterClassName, configuration);
 628  0
     }
 629  
 
 630  
     @Override
 631  
     public final void addValidator(final String validatorId, final String validatorClass)
 632  
     {
 633  0
         checkNull(validatorId, "validatorId");
 634  0
         checkEmpty(validatorId, "validatorId");
 635  0
         checkNull(validatorClass, "validatorClass");
 636  0
         checkEmpty(validatorClass, "validatorClass");
 637  
 
 638  
         try
 639  
         {
 640  0
             _validatorClassMap.put(validatorId, ClassUtils.simpleClassForName(validatorClass));
 641  0
             if (log.isTraceEnabled())
 642  0
                 log.trace("add Validator id = " + validatorId + " class = " + validatorClass);
 643  
         }
 644  0
         catch (Exception e)
 645  
         {
 646  0
             log.error("Validator class " + validatorClass + " not found", e);
 647  0
         }
 648  0
     }
 649  
 
 650  
     @Override
 651  
     public final UIComponent createComponent(final String componentType) throws FacesException
 652  
     {
 653  0
         checkNull(componentType, "componentType");
 654  0
         checkEmpty(componentType, "componentType");
 655  
 
 656  0
         final Class componentClass = _componentClassMap.get(componentType);
 657  0
         if (componentClass == null)
 658  
         {
 659  0
             log.error("Undefined component type " + componentType);
 660  0
             throw new FacesException("Undefined component type " + componentType);
 661  
         }
 662  
 
 663  
         try
 664  
         {
 665  0
             return (UIComponent) componentClass.newInstance();
 666  
         }
 667  0
         catch (Exception e)
 668  
         {
 669  0
             log.error("Could not instantiate component componentType = " + componentType, e);
 670  0
             throw new FacesException("Could not instantiate component componentType = " + componentType, e);
 671  
         }
 672  
     }
 673  
 
 674  
     /**
 675  
      * @deprecated Use createComponent(ValueExpression, FacesContext, String) instead.
 676  
      */
 677  
     @Deprecated
 678  
     @Override
 679  
     public final UIComponent createComponent(final ValueBinding valueBinding, final FacesContext facesContext,
 680  
             final String componentType) throws FacesException
 681  
     {
 682  
 
 683  0
         checkNull(valueBinding, "valueBinding");
 684  0
         checkNull(facesContext, "facesContext");
 685  0
         checkNull(componentType, "componentType");
 686  0
         checkEmpty(componentType, "componentType");
 687  
 
 688  0
         final ValueExpression valExpression = new ValueBindingToValueExpression(valueBinding);
 689  
 
 690  0
         return createComponent(valExpression, facesContext, componentType);
 691  
     }
 692  
 
 693  
     /**
 694  
      * Return an instance of the converter class that has been registered under
 695  
      * the specified id.
 696  
      * <p>
 697  
      * Converters are registered via faces-config.xml files, and can also be registered
 698  
      * via the addConverter(String id, Class converterClass) method on this class. Here
 699  
      * the the appropriate Class definition is found, then an instance is created and
 700  
      * returned.
 701  
      * <p>
 702  
      * A converter registered via a config file can have any number of nested attribute or
 703  
      * property tags. The JSF specification is very vague about what effect these nested
 704  
      * tags have. This method ignores nested attribute definitions, but for each nested
 705  
      * property tag the corresponding setter is invoked on the new Converter instance
 706  
      * passing the property's defaultValuer. Basic typeconversion is done so the target
 707  
      * properties on the Converter instance can be String, int, boolean, etc. Note that:
 708  
      * <ol>
 709  
      * <li>the Sun Mojarra JSF implemenation ignores nested property tags completely, so
 710  
      * this behaviour cannot be relied on across implementations.
 711  
      * <li>there is no equivalent functionality for converter classes registered via
 712  
      * the Application.addConverter api method.
 713  
      * </ol>
 714  
      * <p>
 715  
      * Note that this method is most commonly called from the standard f:attribute tag.
 716  
      * As an alternative, most components provide a "converter" attribute which uses an
 717  
      * EL expression to create a Converter instance, in which case this method is not
 718  
      * invoked at all. The converter attribute allows the returned Converter instance to
 719  
      * be configured via normal dependency-injection, and is generally a better choice
 720  
      * than using this method.
 721  
      */
 722  
     @Override
 723  
     public final Converter createConverter(final String converterId)
 724  
     {
 725  0
         checkNull(converterId, "converterId");
 726  0
         checkEmpty(converterId, "converterId");
 727  
 
 728  0
         final Class converterClass = _converterIdToClassMap.get(converterId);
 729  0
         if(converterClass == null)
 730  
         {
 731  0
             throw new FacesException("Could not find any registered converter-class by converterId : "+converterId);
 732  
         }
 733  
 
 734  
         try
 735  
         {
 736  0
             final Converter converter = (Converter) converterClass.newInstance();
 737  
 
 738  0
             setConverterProperties(converterClass, converter);
 739  
 
 740  0
             return converter;
 741  
         }
 742  0
         catch (Exception e)
 743  
         {
 744  0
             log.error("Could not instantiate converter " + converterClass, e);
 745  0
             throw new FacesException("Could not instantiate converter: " + converterClass, e);
 746  
         }
 747  
     }
 748  
 
 749  
     @Override
 750  
     public final Converter createConverter(final Class targetClass)
 751  
     {
 752  0
         checkNull(targetClass, "targetClass");
 753  
 
 754  0
         return internalCreateConverter(targetClass);
 755  
     }
 756  
 
 757  
     private Converter internalCreateConverter(final Class targetClass)
 758  
     {
 759  
         // Locate a Converter registered for the target class itself.
 760  0
         String converterClassName = _converterClassNameToClassMap.get(targetClass);
 761  
 
 762  
         // Locate a Converter registered for interfaces that are
 763  
         // implemented by the target class (directly or indirectly).
 764  0
         if (converterClassName == null)
 765  
         {
 766  0
             final Class interfaces[] = targetClass.getInterfaces();
 767  0
             if (interfaces != null)
 768  
             {
 769  0
                 for (int i = 0, len = interfaces.length; i < len; i++)
 770  
                 {
 771  
                     // search all superinterfaces for a matching converter,
 772  
                     // create it
 773  0
                     final Converter converter = internalCreateConverter(interfaces[i]);
 774  0
                     if (converter != null)
 775  
                     {
 776  0
                         return converter;
 777  
                     }
 778  
                 }
 779  
             }
 780  
         }
 781  
 
 782  
         // Get EnumConverter for enum classes with no special converter, check
 783  
         // here as recursive call with java.lang.Enum will not work
 784  0
         if (converterClassName == null && targetClass.isEnum()) {
 785  0
             converterClassName = _converterClassNameToClassMap.get(Enum.class);
 786  
         }
 787  
 
 788  0
         if (converterClassName != null)
 789  
         {
 790  
             try
 791  
             {
 792  0
                 final Class converterClass = ClassUtils.simpleClassForName(converterClassName);
 793  
 
 794  0
                 Converter converter = null;
 795  
                 try
 796  
                 {
 797  
                     // look for a constructor that takes a single Class object
 798  
                     // See JSF 1.2 javadoc for Converter
 799  0
                     final Constructor constructor = converterClass.getConstructor(new Class[] { Class.class });
 800  0
                     converter = (Converter) constructor.newInstance(new Object[] { targetClass });
 801  
                 }
 802  0
                 catch (Exception e)
 803  
                 {
 804  
                     // if there is no matching constructor use no-arg
 805  
                     // constructor
 806  0
                     converter = (Converter) converterClass.newInstance();
 807  0
                 }
 808  
 
 809  0
                 setConverterProperties(converterClass, converter);
 810  
 
 811  0
                 return converter;
 812  
             }
 813  0
             catch (Exception e)
 814  
             {
 815  0
                 log.error("Could not instantiate converter " + converterClassName, e);
 816  0
                 throw new FacesException("Could not instantiate converter: " + converterClassName, e);
 817  
             }
 818  
         }
 819  
 
 820  
         // locate converter for primitive types
 821  0
         if (targetClass == Long.TYPE)
 822  
         {
 823  0
             return internalCreateConverter(Long.class);
 824  
         }
 825  0
         else if (targetClass == Boolean.TYPE)
 826  
         {
 827  0
             return internalCreateConverter(Boolean.class);
 828  
         }
 829  0
         else if (targetClass == Double.TYPE)
 830  
         {
 831  0
             return internalCreateConverter(Double.class);
 832  
         }
 833  0
         else if (targetClass == Byte.TYPE)
 834  
         {
 835  0
             return internalCreateConverter(Byte.class);
 836  
         }
 837  0
         else if (targetClass == Short.TYPE)
 838  
         {
 839  0
             return internalCreateConverter(Short.class);
 840  
         }
 841  0
         else if (targetClass == Integer.TYPE)
 842  
         {
 843  0
             return internalCreateConverter(Integer.class);
 844  
         }
 845  0
         else if (targetClass == Float.TYPE)
 846  
         {
 847  0
             return internalCreateConverter(Float.class);
 848  
         }
 849  0
         else if (targetClass == Character.TYPE)
 850  
         {
 851  0
             return internalCreateConverter(Character.class);
 852  
         }
 853  
 
 854  
         // Locate a Converter registered for the superclass (if any) of the
 855  
         // target class,
 856  
         // recursively working up the inheritance hierarchy.
 857  0
         Class superClazz = targetClass.getSuperclass();
 858  
 
 859  0
         return superClazz != null ? internalCreateConverter(superClazz) : null;
 860  
 
 861  
     }
 862  
 
 863  
     private void setConverterProperties(final Class converterClass, final Converter converter)
 864  
     {
 865  0
         final org.apache.myfaces.config.impl.digester.elements.Converter converterConfig = _converterClassNameToConfigurationMap
 866  
                 .get(converterClass.getName());
 867  
 
 868  0
         if (converterConfig != null)
 869  
         {
 870  
 
 871  0
             final Iterator it = converterConfig.getProperties();
 872  
 
 873  0
             while (it.hasNext())
 874  
             {
 875  0
                 final Property property = (Property) it.next();
 876  
 
 877  
                 try
 878  
                 {
 879  0
                     BeanUtils.setProperty(converter, property.getPropertyName(), property.getDefaultValue());
 880  
                 }
 881  0
                 catch (Throwable th)
 882  
                 {
 883  0
                     log.error("Initializing converter : " + converterClass.getName() + " with property : "
 884  
                             + property.getPropertyName() + " and value : " + property.getDefaultValue() + " failed.");
 885  0
                 }
 886  0
             }
 887  
         }
 888  0
     }
 889  
 
 890  
     // Note: this method used to be synchronized in the JSF 1.1 version. Why?
 891  
     /**
 892  
      * @deprecated
 893  
      */
 894  
     @Deprecated
 895  
     @Override
 896  
     public final MethodBinding createMethodBinding(final String reference, Class[] params) throws ReferenceSyntaxException
 897  
     {
 898  0
         checkNull(reference, "reference");
 899  0
         checkEmpty(reference, "reference");
 900  
 
 901  
         // TODO: this check should be performed by the expression factory. It is a requirement of the TCK
 902  0
         if (!(reference.startsWith("#{") && reference.endsWith("}")))
 903  
         {
 904  0
             throw new ReferenceSyntaxException("Invalid method reference: '" + reference + "'");
 905  
         }
 906  
 
 907  0
         if (params == null)
 908  0
             params = new Class[0];
 909  
 
 910  
         MethodExpression methodExpression;
 911  
 
 912  
         try
 913  
         {
 914  0
             methodExpression = getExpressionFactory().createMethodExpression(threadELContext(), reference,
 915  
                     Object.class, params);
 916  
         }
 917  0
         catch (ELException e)
 918  
         {
 919  0
             throw new ReferenceSyntaxException(e);
 920  0
         }
 921  
 
 922  0
         return new MethodExpressionToMethodBinding(methodExpression);
 923  
     }
 924  
 
 925  
     @Override
 926  
     public final Validator createValidator(final String validatorId) throws FacesException
 927  
     {
 928  0
         checkNull(validatorId, "validatorId");
 929  0
         checkEmpty(validatorId, "validatorId");
 930  
 
 931  0
         Class validatorClass = _validatorClassMap.get(validatorId);
 932  0
         if (validatorClass == null)
 933  
         {
 934  0
             String message = "Unknown validator id '" + validatorId + "'.";
 935  0
             log.error(message);
 936  0
             throw new FacesException(message);
 937  
         }
 938  
 
 939  
         try
 940  
         {
 941  0
             return (Validator) validatorClass.newInstance();
 942  
         }
 943  0
         catch (Exception e)
 944  
         {
 945  0
             log.error("Could not instantiate validator " + validatorClass, e);
 946  0
             throw new FacesException("Could not instantiate validator: " + validatorClass, e);
 947  
         }
 948  
     }
 949  
 
 950  
     /**
 951  
      * @deprecated
 952  
      */
 953  
     @Override
 954  
     public final ValueBinding createValueBinding(final String reference) throws ReferenceSyntaxException
 955  
     {
 956  0
         checkNull(reference, "reference");
 957  0
         checkEmpty(reference, "reference");
 958  
 
 959  
         ValueExpression valueExpression;
 960  
 
 961  
         try
 962  
         {
 963  0
             valueExpression = getExpressionFactory().createValueExpression(threadELContext(), reference, Object.class);
 964  
         }
 965  0
         catch (ELException e)
 966  
         {
 967  0
             throw new ReferenceSyntaxException(e);
 968  0
         }
 969  
 
 970  0
         return new ValueExpressionToValueBinding(valueExpression);
 971  
     }
 972  
 
 973  
     // gets the elContext from the current FacesContext()
 974  
     private final ELContext threadELContext()
 975  
     {
 976  0
         return getFaceContext().getELContext();
 977  
     }
 978  
 
 979  
     @Override
 980  
     public final String getDefaultRenderKitId()
 981  
     {
 982  0
         return _defaultRenderKitId;
 983  
     }
 984  
 
 985  
     @Override
 986  
     public final void setDefaultRenderKitId(final String defaultRenderKitId)
 987  
     {
 988  0
         _defaultRenderKitId = defaultRenderKitId;
 989  0
     }
 990  
 
 991  
     @Override
 992  
     public final StateManager getStateManager()
 993  
     {
 994  0
         return _stateManager;
 995  
     }
 996  
 
 997  
     @Override
 998  
     public final void setStateManager(final StateManager stateManager)
 999  
     {
 1000  0
         _stateManager = stateManager;
 1001  0
     }
 1002  
 
 1003  
     private void checkNull(final Object param, final String paramName)
 1004  
     {
 1005  0
         if (param == null)
 1006  
         {
 1007  0
             throw new NullPointerException(paramName + " can not be null.");
 1008  
         }
 1009  0
     }
 1010  
 
 1011  
     private void checkEmpty(final String param, final String paramName)
 1012  
     {
 1013  0
         if (param.length() == 0)
 1014  
         {
 1015  0
             throw new NullPointerException("String " + paramName + " can not be empty.");
 1016  
         }
 1017  0
     }
 1018  
 }