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.el.unified;
20  
21  import java.util.Collections;
22  import java.util.List;
23  import java.util.logging.Level;
24  import java.util.logging.Logger;
25  
26  import javax.el.ELResolver;
27  import javax.faces.context.FacesContext;
28  import javax.faces.el.PropertyResolver;
29  import javax.faces.el.VariableResolver;
30  
31  import org.apache.commons.collections.CollectionUtils;
32  import org.apache.commons.collections.Predicate;
33  import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFWebConfigParam;
34  import org.apache.myfaces.config.RuntimeConfig;
35  import org.apache.myfaces.el.convert.PropertyResolverToELResolver;
36  import org.apache.myfaces.el.convert.VariableResolverToELResolver;
37  import org.apache.myfaces.el.unified.resolver.FacesCompositeELResolver.Scope;
38  import org.apache.myfaces.shared.config.MyfacesConfig;
39  
40  /**
41   * @author Mathias Broekelmann (latest modification by $Author: lu4242 $)
42   * @version $Revision: 1526587 $ $Date: 2013-09-26 10:57:08 -0500 (Thu, 26 Sep 2013) $
43   */
44  @SuppressWarnings("deprecation")
45  public class ResolverBuilderBase
46  {
47      
48      private static final Logger log = Logger.getLogger(ResolverBuilderBase.class.getName());
49      
50      /**
51       * Define a custom comparator class used to sort the ELResolvers.
52       * 
53       * <p>This is useful when it is necessary to put an ELResolver on top of other resolvers. Note set
54       * this param override the default ordering described by JSF spec section 5. 
55       * </p>
56       */
57      @JSFWebConfigParam(since = "1.2.10, 2.0.2", group="EL",
58              desc = "The Class of an Comparator&lt;ELResolver&gt; implementation.")
59      public static final String EL_RESOLVER_COMPARATOR = "org.apache.myfaces.EL_RESOLVER_COMPARATOR";
60      
61      @JSFWebConfigParam(since = "2.1.0", group="EL",
62          desc="The Class of an org.apache.commons.collections.Predicate&lt;ELResolver&gt; implementation."
63               + "If used and returns true for a ELResolver instance, such resolver will not be installed in "
64               + "ELResolvers chain. Use with caution - can break functionality defined in JSF specification "
65               + "'ELResolver Instances Provided by Faces'")
66      public static final String EL_RESOLVER_PREDICATE = "org.apache.myfaces.EL_RESOLVER_PREDICATE";
67      
68      private final RuntimeConfig _config;
69  
70      public ResolverBuilderBase(RuntimeConfig config)
71      {
72          _config = config;
73      }
74  
75      /**
76       * add the el resolvers from the faces config, the el resolver wrapper for variable resolver, the el resolver
77       * wrapper for the property resolver and the el resolvers added by
78       * {@link javax.faces.application.Application#addELResolver(ELResolver)}.
79       * The resolvers where only added if they are not null
80       * 
81       * @param resolvers
82       */
83      protected void addFromRuntimeConfig(List<ELResolver> resolvers)
84      {
85          if (_config.getFacesConfigElResolvers() != null)
86          {
87              for (ELResolver resolver : _config.getFacesConfigElResolvers())
88              {
89                  resolvers.add(resolver);
90              }
91          }
92  
93          FacesContext facesContext = FacesContext.getCurrentInstance();
94          if (facesContext == null)
95          {
96              // Should not happen, but if by some reason happens,
97              // initialize as usual.
98              if (_config.getVariableResolver() != null)
99              {
100                 resolvers.add(createELResolver(_config.getVariableResolver()));
101             }
102             else if (_config.getVariableResolverChainHead() != null)
103             {
104                 resolvers.add(createELResolver(_config.getVariableResolverChainHead()));
105             }
106 
107             if (_config.getPropertyResolver() != null)
108             {
109                 resolvers.add(createELResolver(_config.getPropertyResolver()));
110             }
111             else if (_config.getPropertyResolverChainHead() != null)
112             {
113                 resolvers.add(createELResolver(_config.getPropertyResolverChainHead()));
114             }
115         }
116         else if (facesContext != null && MyfacesConfig.getCurrentInstance(
117                 facesContext.getExternalContext()).isSupportJSPAndFacesEL())
118         {
119             if (_config.getVariableResolver() != null)
120             {
121                 resolvers.add(createELResolver(_config.getVariableResolver()));
122             }
123             else if (_config.getVariableResolverChainHead() != null)
124             {
125                 resolvers.add(createELResolver(_config.getVariableResolverChainHead()));
126             }
127 
128             if (_config.getPropertyResolver() != null)
129             {
130                 resolvers.add(createELResolver(_config.getPropertyResolver()));
131             }
132             else if (_config.getPropertyResolverChainHead() != null)
133             {
134                 resolvers.add(createELResolver(_config.getPropertyResolverChainHead()));
135             }
136         }
137 
138         if (_config.getApplicationElResolvers() != null)
139         {
140             for (ELResolver resolver : _config.getApplicationElResolvers())
141             {
142                 resolvers.add(resolver);
143             }
144         }
145     }
146     
147     /**
148      * Sort the ELResolvers with a custom Comparator provided by the user.
149      * @param resolvers
150      * @param scope scope of ELResolvers (Faces,JSP)  
151      * @since 1.2.10, 2.0.2
152      */
153     @SuppressWarnings("unchecked")
154     protected void sortELResolvers(List<ELResolver> resolvers, Scope scope)
155     {
156         if (_config.getELResolverComparator() != null)
157         {
158             try
159             {
160                 // sort the resolvers
161                 Collections.sort(resolvers, _config.getELResolverComparator());
162                 
163                 if (log.isLoggable(Level.INFO))
164                 {
165                     log.log(Level.INFO, "Chain of EL resolvers for {0} sorted with: {1} and the result order is {2}", 
166                             new Object [] {scope, _config.getELResolverComparator(), resolvers});
167                 }
168             }
169             catch (Exception e)
170             {
171                 log.log(Level.WARNING, 
172                         "Could not sort ELResolvers with custom Comparator", e);
173             }
174         }
175     }
176     
177     /**
178      * Filters the ELResolvers  with a custom Predicate provided by the user.
179      * @param resolvers list of ELResolvers
180      * @param scope scope of ELResolvers (Faces,JSP)
181      * @return Iterable instance of Iterable containing filtered ELResolvers 
182      */
183     protected Iterable<ELResolver> filterELResolvers(List<ELResolver> resolvers, Scope scope)
184     {
185         
186         Predicate predicate = _config.getELResolverPredicate();
187         if (predicate != null)
188         {
189             try
190             {
191                 // filter the resolvers
192                 CollectionUtils.filter(resolvers, predicate);
193                 
194                 if (log.isLoggable(Level.INFO))
195                 {
196                     log.log(Level.INFO, "Chain of EL resolvers for {0} filtered with: {1} and the result is {2}", 
197                             new Object [] {scope, predicate, resolvers});
198                 }
199             }
200             catch (Exception e)
201             {
202                 log.log(Level.WARNING, 
203                         "Could not filter ELResolvers with custom Predicate", e);
204             }
205         }
206         return resolvers;
207     }
208     
209     protected ELResolver createELResolver(VariableResolver resolver)
210     {
211         return new VariableResolverToELResolver(resolver);
212     }
213 
214     protected ELResolver createELResolver(PropertyResolver resolver)
215     {
216         return new PropertyResolverToELResolver(resolver);
217     }
218 
219     protected RuntimeConfig getRuntimeConfig()
220     {
221         return _config;
222     }
223 }