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