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