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.config;
20  
21  import java.io.File;
22  import java.lang.reflect.Field;
23  import java.util.HashMap;
24  
25  import javax.faces.FactoryFinder;
26  import javax.faces.validator.BeanValidator;
27  import javax.faces.validator.LengthValidator;
28  import javax.faces.validator.RequiredValidator;
29  import javax.faces.webapp.FacesServlet;
30  
31  import org.apache.myfaces.test.base.AbstractJsfTestCase;
32  import org.apache.myfaces.test.mock.MockRenderKitFactory;
33  import org.apache.myfaces.util.ExternalSpecifications;
34  
35  /**
36   * Test cases for the installation of default validators (e.g. BeanValidator).
37   * @author Jakob Korherr (latest modification by $Author: jakobk $)
38   * @version $Revision: 946728 $ $Date: 2010-05-20 12:57:58 -0500 (Thu, 20 May 2010) $
39   * @since 2.0
40   */
41  public class FacesConfiguratorDefaultValidatorsTestCase extends AbstractJsfTestCase
42  {
43      
44      private FacesConfigurator facesConfigurator;
45      
46      public FacesConfiguratorDefaultValidatorsTestCase(String name)
47      {
48          super(name);
49      }
50      
51      protected void setUp() throws Exception
52      {
53          super.setUp();
54          
55          facesConfigurator = new FacesConfigurator(externalContext);
56      }
57      
58      @Override
59      protected void tearDown() throws Exception
60      {
61          facesConfigurator = null;
62          
63          super.tearDown();
64      }
65      
66      /**
67       * We have to reset MockRenderKitFactory before, because the FacesConfigurator
68       * will later add HTML_BASIC as a new RenderKit, but MockRenderKitFactory has 
69       * this one already installed and so it would throw an Exception.
70       */
71      @SuppressWarnings("unchecked")
72      private void _cleanRenderKits()
73      {
74          try
75          {
76              MockRenderKitFactory renderKitFactory 
77                      = (MockRenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
78              Field renderKitsField = MockRenderKitFactory.class.getDeclaredField("renderKits");
79              renderKitsField.setAccessible(true);
80              renderKitsField.set(renderKitFactory, new HashMap());
81          }
82          catch (Exception e)
83          {
84              throw new IllegalStateException("Could not configure MockRenderKitFactory for test case.", e);
85          }
86      }
87      
88      /**
89       * Sets the cached field in ExternalSpecifications to enable or 
90       * disable bean validation for testing purposes.
91       * 
92       * @param available
93       */
94      private void _setBeanValidationAvailable(boolean available)
95      {
96          try
97          {
98              Field field = ExternalSpecifications.class.getDeclaredField("beanValidationAvailable");
99              field.setAccessible(true);
100             field.set(ExternalSpecifications.class, available);
101         }
102         catch (Exception e)
103         {
104             throw new IllegalStateException("Could not configure BeanValidation for the test case.", e);
105         }
106     }
107 
108     /**
109      * Tests the case that the default bean validator is disabled with the config parameter
110      * javax.faces.validator.DISABLE_DEFAULT_BEAN_VALIDATOR, but it is defined in the faces-config.
111      * In this case the bean validator should be installed as a default validator.
112      */
113     public void testDefaultBeanValidatorDisabledButPresentInFacesConfig()
114     {
115         // remove existing RenderKit installations
116         _cleanRenderKits();
117         
118         // set the document root for the config file
119         File documentRoot = new File("src/test/resources/org/apache/myfaces/config/testfiles");
120         servletContext.setDocumentRoot(documentRoot);
121         
122         // set the right faces-config file
123         servletContext.addInitParameter(FacesServlet.CONFIG_FILES_ATTR, 
124                 "/default-bean-validator.xml");
125         
126         // disable the default bean validator via config parameter
127         // thus it will not be added programmatically
128         servletContext.addInitParameter(
129                 BeanValidator.DISABLE_DEFAULT_BEAN_VALIDATOR_PARAM_NAME, "true");
130         
131         // configure BeanValidation to be available
132         _setBeanValidationAvailable(true);
133             
134         // run the configuration procedure
135         facesConfigurator.configure();
136         
137         // the bean validator has to be installed, because 
138         // of the entry in default-bean-validator.xml
139         assertTrue(application.getDefaultValidatorInfo()
140                 .containsKey(BeanValidator.VALIDATOR_ID));
141     }
142     
143     /**
144      * Tests the case when bean validation is available, but adding the BeanValidator
145      * as a default validator has been disabled via the config parameter and there
146      * is no faces-config file that would install it manually.
147      * In this case the BeanValidator mustn't be installed.
148      */
149     public void testDefaultBeanValidatorDisabled()
150     {
151         // remove existing RenderKit installations
152         _cleanRenderKits();
153         
154         // set the document root for the config file
155         File documentRoot = new File("src/test/resources/org/apache/myfaces/config/testfiles");
156         servletContext.setDocumentRoot(documentRoot);
157         
158         // disable the default bean validator via config parameter
159         // thus it will not be added programmatically
160         servletContext.addInitParameter(
161                 BeanValidator.DISABLE_DEFAULT_BEAN_VALIDATOR_PARAM_NAME, "true");
162         
163         // configure BeanValidation to be available
164         _setBeanValidationAvailable(true);
165             
166         // run the configuration procedure
167         facesConfigurator.configure();
168         
169         // the bean validator must not be installed, because it
170         // has been disabled and there is no entry in the faces-config
171         // that would install it manually.
172         assertFalse(application.getDefaultValidatorInfo()
173                 .containsKey(BeanValidator.VALIDATOR_ID));
174     }
175     
176     /**
177      * Tests the case that bean validation is not available in the classpath.
178      * In this case the BeanValidator must not be installed.
179      */
180     public void testBeanValidationNotAvailable()
181     {
182         // remove existing RenderKit installations
183         _cleanRenderKits();
184         
185         // set the document root for the config file
186         File documentRoot = new File("src/test/resources/org/apache/myfaces/config/testfiles");
187         servletContext.setDocumentRoot(documentRoot);
188         
189         // configure BeanValidation to be not available
190         _setBeanValidationAvailable(false);
191             
192         // run the configuration procedure
193         facesConfigurator.configure();
194         
195         // the bean validator mustn't be installed, because
196         // bean validation is not available in the classpath
197         assertFalse(application.getDefaultValidatorInfo()
198                 .containsKey(BeanValidator.VALIDATOR_ID));
199     }
200     
201     /**
202      * Tests the case with two config files. The first one would install the a
203      * default validator (in this case the RequiredValidator), but the second one 
204      * specifies an empty default-validators element, which overrules the first one
205      * and cleares all existing default-validators.
206      * In this case the RequiredValidator must not be installed, however the BeanValidator
207      * has to be installed (automatically) since bean validation is available.
208      */
209     public void testDefaultValidatorsClearedByLatterConfigFileWithEmptyElement()
210     {
211         // remove existing RenderKit installations
212         _cleanRenderKits();
213         
214         // set the document root for the config files
215         File documentRoot = new File("src/test/resources/org/apache/myfaces/config/testfiles");
216         servletContext.setDocumentRoot(documentRoot);
217         
218         // set the right faces-config files.
219         // we want that default-required-validator.xml is feeded before
220         // empty-default-validators.xml and since the FacesConfigurator
221         // will change the order when no ordering information is present, 
222         // we have to specify them the other way round!
223         servletContext.addInitParameter(FacesServlet.CONFIG_FILES_ATTR, 
224                 "/empty-default-validators.xml,/default-required-validator.xml");
225         
226         // configure BeanValidation to be available
227         _setBeanValidationAvailable(true);
228         
229         // run the configuration procedure
230         facesConfigurator.configure();
231         
232         // the required validator must not be installed, because the latter config file
233         // (empty-default-validators.xml) has an empty default validators element
234         // and this cleares all existing default-validators.
235         assertFalse(application.getDefaultValidatorInfo().containsKey(RequiredValidator.VALIDATOR_ID));
236         
237         // and since bean validation is available, the BeanValidator has to be installed
238         assertTrue(application.getDefaultValidatorInfo().containsKey(BeanValidator.VALIDATOR_ID));
239     }
240     
241     /**
242      * Tests the case with two config files. The first one installs a
243      * default validator (in this case the RequiredValidator), and the 
244      * second one does not specify any default-validators element.
245      * In this case the RequiredValidator must be installed, because the latter
246      * config file does not specify and default-validator information. Furthermore the 
247      * BeanValidator must also be installed since bean validation is available.
248      */
249     public void testDefaultValidatorsNotClearedByLatterConfigFileWithNoElement()
250     {
251         // remove existing RenderKit installations
252         _cleanRenderKits();
253         
254         // set the document root for the config files
255         File documentRoot = new File("src/test/resources/org/apache/myfaces/config/testfiles");
256         servletContext.setDocumentRoot(documentRoot);
257         
258         // set the right faces-config files.
259         // we want that default-required-validator.xml is feeded before
260         // no-default-validators.xml and since the FacesConfigurator
261         // will change the order when no ordering information is present, 
262         // we have to specify them the other way round!
263         servletContext.addInitParameter(FacesServlet.CONFIG_FILES_ATTR, 
264                 "/no-default-validators.xml,/default-required-validator.xml");
265         
266         // configure BeanValidation to be available
267         _setBeanValidationAvailable(true);
268         
269         // run the configuration procedure
270         facesConfigurator.configure();
271         
272         // the required validator must be installed, because the latter config file
273         // (no-default-validators.xml) has not got a default validators element.
274         assertTrue(application.getDefaultValidatorInfo().containsKey(RequiredValidator.VALIDATOR_ID));
275         
276         // and since bean validation is available, the BeanValidator has to be installed
277         assertTrue(application.getDefaultValidatorInfo().containsKey(BeanValidator.VALIDATOR_ID));
278     }
279     
280     /**
281      * Tests the case with two config files. The first one would install a
282      * default validator (in this case the RequiredValidator), but the second one 
283      * also specifies default-validators. This overrules the first config and thus 
284      * cleares all existing default-validators and adds its default-validators.
285      * In this case the RequiredValidator must not be installed, however the 
286      * LengthValidator has to be installed (and the BeanValidator must not be installed
287      * since bean validation is not available).
288      */
289     public void testDefaultValidatorsOverwrittenByLatterConfigFile()
290     {
291         // remove existing RenderKit installations
292         _cleanRenderKits();
293         
294         // set the document root for the config files
295         File documentRoot = new File("src/test/resources/org/apache/myfaces/config/testfiles");
296         servletContext.setDocumentRoot(documentRoot);
297         
298         // set the right faces-config files.
299         // we want that default-required-validator.xml is feeded before
300         // default-length-validator.xml and since the FacesConfigurator
301         // will change the order when no ordering information is present, 
302         // we have to specify them the other way round!
303         servletContext.addInitParameter(FacesServlet.CONFIG_FILES_ATTR, 
304                 "/default-length-validator.xml,/default-required-validator.xml");
305         
306         // configure BeanValidation to be not available
307         _setBeanValidationAvailable(false);
308         
309         // run the configuration procedure
310         facesConfigurator.configure();
311         
312         // the required validator must not be installed, because the latter config file
313         // (default-length-validator.xml) specifies a default validators element
314         // and this cleares all existing default-validators.
315         assertFalse(application.getDefaultValidatorInfo().containsKey(RequiredValidator.VALIDATOR_ID));
316         
317         // the length validator has to be installed, because it was installed
318         // by the latter config file
319         assertTrue(application.getDefaultValidatorInfo().containsKey(LengthValidator.VALIDATOR_ID));
320         
321         // and since bean validation is not available, the BeanValidator must not be installed
322         assertFalse(application.getDefaultValidatorInfo().containsKey(BeanValidator.VALIDATOR_ID));
323     }
324 
325 }