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.resolver;
20  
21  import java.util.ArrayList;
22  import java.util.HashMap;
23  import java.util.List;
24  import java.util.Map;
25  
26  import javax.el.ELException;
27  import javax.faces.FacesException;
28  import javax.faces.application.ProjectStage;
29  
30  import org.apache.myfaces.config.RuntimeConfig;
31  import org.apache.myfaces.config.impl.digester.elements.ManagedBean;
32  import org.apache.myfaces.test.mock.MockApplication20;
33  import org.apache.myfaces.test.base.AbstractJsfTestCase;
34  import org.apache.myfaces.test.el.MockValueExpression;
35  
36  /**
37   * Class used to test ManagedBeanResolver
38   * @author Jakob Korherr (latest modification by $Author: bommel $)
39   */
40  public class ManagedBeanResolverTest extends AbstractJsfTestCase
41  {
42      
43      /**
44       * A managed bean used in the test cases
45       * @author Jakob Korherr
46       */
47      public static class TestBean {
48          
49          private Map<Object, Object> scope;
50  
51          public Map<Object, Object> getScope()
52          {
53              if (scope == null)
54              {
55                  scope = new HashMap<Object, Object>();
56              }
57              return scope;
58          }
59  
60          public void setScope(Map<Object, Object> scope)
61          {
62              this.scope = scope;
63          }
64          
65      }
66      
67      private RuntimeConfig runtimeConfig;
68      
69      public ManagedBeanResolverTest(String name)
70      {
71          super(name);
72      }
73      
74      @Override
75      protected void setUp() throws Exception
76      {
77          super.setUp();
78          
79          // override MockApplication20 to get a ProjectStage
80          application = new MockApplication20() {
81  
82              @Override
83              public ProjectStage getProjectStage()
84              {
85                  return ProjectStage.Development;
86              }
87              
88          };
89          // add the ManagedBeanResolver as a ELResolver
90          ManagedBeanResolver resolver = new ManagedBeanResolver();
91          application.addELResolver(resolver);
92          facesContext.setApplication(application);
93          
94          runtimeConfig = RuntimeConfig.getCurrentInstance(externalContext);
95      }
96      
97      @Override
98      protected void tearDown() throws Exception
99      {
100         runtimeConfig = null;
101         
102         super.tearDown();
103     }
104 
105     /**
106      * Tests if the ManagedBeanResolver handles custom scopes correctly
107      */
108     @SuppressWarnings("unchecked")
109     public void testCustomScope()
110     {
111         // create the custom scope
112         ManagedBean scopeBean = new ManagedBean();
113         scopeBean.setBeanClass(HashMap.class.getName());
114         scopeBean.setName("scopeBean");
115         scopeBean.setScope("application");
116         runtimeConfig.addManagedBean("scopeBean", scopeBean);
117         
118         // create the managed bean
119         ManagedBean beanInCustomScope = new ManagedBean();
120         beanInCustomScope.setBeanClass(ArrayList.class.getName());
121         beanInCustomScope.setName("beanInCustomScope");
122         beanInCustomScope.setScope("#{scopeBean}");
123         runtimeConfig.addManagedBean("beanInCustomScope", beanInCustomScope);
124         
125         // resolve the managed bean
126         Object resolvedBeanInCustomScope = new MockValueExpression("#{beanInCustomScope}", List.class)
127                                                    .getValue(facesContext.getELContext());
128         
129         // get the custom scope
130         Map resolvedScopeBean = (Map) new MockValueExpression("#{scopeBean}", Map.class)
131                                               .getValue(facesContext.getELContext());
132         
133         // the custom scope has to contain the resolved bean
134         assertTrue(resolvedScopeBean.containsKey("beanInCustomScope"));
135         assertTrue(resolvedScopeBean.get("beanInCustomScope").equals(resolvedBeanInCustomScope));
136     }
137     
138     /**
139      * Tests if the ManagedBeanResolver throws the right Exception, if a custom scope
140      * does not evaluate to java.util.Map.
141      * Spec says: If the ValueExpression does not evaluate to a Map, a FacesException 
142      * must be thrown with a message that includes the expression string, the toString() 
143      * of the value, and the type of the value.
144      */
145     public void testCustomScopeNoMap()
146     {
147         // create the custom scope
148         ManagedBean scopeBean = new ManagedBean();
149         // Scope is ArrayList instead of HashMap
150         scopeBean.setBeanClass(ArrayList.class.getName()); 
151         scopeBean.setName("scopeBean");
152         scopeBean.setScope("application");
153         runtimeConfig.addManagedBean("scopeBean", scopeBean);
154         
155         // create the managed bean
156         ManagedBean beanInCustomScope = new ManagedBean();
157         beanInCustomScope.setBeanClass(ArrayList.class.getName());
158         beanInCustomScope.setName("beanInCustomScope");
159         beanInCustomScope.setScope("#{scopeBean}");
160         runtimeConfig.addManagedBean("beanInCustomScope", beanInCustomScope);
161         
162         // resolve the managed bean
163         try
164         {
165             new MockValueExpression("#{beanInCustomScope}", List.class)
166                     .getValue(facesContext.getELContext());
167         }
168         catch (FacesException fe)
169         {
170             // the message must contain ...
171             final String message = fe.getMessage();
172             // ... the expression string 
173             assertTrue(message.contains(beanInCustomScope.getManagedBeanScope()));
174             Object resolvedScopeBean = new MockValueExpression("#{scopeBean}", List.class)
175                                                .getValue(facesContext.getELContext());
176             // ... the toString() of the value
177             assertTrue(message.contains(resolvedScopeBean.toString()));
178             // ... and the type of the value
179             assertTrue(message.contains(resolvedScopeBean.getClass().getName()));
180             return;
181         }
182         // No FacesException was thrown
183         fail();
184     }
185     
186     /**
187      * Tests if the ManagedBeanResolver detects cyclic references in custom scopes.
188      * The ManagedBeanResolver only tries to detect cyclic references if ProjectStage != Production.
189      */
190     public void testCustomScopeCyclicReferences()
191     {
192         // create m1
193         ManagedBean m1 = new ManagedBean();
194         m1.setBeanClass(TestBean.class.getName());
195         m1.setName("m1");
196         m1.setScope("#{m2.scope}");
197         runtimeConfig.addManagedBean("m1", m1);
198         
199         // create m2
200         ManagedBean m2 = new ManagedBean();
201         m2.setBeanClass(TestBean.class.getName());
202         m2.setName("m2");
203         m2.setScope("#{m1.scope}");
204         runtimeConfig.addManagedBean("m2", m2);
205         
206         // try to resolve m1
207         try
208         {
209             new MockValueExpression("#{m1}", TestBean.class).getValue(facesContext.getELContext());
210         }
211         catch (ELException e)
212         {
213             // success
214             return;
215         }
216         fail();
217     }
218     
219     /**
220      * Tests the view scope, which was introduced in jsf 2.0
221      */
222     public void testViewScope()
223     {
224         // create the managed bean
225         ManagedBean beanInViewScope = new ManagedBean();
226         beanInViewScope.setBeanClass(ArrayList.class.getName());
227         beanInViewScope.setName("beanInViewScope");
228         beanInViewScope.setScope("view");
229         runtimeConfig.addManagedBean("beanInViewScope", beanInViewScope);
230         
231         // resolve the managed bean
232         Object resolvedBeanInCustomScope = new MockValueExpression("#{beanInViewScope}", List.class)
233                                                    .getValue(facesContext.getELContext());
234         
235         // get the view map
236         Map<String, Object> viewMap = facesContext.getViewRoot().getViewMap();
237         
238         // the custom scope has to contain the resolved bean
239         assertTrue(viewMap.containsKey("beanInViewScope"));
240         assertTrue(viewMap.get("beanInViewScope").equals(resolvedBeanInCustomScope));
241     }
242 
243 }