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  
20  package org.apache.myfaces.view.facelets;
21  
22  import java.io.File;
23  import java.io.FileNotFoundException;
24  import java.io.InputStream;
25  import java.io.StringWriter;
26  import java.lang.reflect.Field;
27  import java.net.URI;
28  import java.net.URL;
29  import java.util.List;
30  
31  import javax.el.ExpressionFactory;
32  import javax.faces.FacesException;
33  import javax.faces.FactoryFinder;
34  import javax.faces.application.ProjectStage;
35  import javax.faces.application.StateManager;
36  import javax.faces.component.UIViewRoot;
37  import javax.faces.context.FacesContext;
38  import javax.faces.context.ResponseWriter;
39  import javax.faces.render.RenderKitFactory;
40  
41  import org.apache.myfaces.application.ApplicationFactoryImpl;
42  import org.apache.myfaces.application.ViewHandlerImpl;
43  import org.apache.myfaces.config.FacesConfigDispenser;
44  import org.apache.myfaces.config.FacesConfigUnmarshaller;
45  import org.apache.myfaces.config.RuntimeConfig;
46  import org.apache.myfaces.config.element.Behavior;
47  import org.apache.myfaces.config.element.ClientBehaviorRenderer;
48  import org.apache.myfaces.config.element.FacesConfig;
49  import org.apache.myfaces.config.element.Renderer;
50  import org.apache.myfaces.config.element.facelets.FaceletTagLibrary;
51  import org.apache.myfaces.config.impl.digester.DigesterFacesConfigDispenserImpl;
52  import org.apache.myfaces.config.impl.digester.DigesterFacesConfigUnmarshallerImpl;
53  import org.apache.myfaces.context.PartialViewContextFactoryImpl;
54  import org.apache.myfaces.shared.application.ViewHandlerSupport;
55  import org.apache.myfaces.shared.util.ClassUtils;
56  import org.apache.myfaces.spi.FacesConfigurationProviderFactory;
57  import org.apache.myfaces.test.base.junit4.AbstractJsfConfigurableMultipleRequestsTestCase;
58  import org.apache.myfaces.test.el.MockExpressionFactory;
59  import org.apache.myfaces.test.mock.MockExternalContext;
60  import org.apache.myfaces.test.mock.MockFacesContext;
61  import org.apache.myfaces.test.mock.MockFacesContextFactory;
62  import org.apache.myfaces.test.mock.MockPropertyResolver;
63  import org.apache.myfaces.test.mock.MockVariableResolver;
64  import org.apache.myfaces.test.mock.visit.MockVisitContextFactory;
65  import org.apache.myfaces.view.facelets.impl.FaceletCacheFactoryImpl;
66  import org.apache.myfaces.view.facelets.mock.MockViewDeclarationLanguageFactory;
67  import org.apache.myfaces.view.facelets.tag.jsf.TagHandlerDelegateFactoryImpl;
68  
69  public abstract class FaceletMultipleRequestsTestCase extends AbstractJsfConfigurableMultipleRequestsTestCase
70  {
71      private final String filePath = this.getDirectory();
72      protected FacesConfigDispenser dispenser = null;
73      protected MockFaceletViewDeclarationLanguage vdl;
74  
75  
76      @Override
77      protected void setUpServletContextAndSession() throws Exception
78      {
79          super.setUpServletContextAndSession();
80          URI context = this.getContext();
81          servletContext.setDocumentRoot(new File(context));
82          
83          //This params are optional
84          servletContext.addInitParameter(StateManager.STATE_SAVING_METHOD_PARAM_NAME,
85                  StateManager.STATE_SAVING_METHOD_CLIENT);
86          servletContext.addInitParameter("org.apache.myfaces.PRETTY_HTML","true");
87          servletContext.addInitParameter("org.apache.myfaces.ALLOW_JAVASCRIPT","true");
88          servletContext.addInitParameter("org.apache.myfaces.RENDER_CLEAR_JAVASCRIPT_FOR_BUTTON","false");
89          servletContext.addInitParameter("org.apache.myfaces.SAVE_FORM_SUBMIT_LINK_IE","false");
90          servletContext.addInitParameter("org.apache.myfaces.READONLY_AS_DISABLED_FOR_SELECTS","true");
91          servletContext.addInitParameter("org.apache.myfaces.RENDER_VIEWSTATE_ID","true");
92          servletContext.addInitParameter("org.apache.myfaces.STRICT_XHTML_LINKS","true");
93          servletContext.addInitParameter("org.apache.myfaces.CONFIG_REFRESH_PERIOD","0");
94          servletContext.addInitParameter("org.apache.myfaces.VIEWSTATE_JAVASCRIPT","false");
95          servletContext.addInitParameter(ProjectStage.PROJECT_STAGE_PARAM_NAME, "UnitTest");
96      }
97      
98      @Override
99      protected void setUpServletRequestAndResponse() throws Exception
100     {
101         super.setUpServletRequestAndResponse();
102         URI context = this.getContext();
103         request.setPathElements(context.getPath(), null, context.getPath(), context.getQuery());
104     }
105 
106     protected URI getContext()
107     {
108         try
109         {
110             ClassLoader cl = Thread.currentThread().getContextClassLoader();
111             URL url = cl.getResource(this.filePath);
112             if (url == null)
113             {
114                 throw new FileNotFoundException(cl.getResource("").getFile()
115                         + this.filePath + " was not found");
116             }
117             else
118             {
119                 return new URI(url.toString());
120             }
121         }
122         catch (Exception e)
123         {
124             throw new RuntimeException("Error Initializing Context", e);
125         }
126     }
127 
128     protected URL getLocalFile(String name) throws FileNotFoundException
129     {
130         ClassLoader cl = Thread.currentThread().getContextClassLoader();
131         URL url = cl.getResource(this.filePath + "/" + name);
132         if (url == null)
133         {
134             throw new FileNotFoundException(cl.getResource("").getFile() + name
135                     + " was not found");
136         }
137         return url;
138     }
139 
140     private String getDirectory()
141     {
142         return this.getClass().getName().substring(0,
143                 this.getClass().getName().lastIndexOf('.')).replace('.', '/')
144                 + "/";
145     }
146 
147     @Override
148     protected void setFactories() throws Exception
149     {
150         super.setFactories();
151 
152         FactoryFinder.setFactory(FactoryFinder.APPLICATION_FACTORY,
153                 ApplicationFactoryImpl.class.getName());
154         FactoryFinder.setFactory(FactoryFinder.FACES_CONTEXT_FACTORY,
155                 "org.apache.myfaces.test.mock.MockFacesContextFactory");
156         FactoryFinder.setFactory(FactoryFinder.LIFECYCLE_FACTORY,
157                 "org.apache.myfaces.test.mock.lifecycle.MockLifecycleFactory");
158         FactoryFinder.setFactory(FactoryFinder.RENDER_KIT_FACTORY,
159                 "org.apache.myfaces.test.mock.MockRenderKitFactory");
160         FactoryFinder.setFactory(
161                 FactoryFinder.VIEW_DECLARATION_LANGUAGE_FACTORY,
162                 MockViewDeclarationLanguageFactory.class.getName());
163         FactoryFinder.setFactory(FactoryFinder.TAG_HANDLER_DELEGATE_FACTORY,
164                 TagHandlerDelegateFactoryImpl.class.getName());
165         FactoryFinder.setFactory(FactoryFinder.PARTIAL_VIEW_CONTEXT_FACTORY,
166                 PartialViewContextFactoryImpl.class.getName());
167         FactoryFinder.setFactory(FactoryFinder.VISIT_CONTEXT_FACTORY, 
168                 MockVisitContextFactory.class.getName());
169         FactoryFinder.setFactory(FactoryFinder.FACELET_CACHE_FACTORY,
170                 FaceletCacheFactoryImpl.class.getName());
171     }
172     
173     @Override
174     protected void setUpExternalContext() throws Exception
175     {
176         super.setUpExternalContext();
177         
178         RuntimeConfig.getCurrentInstance(externalContext).setPropertyResolver(
179                 new MockPropertyResolver());
180         RuntimeConfig.getCurrentInstance(externalContext).setVariableResolver(
181                 new MockVariableResolver());
182         RuntimeConfig.getCurrentInstance(externalContext).setExpressionFactory(
183                 createExpressionFactory());
184     }
185     
186     protected ExpressionFactory createExpressionFactory()
187     {
188         return new MockExpressionFactory();
189     }
190     
191     @Override
192     protected void setUpFacesContext() throws Exception
193     {
194         super.setUpFacesContext();
195 
196         //Finally set the ResponseWriter
197         ResponseWriter rw = renderKit.createResponseWriter(
198                 new StringWriter(), null, null);
199         facesContext.setResponseWriter(rw);
200     }
201 
202     @Override
203     protected void setUpRenderKit() throws Exception
204     {
205         super.setUpRenderKit();
206         setupComponents();
207         setupConvertersAndValidators();
208         setupBehaviors();
209         setupRenderers();
210     }
211 
212     @Override
213     protected void setUpView() throws Exception
214     {
215         UIViewRoot root = new UIViewRoot();
216         root.setViewId("/test");
217         root.setRenderKitId(RenderKitFactory.HTML_BASIC_RENDER_KIT);
218         facesContext.setViewRoot(root);
219     }
220 
221     @Override
222     protected void setUpApplication() throws Exception
223     {
224         FactoryFinder.setFactory(FactoryFinder.FACES_CONTEXT_FACTORY,
225             "org.apache.myfaces.test.mock.MockFacesContextFactory");
226         facesContextFactory = (MockFacesContextFactory) FactoryFinder
227             .getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
228         facesContext = (MockFacesContext) facesContextFactory.getFacesContext(
229                 servletContext, request, response, lifecycle);
230         if (facesContext.getExternalContext() != null)
231         {
232             externalContext = (MockExternalContext) facesContext
233                     .getExternalContext();
234         }
235 
236         super.setUpApplication();
237         
238         ((MockFacesContext)facesContext).setApplication(application);
239         
240         ViewHandlerImpl viewHandler = (ViewHandlerImpl) application.getViewHandler();
241         viewHandler.setViewHandlerSupport(new ViewHandlerSupport(){
242 
243             public String calculateActionURL(FacesContext facesContext,
244                     String viewId)
245             {
246                 return viewId;
247             }
248 
249             public String calculateViewId(FacesContext context, String viewId)
250             {
251                 return viewId;
252             }
253             
254             public String calculateAndCheckViewId(FacesContext context, String viewId)
255             {
256                 return viewId;
257             }
258             
259         }); 
260         
261         // Redirect resource request to the directory where the test class is,
262         // to make easier test composite components.
263         //((ResourceHandlerImpl)application.getResourceHandler()).
264         //    setResourceHandlerSupport(new MockResourceHandlerSupport(this.getClass()));
265     }
266     
267     @Override
268     public void setUp() throws Exception
269     {
270         super.setUp();
271         //facesContext.setViewRoot(facesContext.getApplication().getViewHandler()
272         //        .createView(facesContext, "/test"));
273         
274         FacesConfigurationProviderFactory factory = FacesConfigurationProviderFactory.
275             getFacesConfigurationProviderFactory(externalContext);
276         List<FacesConfig> list = factory.getFacesConfigurationProvider(externalContext)
277             .getFaceletTaglibFacesConfig(externalContext);
278         RuntimeConfig runtimeConfig = RuntimeConfig.getCurrentInstance(externalContext);
279         for (FacesConfig fc : list)
280         {
281             for (FaceletTagLibrary lib : fc.getFaceletTagLibraryList())
282             {
283                 runtimeConfig.addFaceletTagLibrary(lib);
284             }
285         }
286         
287         vdl = (MockFaceletViewDeclarationLanguage) application.getViewHandler().
288             getViewDeclarationLanguage(facesContext,"/test");
289         
290         externalContext = null;
291         facesContext = null;
292     }
293     
294     /*@Override
295     public void tearDown() throws Exception
296     {
297         super.tearDown();
298     }*/
299 
300     protected void loadStandardFacesConfig() throws Exception
301     {
302         if (dispenser == null)
303         {
304             InputStream stream = ClassUtils
305             .getResourceAsStream("META-INF/standard-faces-config.xml");
306             FacesConfigUnmarshaller<? extends FacesConfig> unmarshaller = new DigesterFacesConfigUnmarshallerImpl(
307                     externalContext);
308             dispenser = new DigesterFacesConfigDispenserImpl();
309             dispenser.feed(unmarshaller.getFacesConfig(stream,
310                     "META-INF/standard-faces-config.xml"));
311         }
312     }
313     
314     /**
315      * Override this methods and add just what it is necessary
316      * reduce execution time.
317      */
318     protected void setupComponents() throws Exception
319     {
320         loadStandardFacesConfig();
321         for (String componentType : dispenser.getComponentTypes())
322         {
323             application.addComponent(componentType, dispenser
324                     .getComponentClass(componentType));
325         }
326     }
327     
328     protected void setupBehaviors() throws Exception
329     {
330         loadStandardFacesConfig();
331         for (Behavior behavior : dispenser.getBehaviors())
332         {
333             application.addBehavior(behavior.getBehaviorId(), behavior.getBehaviorClass());
334         }
335     }
336     
337     /**
338      * Override this methods and add just what it is necessary
339      * reduce execution time.
340      */
341     protected void setupRenderers() throws Exception
342     {
343         loadStandardFacesConfig();
344         for (Renderer element : dispenser
345                 .getRenderers(RenderKitFactory.HTML_BASIC_RENDER_KIT))
346         {
347             javax.faces.render.Renderer renderer;
348             try
349             {
350                 renderer = (javax.faces.render.Renderer) ClassUtils
351                         .newInstance(element.getRendererClass());
352             }
353             catch (Throwable e)
354             {
355                 // ignore the failure so that the render kit is configured
356                 continue;
357             }
358 
359             renderKit.addRenderer(element.getComponentFamily(), element
360                     .getRendererType(), renderer);
361         }
362         
363         for (ClientBehaviorRenderer element : dispenser.getClientBehaviorRenderers(RenderKitFactory.HTML_BASIC_RENDER_KIT))
364         {
365             javax.faces.render.ClientBehaviorRenderer renderer;
366             
367             try
368             {
369                 renderer = (javax.faces.render.ClientBehaviorRenderer) ClassUtils
370                         .newInstance(element.getRendererClass());
371             }
372             catch (Throwable e)
373             {
374                 // ignore the failure so that the render kit is configured
375                 continue;
376             }
377 
378             renderKit.addClientBehaviorRenderer(element.getRendererType(), renderer);
379         }
380     }
381     
382     /**
383      * Override this methods and add just what it is necessary
384      * reduce execution time.
385      */
386     protected void setupConvertersAndValidators() throws Exception
387     {
388         loadStandardFacesConfig();
389         for (String validatorId : dispenser.getValidatorIds())
390         {
391             application.addValidator(validatorId, dispenser
392                     .getValidatorClass(validatorId));
393         }
394         for (String converterId : dispenser.getConverterIds())
395         {
396             application.addConverter(converterId, dispenser
397                     .getConverterClassById(converterId));
398         }
399         for (String validatorId : dispenser.getValidatorIds())
400         {
401             application.addValidator(validatorId, dispenser
402                     .getValidatorClass(validatorId));
403         }
404     }
405 
406     public URL resolveUrl(String path)
407     {
408         try
409         {
410             return new URL(this.getContext().toURL(), path.substring(1));
411         }
412         catch (Exception e)
413         {
414             throw new FacesException(e);
415         }
416     }
417     
418     /**
419      * Sets the ProjectStage for the test case.
420      * @param stage
421      * @throws IllegalStateException
422      */
423     public void setProjectStage(ProjectStage stage) throws IllegalStateException
424     {
425         try
426         {
427             Field projectStageField = application.getClass().getDeclaredField("_projectStage");
428             projectStageField.setAccessible(true);
429             projectStageField.set(application, stage);
430         }
431         catch (Exception e)
432         {
433             throw new IllegalStateException("Could not configure ProjectStage for test case", e);
434         }
435     }
436 
437 }