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