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