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