View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.config;
20  
21  import java.util.ArrayList;
22  import java.util.Collection;
23  import java.util.Collections;
24  import java.util.Comparator;
25  import java.util.HashMap;
26  import java.util.HashSet;
27  import java.util.List;
28  import java.util.Map;
29  import java.util.Set;
30  import java.util.concurrent.ConcurrentHashMap;
31  import java.util.logging.Level;
32  import java.util.logging.Logger;
33  
34  import javax.el.ELResolver;
35  import javax.el.ExpressionFactory;
36  import javax.faces.context.ExternalContext;
37  import javax.faces.el.PropertyResolver;
38  import javax.faces.el.VariableResolver;
39  
40  import org.apache.commons.collections.Predicate;
41  import org.apache.myfaces.config.element.ComponentTagDeclaration;
42  import org.apache.myfaces.config.element.FaceletsProcessing;
43  import org.apache.myfaces.config.element.ManagedBean;
44  import org.apache.myfaces.config.element.NavigationRule;
45  import org.apache.myfaces.config.element.ResourceBundle;
46  import org.apache.myfaces.config.element.ViewPoolMapping;
47  import org.apache.myfaces.config.element.facelets.FaceletTagLibrary;
48  
49  /**
50   * Holds all configuration information (from the faces-config xml files) that is needed later during runtime. The config
51   * information in this class is only available to the MyFaces core implementation classes (i.e. the myfaces source
52   * tree). See MyfacesConfig for config parameters that can be used for shared or component classes.
53   * 
54   * @author Manfred Geiler (latest modification by $Author$)
55   * @version $Revision$ $Date$
56   */
57  @SuppressWarnings("deprecation")
58  public class RuntimeConfig
59  {
60      //private static final Log log = LogFactory.getLog(RuntimeConfig.class);
61      private static final Logger log = Logger.getLogger(RuntimeConfig.class.getName());
62  
63      private static final String APPLICATION_MAP_PARAM_NAME = RuntimeConfig.class.getName();
64  
65      private final Collection<NavigationRule> _navigationRules = new ArrayList<NavigationRule>();
66      private final Map<String, ManagedBean> _managedBeans = new HashMap<String, ManagedBean>();
67      private boolean _navigationRulesChanged = false;
68      private final Map<String, ResourceBundle> _resourceBundles = new HashMap<String, ResourceBundle>();
69      private final Map<String, ManagedBean> _oldManagedBeans = new HashMap<String, ManagedBean>();
70      
71      private String _facesVersion;
72      
73      private List<ELResolver> facesConfigElResolvers;
74      private List<ELResolver> applicationElResolvers;
75  
76      private VariableResolver _variableResolver;
77      private PropertyResolver _propertyResolver;
78  
79      private ExpressionFactory _expressionFactory;
80  
81      private PropertyResolver _propertyResolverChainHead;
82  
83      private VariableResolver _variableResolverChainHead;
84      
85      private Comparator<ELResolver> _elResolverComparator;
86      
87      private Predicate _elResolverPredicate;
88  
89      private final Map<String, org.apache.myfaces.config.element.Converter> _converterClassNameToConfigurationMap =
90          new ConcurrentHashMap<String, org.apache.myfaces.config.element.Converter>();
91      
92      private NamedEventManager _namedEventManager;
93      
94      private final Map<String, FaceletsProcessing> _faceletsProcessingByFileExtension =
95          new HashMap<String, FaceletsProcessing>();
96      
97      /**
98       * JSF 2.2 section 11.4.2.1. 
99       * 
100      * Scanning for all available contracts is necessary because the spec says 
101      * "... if the information from the application configuration resources refers 
102      * to a contract that is not available to the application, an informative error 
103      * message must be logged. ..."
104      */
105     private Set<String> _externalContextResourceLibraryContracts = new HashSet<String>();
106     private Set<String> _classLoaderResourceLibraryContracts = new HashSet<String>();
107     private Set<String> _resourceLibraryContracts = new HashSet<String>();
108     
109     private Map<String, List<String>> _contractMappings = new HashMap<String, List<String>>();
110     
111     private List<ComponentTagDeclaration> _componentTagDeclarations = 
112             new ArrayList<ComponentTagDeclaration>();
113     
114     private List<String> _resourceResolvers = new ArrayList<String>();
115     
116     private List<Object> _injectedObjects = new ArrayList<Object>();
117     
118     private List<FaceletTagLibrary> _faceletTagLibraries = new ArrayList<FaceletTagLibrary>();
119     
120     private Map<Integer, String> _namespaceById = new HashMap<Integer, String>();
121     private Map<String, Integer> _idByNamespace = new HashMap<String, Integer>();
122     
123     private List<ViewPoolMapping> _viewPoolMappings = new ArrayList<ViewPoolMapping>();
124 
125     public static RuntimeConfig getCurrentInstance(ExternalContext externalContext)
126     {
127         RuntimeConfig runtimeConfig = (RuntimeConfig) externalContext.getApplicationMap().get(
128                 APPLICATION_MAP_PARAM_NAME);
129         if (runtimeConfig == null)
130         {
131             runtimeConfig = new RuntimeConfig();
132             externalContext.getApplicationMap().put(APPLICATION_MAP_PARAM_NAME, runtimeConfig);
133         }
134         return runtimeConfig;
135     }
136 
137     public void purge()
138     {
139         _navigationRules.clear();
140         _oldManagedBeans.clear();
141         _oldManagedBeans.putAll(_managedBeans);
142         _managedBeans.clear();
143         _navigationRulesChanged = false;
144         _converterClassNameToConfigurationMap.clear();
145         _externalContextResourceLibraryContracts.clear();
146         _classLoaderResourceLibraryContracts.clear();
147         _resourceLibraryContracts.clear();
148         _injectedObjects.clear();
149         _faceletTagLibraries.clear();
150         
151         _resourceBundles.clear();
152         if (facesConfigElResolvers != null)
153         {
154             facesConfigElResolvers.clear();
155         }
156         if (applicationElResolvers != null)
157         {
158             applicationElResolvers.clear();
159         }
160         _faceletsProcessingByFileExtension.clear();
161         _contractMappings.clear();
162         _componentTagDeclarations.clear();
163         _resourceResolvers.clear();
164         _namespaceById = new HashMap<Integer, String>();
165         _idByNamespace = new HashMap<String, Integer>();
166         _viewPoolMappings.clear();
167     }
168 
169     /**
170      * Return the navigation rules that can be used by the NavigationHandler implementation.
171      * 
172      * @return a Collection of {@link org.apache.myfaces.config.element.NavigationRule NavigationRule}s
173      */
174     public Collection<NavigationRule> getNavigationRules()
175     {
176         return Collections.unmodifiableCollection(_navigationRules);
177     }
178 
179     public void addNavigationRule(NavigationRule navigationRule)
180     {
181         _navigationRules.add(navigationRule);
182 
183         _navigationRulesChanged = true;
184     }
185 
186     public boolean isNavigationRulesChanged()
187     {
188         return _navigationRulesChanged;
189     }
190 
191     public void setNavigationRulesChanged(boolean navigationRulesChanged)
192     {
193         _navigationRulesChanged = navigationRulesChanged;
194     }
195 
196     /**
197      * Return the managed bean info that can be used by the VariableResolver implementation.
198      * 
199      * @return a {@link org.apache.myfaces.config.element.ManagedBean ManagedBean}
200      */
201     public ManagedBean getManagedBean(String name)
202     {
203         return _managedBeans.get(name);
204     }
205 
206     public Map<String, ManagedBean> getManagedBeans()
207     {
208         return Collections.unmodifiableMap(_managedBeans);
209     }
210 
211     public void addManagedBean(String name, ManagedBean managedBean)
212     {
213         _managedBeans.put(name, managedBean);
214         if(_oldManagedBeans!=null)
215         {
216             _oldManagedBeans.remove(name);
217         }
218     }
219     
220     public void addComponentTagDeclaration(ComponentTagDeclaration declaration)
221     {
222         _componentTagDeclarations.add(declaration);
223     }
224     
225     public List<ComponentTagDeclaration> getComponentTagDeclarations()
226     {
227         return Collections.unmodifiableList(_componentTagDeclarations);
228     }
229     
230     public void addFaceletTagLibrary(FaceletTagLibrary library)
231     {
232         _faceletTagLibraries.add(library);
233     }
234     
235     public List<FaceletTagLibrary> getFaceletTagLibraries()
236     {
237         return Collections.unmodifiableList(_faceletTagLibraries);
238     }
239     
240     public final void addConverterConfiguration(final String converterClassName,
241             final org.apache.myfaces.config.element.Converter configuration)
242     {
243         checkNull(converterClassName, "converterClassName");
244         checkEmpty(converterClassName, "converterClassName");
245         checkNull(configuration, "configuration");
246 
247         _converterClassNameToConfigurationMap.put(converterClassName, configuration);
248     }
249     
250     public org.apache.myfaces.config.element.Converter getConverterConfiguration(String converterClassName)
251     {
252         return (org.apache.myfaces.config.element.Converter)
253                 _converterClassNameToConfigurationMap.get(converterClassName);
254     }
255     
256     private void checkNull(final Object param, final String paramName)
257     {
258         if (param == null)
259         {
260             throw new NullPointerException(paramName + " can not be null.");
261         }
262     }
263 
264     private void checkEmpty(final String param, final String paramName)
265     {
266         if (param.length() == 0)
267         {
268             throw new NullPointerException("String " + paramName + " can not be empty.");
269         }
270     }
271 
272     /**
273      * Return the resourcebundle which was configured in faces config by var name
274      * 
275      * @param name
276      *            the name of the resource bundle (content of var)
277      * @return the resource bundle or null if not found
278      */
279     public ResourceBundle getResourceBundle(String name)
280     {
281         return _resourceBundles.get(name);
282     }
283 
284     /**
285      * @return the resourceBundles
286      */
287     public Map<String, ResourceBundle> getResourceBundles()
288     {
289         return _resourceBundles;
290     }
291 
292     public void addResourceBundle(ResourceBundle bundle)
293     {
294         if (bundle == null)
295         {
296             throw new IllegalArgumentException("bundle must not be null");
297         }
298         String var = bundle.getVar();
299         if (_resourceBundles.containsKey(var) && log.isLoggable(Level.WARNING))
300         {
301             log.warning("Another resource bundle for var '" + var + "' with base name '"
302                     + _resourceBundles.get(var).getBaseName() + "' is already registered. '"
303                     + _resourceBundles.get(var).getBaseName() + "' will be replaced with '" + bundle.getBaseName()
304                     + "'.");
305         }
306         _resourceBundles.put(var, bundle);
307     }
308 
309     public void addFacesConfigElResolver(ELResolver resolver)
310     {
311         if (facesConfigElResolvers == null)
312         {
313             facesConfigElResolvers = new ArrayList<ELResolver>();
314         }
315         facesConfigElResolvers.add(resolver);
316     }
317 
318     public List<ELResolver> getFacesConfigElResolvers()
319     {
320         return facesConfigElResolvers;
321     }
322 
323     public void addApplicationElResolver(ELResolver resolver)
324     {
325         if (applicationElResolvers == null)
326         {
327             applicationElResolvers = new ArrayList<ELResolver>();
328         }
329         applicationElResolvers.add(resolver);
330     }
331 
332     public List<ELResolver> getApplicationElResolvers()
333     {
334         return applicationElResolvers;
335     }
336 
337     public void setVariableResolver(VariableResolver variableResolver)
338     {
339         _variableResolver = variableResolver;
340     }
341 
342     public VariableResolver getVariableResolver()
343     {
344         return _variableResolver;
345     }
346 
347     public void setPropertyResolver(PropertyResolver propertyResolver)
348     {
349         _propertyResolver = propertyResolver;
350     }
351 
352     public PropertyResolver getPropertyResolver()
353     {
354         return _propertyResolver;
355     }
356 
357     public ExpressionFactory getExpressionFactory()
358     {
359         return _expressionFactory;
360     }
361 
362     public void setExpressionFactory(ExpressionFactory expressionFactory)
363     {
364         _expressionFactory = expressionFactory;
365     }
366 
367     public void setPropertyResolverChainHead(PropertyResolver resolver)
368     {
369         _propertyResolverChainHead = resolver;
370     }
371 
372     public PropertyResolver getPropertyResolverChainHead()
373     {
374         return _propertyResolverChainHead;
375     }
376 
377     public void setVariableResolverChainHead(VariableResolver resolver)
378     {
379         _variableResolverChainHead = resolver;
380     }
381 
382     public VariableResolver getVariableResolverChainHead()
383     {
384         return _variableResolverChainHead;
385     }
386 
387     public Map<String, ManagedBean> getManagedBeansNotReaddedAfterPurge()
388     {
389         return _oldManagedBeans;
390     }
391 
392     public void resetManagedBeansNotReaddedAfterPurge()
393     {
394         _oldManagedBeans.clear();
395     }
396     
397     public String getFacesVersion ()
398     {
399         return _facesVersion;
400     }
401     
402     void setFacesVersion (String facesVersion)
403     {
404         _facesVersion = facesVersion;
405     }
406 
407     public NamedEventManager getNamedEventManager()
408     {
409         return _namedEventManager;
410     }
411 
412     public void setNamedEventManager(NamedEventManager namedEventManager)
413     {
414         this._namedEventManager = namedEventManager;
415     }
416 
417     public Comparator<ELResolver> getELResolverComparator()
418     {
419         return _elResolverComparator;
420     }
421     
422     public void setELResolverComparator(Comparator<ELResolver> elResolverComparator)
423     {
424         _elResolverComparator = elResolverComparator;
425     }
426     
427     public Predicate getELResolverPredicate()
428     {
429         return _elResolverPredicate;
430     }
431     
432     public void setELResolverPredicate(Predicate elResolverPredicate)
433     {
434         _elResolverPredicate = elResolverPredicate;
435     }
436     
437     public void addFaceletProcessingConfiguration(String fileExtension, FaceletsProcessing configuration)
438     {
439         checkNull(fileExtension, "fileExtension");
440         checkEmpty(fileExtension, "fileExtension");
441         checkNull(configuration, "configuration");
442 
443         this._faceletsProcessingByFileExtension.put(fileExtension, configuration);
444     }
445     
446     public FaceletsProcessing getFaceletProcessingConfiguration(String fileExtensions)
447     {
448         return _faceletsProcessingByFileExtension.get(fileExtensions);
449     }
450     
451     public Collection<FaceletsProcessing> getFaceletProcessingConfigurations()
452     {
453         return _faceletsProcessingByFileExtension.values();
454     }
455 
456     /**
457      * @return the _externalContextResourceLibraryContracts
458      */
459     public Set<String> getExternalContextResourceLibraryContracts()
460     {
461         return _externalContextResourceLibraryContracts;
462     }
463 
464     /**
465      * @param externalContextResourceLibraryContracts the _externalContextResourceLibraryContracts to set
466      */
467     public void setExternalContextResourceLibraryContracts(Set<String> externalContextResourceLibraryContracts)
468     {
469         this._externalContextResourceLibraryContracts = externalContextResourceLibraryContracts;
470         this._resourceLibraryContracts.clear();
471         this._resourceLibraryContracts.addAll(this._externalContextResourceLibraryContracts);
472         this._resourceLibraryContracts.addAll(this._classLoaderResourceLibraryContracts);
473     }
474 
475     /**
476      * @return the _classLoaderResourceLibraryContracts
477      */
478     public Set<String> getClassLoaderResourceLibraryContracts()
479     {
480         return _classLoaderResourceLibraryContracts;
481     }
482 
483     /**
484      * @param classLoaderResourceLibraryContracts the _classLoaderResourceLibraryContracts to set
485      */
486     public void setClassLoaderResourceLibraryContracts(Set<String> classLoaderResourceLibraryContracts)
487     {
488         this._classLoaderResourceLibraryContracts = classLoaderResourceLibraryContracts;
489         this._resourceLibraryContracts.clear();
490         this._resourceLibraryContracts.addAll(this._externalContextResourceLibraryContracts);
491         this._resourceLibraryContracts.addAll(this._classLoaderResourceLibraryContracts);
492     }
493 
494     /**
495      * @return the _resourceLibraryContracts
496      */
497     public Set<String> getResourceLibraryContracts()
498     {
499         return _resourceLibraryContracts;
500     }
501 
502     /**
503      * @return the _contractMappings
504      */
505     public Map<String, List<String>> getContractMappings()
506     {
507         return _contractMappings;
508     }
509 
510     public void addContractMapping(String urlPattern, String[] contracts)
511     {
512         List<String> contractsList = _contractMappings.get(urlPattern);
513         if (contractsList == null)
514         {
515             contractsList = new ArrayList<String>();
516             _contractMappings.put(urlPattern, contractsList);
517         }
518         for (String contract : contracts)
519         {
520             contractsList.add(contract);
521         }
522     }
523     
524     public void addContractMapping(String urlPattern, String contract)
525     {
526         List<String> contractsList = _contractMappings.get(urlPattern);
527         if (contractsList == null)
528         {
529             contractsList = new ArrayList<String>();
530             _contractMappings.put(urlPattern, contractsList);
531         }
532         contractsList.add(contract);
533     }    
534     
535     public List<String> getResourceResolvers()
536     {
537         return _resourceResolvers;
538     }
539     
540     public void addResourceResolver(String resourceResolver)
541     {
542         _resourceResolvers.add(resourceResolver);
543     }
544 
545     /**
546      * @return the _injectedObjects
547      */
548     public List<Object> getInjectedObjects()
549     {
550         return _injectedObjects;
551     }
552 
553     public void addInjectedObject(Object object)
554     {
555         _injectedObjects.add(object);
556     }
557 
558     public Map<Integer, String> getNamespaceById()
559     {
560         return _namespaceById;
561     }
562 
563     public void setNamespaceById(Map<Integer, String> namespaceById)
564     {
565         this._namespaceById = namespaceById;
566     }
567 
568     public Map<String, Integer> getIdByNamespace()
569     {
570         return _idByNamespace;
571     }
572 
573     public void setIdByNamespace(Map<String, Integer> idByNamespace)
574     {
575         this._idByNamespace = idByNamespace;
576     }
577 
578     public List<ViewPoolMapping> getViewPoolMappings()
579     {
580         return _viewPoolMappings;
581     }
582     
583     public void addViewPoolMapping(ViewPoolMapping mapping)
584     {
585         _viewPoolMappings.add(mapping);
586     }
587 }