View Javadoc

1   /*
2    * Copyright 2004-2009 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.springmodules.validation.commons;
18  
19  import java.io.IOException;
20  import java.io.InputStream;
21  import java.util.Locale;
22  
23  import org.apache.commons.validator.Form;
24  import org.apache.commons.validator.Validator;
25  import org.apache.commons.validator.ValidatorResources;
26  import org.slf4j.Logger;
27  import org.slf4j.LoggerFactory;
28  import org.springframework.beans.FatalBeanException;
29  import org.springframework.beans.factory.InitializingBean;
30  import org.springframework.core.io.Resource;
31  import org.springframework.util.StringUtils;
32  import org.springframework.validation.Errors;
33  import org.xml.sax.SAXException;
34  
35  /**
36   * @author Daniel Miller
37   * @author Rob Harrop
38   */
39  public class DefaultValidatorFactory implements ValidatorFactory, InitializingBean {
40  
41      /**
42       * Key used to store the Spring <code>Errors</code> instance in the <code>Validator</code>
43       */
44      public static final String ERRORS_KEY = "org.springframework.validation.Errors";
45  
46      /**
47       * The <code>Log</code> instance used by this class.
48       */
49      private static Logger log = LoggerFactory.getLogger(DefaultValidatorFactory.class);
50  
51      /**
52       * the Commons Validator <code>ValidatorResources</code> used to load validation configuration.
53       */
54      private ValidatorResources validatorResources;
55  
56      /**
57       * Checks that the <code>ValidatorResources</code> exists and has been configured with resources
58       * via a call to <code>setValidationConfigLocations</code>.
59       *
60       * @throws org.springframework.beans.FatalBeanException if <code>setValidationConfigLocations()</code> has not been called.
61       */
62      public void afterPropertiesSet() throws Exception {
63          if (this.validatorResources == null) {
64              throw new FatalBeanException("Unable to locate validation configuration. Property [validationLocations] is required.");
65          }
66      }
67  
68      /**
69       * Sets the locations of the validation configuration files from which to load validation rules. Creates an instance
70       * of <code>ValidatorResources</code> from the specified configuration files.
71       *
72       * @see org.springframework.core.io.Resource
73       * @see ValidatorResources
74       */
75      public void setValidationConfigLocations(Resource[] validationConfigLocations) {
76  
77          if (DefaultValidatorFactory.log.isInfoEnabled()) {
78              DefaultValidatorFactory.log.info("Loading validation configurations from [" + StringUtils.arrayToCommaDelimitedString(validationConfigLocations) + "]");
79          }
80  
81          try {
82              InputStream[] inputStreams = new InputStream[validationConfigLocations.length];
83  
84              for (int i = 0; i < inputStreams.length; i++) {
85                  inputStreams[i] = validationConfigLocations[i].getInputStream();
86              }
87  
88              this.validatorResources = new ValidatorResources(inputStreams);
89          }
90          catch (IOException e) {
91              throw new FatalBeanException("Unable to read validation configuration due to IOException.", e);
92          }
93          catch (SAXException e) {
94              throw new FatalBeanException("Unable to parse validation configuration XML", e);
95          }
96      }
97  
98      /**
99       * Gets a new instance of a <code>org.apache.commons.validator.Validator</code> for the given bean.
100      *
101      * @param beanName The name of the bean for which this <code>Validator</code> will be created
102      * @see org.apache.commons.validator.Validator
103      */
104     public Validator getValidator(String beanName, Object bean, Errors errors) {
105         Validator validator = new Validator(validatorResources, beanName);
106         validator.setParameter(DefaultValidatorFactory.ERRORS_KEY, errors);
107         validator.setParameter(Validator.BEAN_PARAM, bean);
108         return validator;
109     }
110 
111 
112     /**
113      * Returns true if this validator factory can create a validator that
114      * supports the given <code>beanName</code> and <code>locale</code>.
115      *
116      * @param beanName name of the bean to be validated.
117      * @param locale <code>Locale</code> to search under.
118      * @return <code>true</code> if this validator factory can create a validator for
119      *         the given bean name, <code>false otherwise.
120      */
121     public boolean hasRulesForBean(String beanName, Locale locale) {
122         Form form = validatorResources.getForm(locale, beanName);
123         return (form != null);
124     }
125 
126     /**
127      * Gets the managed instance of <code>ValidatorResources</code>.
128      */
129     public ValidatorResources getValidatorResources() {
130         return validatorResources;
131     }
132 
133 }