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.lang.reflect.InvocationTargetException;
22  import java.lang.reflect.Method;
23  import java.util.ArrayList;
24  import java.util.List;
25  
26  import javax.el.ArrayELResolver;
27  import javax.el.BeanELResolver;
28  import javax.el.CompositeELResolver;
29  import javax.el.ELResolver;
30  import javax.el.ExpressionFactory;
31  import javax.el.ListELResolver;
32  import javax.el.MapELResolver;
33  import javax.el.ResourceBundleELResolver;
34  import javax.enterprise.inject.spi.BeanManager;
35  import javax.faces.context.FacesContext;
36  import org.apache.myfaces.cdi.util.CDIUtils;
37  
38  import org.apache.myfaces.config.RuntimeConfig;
39  import org.apache.myfaces.el.FlashELResolver;
40  import org.apache.myfaces.el.unified.resolver.CompositeComponentELResolver;
41  import org.apache.myfaces.el.unified.resolver.FacesCompositeELResolver.Scope;
42  import org.apache.myfaces.el.unified.resolver.ImportConstantsELResolver;
43  import org.apache.myfaces.el.unified.resolver.ImportHandlerResolver;
44  import org.apache.myfaces.el.unified.resolver.ManagedBeanResolver;
45  import org.apache.myfaces.el.unified.resolver.ResourceBundleResolver;
46  import org.apache.myfaces.el.unified.resolver.ResourceResolver;
47  import org.apache.myfaces.el.unified.resolver.ScopedAttributeResolver;
48  import org.apache.myfaces.el.unified.resolver.implicitobject.ImplicitObjectResolver;
49  import org.apache.myfaces.shared.config.MyfacesConfig;
50  import org.apache.myfaces.shared.util.ClassUtils;
51  
52  /**
53   * Create the el resolver for faces. see 1.2 spec section 5.6.2
54   * 
55   * @author Mathias Broekelmann (latest modification by $Author$)
56   * @version $Revision$ $Date$
57   */
58  public class ResolverBuilderForFaces extends ResolverBuilderBase implements ELResolverBuilder
59  {
60      private static final Class STATIC_FIELD_EL_RESOLVER_CLASS;
61      private static final Method GET_STREAM_EL_RESOLVER_METHOD;
62      
63      static
64      {
65          Class staticFieldELResolverClass = null;
66          Method getStreamELResolverMethod = null;
67          try
68          {
69              staticFieldELResolverClass = ClassUtils.classForName("javax.el.StaticFieldELResolver");
70              getStreamELResolverMethod = ExpressionFactory.class.getMethod("getStreamELResolver");
71          }
72          catch (NoSuchMethodException ex)
73          {
74              //No op
75          }
76          catch (SecurityException ex)
77          {
78              //No op
79          }
80          catch (ClassNotFoundException ex)
81          {
82              //No op
83          }
84          STATIC_FIELD_EL_RESOLVER_CLASS = staticFieldELResolverClass;
85          GET_STREAM_EL_RESOLVER_METHOD = getStreamELResolverMethod;
86      }
87      
88      public ResolverBuilderForFaces(RuntimeConfig config)
89      {
90          super(config);
91      }
92  
93      public void build(CompositeELResolver compositeElResolver)
94      {
95          build(FacesContext.getCurrentInstance(), compositeElResolver);
96      }
97      
98      @Override
99      public void build(FacesContext facesContext, CompositeELResolver compositeElResolver)
100     {
101         MyfacesConfig config = MyfacesConfig.getCurrentInstance(
102                      FacesContext.getCurrentInstance().getExternalContext());
103         
104         // add the ELResolvers to a List first to be able to sort them
105         List<ELResolver> list = new ArrayList<>();
106 
107         // Add CDI ELResolver for JSF 2.3
108         if (isReplaceImplicitObjectResolverWithCDIResolver(facesContext))
109         {
110             list.add(ImplicitObjectResolver.makeResolverForFacesCDI());
111 
112             BeanManager beanManager = CDIUtils.getBeanManager(
113                     FacesContext.getCurrentInstance().getExternalContext());
114             list.add(beanManager.getELResolver());
115         }
116         else
117         {
118             list.add(ImplicitObjectResolver.makeResolverForFaces());
119         }
120             
121         list.add(new CompositeComponentELResolver());
122 
123         addFromRuntimeConfig(list);
124 
125         //Flash object is instanceof Map, so it is necessary to resolve
126         //before MapELResolver. Better to put this one before
127         list.add(new FlashELResolver());
128         if (config.isSupportManagedBeans())
129         {
130             list.add(new ManagedBeanResolver());
131         }
132         list.add(new ResourceResolver());
133         list.add(new ResourceBundleELResolver());
134         list.add(new ResourceBundleResolver());
135         list.add(new ImportConstantsELResolver());
136         
137         if (STATIC_FIELD_EL_RESOLVER_CLASS != null &&
138             GET_STREAM_EL_RESOLVER_METHOD != null)
139         {
140             try
141             {
142                 ELResolver streamElResolver = (ELResolver) GET_STREAM_EL_RESOLVER_METHOD.invoke(
143                         getRuntimeConfig().getExpressionFactory());
144                 if (streamElResolver != null)
145                 {
146                     // By default return null, but in a EL 3 implementation it should be there,
147                     // this is just to avoid exceptions in junit testing
148                     list.add(streamElResolver);
149                 }
150                 list.add((ELResolver) STATIC_FIELD_EL_RESOLVER_CLASS.newInstance());
151             } 
152             catch (IllegalAccessException ex)
153             {
154             }
155             catch (IllegalArgumentException ex)
156             {
157             }
158             catch (InvocationTargetException ex)
159             {
160             }
161             catch (InstantiationException ex)
162             {
163             }
164         }
165         
166         list.add(new MapELResolver());
167         list.add(new ListELResolver());
168         list.add(new ArrayELResolver());
169         list.add(new BeanELResolver());
170         
171         // give the user a chance to sort the resolvers
172         sortELResolvers(list, Scope.Faces);
173         
174         // give the user a chance to filter the resolvers
175         Iterable<ELResolver> filteredELResolvers = filterELResolvers(list, Scope.Faces);
176         
177         // add the resolvers from the list to the CompositeELResolver
178         for (ELResolver resolver : filteredELResolvers)
179         {
180             compositeElResolver.add(resolver);
181         }
182         
183         // Only add this resolver if the user wants to use the EL ImportHandler
184         if (config.isSupportEL3ImportHandler())
185         {
186             compositeElResolver.add(new ImportHandlerResolver());
187         }
188         
189         // the ScopedAttributeResolver has to be the last one in every
190         // case, because it always sets propertyResolved to true (per the spec)
191         compositeElResolver.add(new ScopedAttributeResolver());
192     }
193     
194 }