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.bean.conf.loader.xml;
18  
19  import java.util.HashMap;
20  import java.util.Map;
21  
22  import org.slf4j.Logger;
23  import org.slf4j.LoggerFactory;
24  import org.springframework.beans.factory.InitializingBean;
25  import org.springframework.core.io.ClassPathResource;
26  import org.springframework.core.io.Resource;
27  import org.springframework.util.ClassUtils;
28  import org.springmodules.validation.bean.conf.BeanValidationConfiguration;
29  import org.springmodules.validation.bean.conf.loader.BeanValidationConfigurationLoader;
30  
31  /**
32   * A base class for all bean validation configuration loaders that are resource based (that is, load configuration from
33   * files, urls, etc...)
34   *
35   * @author Uri Boness
36   */
37  public abstract class AbstractResourceBasedBeanValidationConfigurationLoader
38      implements BeanValidationConfigurationLoader, InitializingBean {
39  
40      final Logger logger = LoggerFactory.getLogger(AbstractResourceBasedBeanValidationConfigurationLoader.class);
41  
42      private final static String DEFAULT_RESOURCE_EXTENTION = ".vld.xml";
43  
44      private Map configurationByClass;
45  
46      private Resource[] resources;
47  
48      /**
49       * Constructs a new AbstractResourceBasedBeanValidationConfigurationLoader.
50       */
51      public AbstractResourceBasedBeanValidationConfigurationLoader() {
52          this(new Resource[0]);
53      }
54  
55      /**
56       * Constructs a new AbstractResourceBasedBeanValidationConfigurationLoader with the given resources.
57       *
58       * @param resources The resources from which this loader will load the bean validation configurations.
59       */
60      public AbstractResourceBasedBeanValidationConfigurationLoader(Resource[] resources) {
61          this.resources = resources;
62          configurationByClass = new HashMap();
63      }
64  
65      /**
66       * Loads the bean validation configuration for the given class from the configured resources.
67       *
68       * @see org.springmodules.validation.bean.conf.loader.BeanValidationConfigurationLoader#loadConfiguration(Class)
69       */
70      public final BeanValidationConfiguration loadConfiguration(Class clazz) {
71          BeanValidationConfiguration configuration = (BeanValidationConfiguration) configurationByClass.get(clazz);
72          if (configuration != null) {
73              return configuration;
74          }
75          return loadDefaultConfiguration(clazz);
76      }
77  
78      /**
79       * Determines whether the given class is supported by this loader.
80       *
81       * @see BeanValidationConfigurationLoader#supports(Class)
82       */
83      public final boolean supports(Class clazz) {
84          return configurationByClass.get(clazz) != null;
85      }
86  
87      /**
88       * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
89       */
90      public void afterPropertiesSet() throws Exception {
91          for (int i = 0; i < resources.length; i++) {
92              Map configurations = loadConfigurations(resources[i]);
93              configurationByClass.putAll(configurations);
94          }
95      }
96  
97      /**
98       * Loads all the bean validation configurations from the given resource and returns them as a map where the
99       * value is a {@link BeanValidationConfiguration} instance and the key is the associated class.
100      *
101      * @param resource The resource from which the configurations will be loaded.
102      * @return A map of bean validation configuration by the associated class.
103      */
104     protected abstract Map loadConfigurations(Resource resource);
105 
106     //=============================================== Setter/Getter ====================================================
107 
108     /**
109      * Returns the resouces this loader uses to load bean validation configurations.
110      *
111      * @return The resouces this loader uses to load bean validation configurations.
112      */
113     public Resource[] getResources() {
114         return resources;
115     }
116 
117     /**
118      * Sets the resources this loader will use to load bean validation configurations.
119      *
120      * @param resources The resources this loader will use to load bean validation configurations.
121      */
122     public void setResources(Resource[] resources) {
123         this.resources = resources;
124     }
125 
126     /**
127      * If this loader is configured with only on resource, use this method to retreive it.
128      *
129      * @return The single resource this loader uses to load bean validation configuration from. If the loader uses
130      *         multiple resources, the first one is returned.
131      */
132     public Resource getResource() {
133         return (resources[0] != null) ? resources[0] : null;
134     }
135 
136     /**
137      * Sets a single resource this loader will use to load the bean validation configurations from.
138      *
139      * @param resource The one resource this loader will use to load the bean validation configurations from.
140      */
141     public void setResource(Resource resource) {
142         setResources(new Resource[]{resource});
143     }
144 
145     //=============================================== Helper Methods ===================================================
146 
147     /**
148      * Loads the default validation configuration for the given class, caches it and returns it. The configuration
149      * resource for the given class is resolved by the {@link #createDefaultConfigurationFileName(Class)} method.
150      *
151      * @param clazz The class for which the default configuration should be loaded.
152      * @return The default validation configuration of the given class.
153      */
154     protected BeanValidationConfiguration loadDefaultConfiguration(Class clazz) {
155         String fileName = createDefaultConfigurationFileName(clazz);
156         Resource resource = new ClassPathResource(fileName, clazz);
157         if (resource.exists()) {
158             Map configurationByClass = loadConfigurations(resource);
159             this.configurationByClass.putAll(configurationByClass);
160             return (BeanValidationConfiguration) configurationByClass.get(clazz);
161         }
162         logger.warn("Could not find the default validation configuration for class '" + clazz.getName() + "'");
163         this.configurationByClass.put(clazz, null);
164         return null;
165     }
166 
167     /**
168      * Creates the default configuration file name for the given class. This method will search in the classpath for
169      * a file that is located where the class itself is located, named after the class, and has the extention of
170      * ".vld.xml". For example, the default configuration file name for class
171      * <code>Person</code> will be <code>Person.vld.xml</code>.
172      *
173      * @param clazz The class for which the default configuration will be created.
174      * @return The default validatoin configuration resource for the given class.
175      */
176     protected String createDefaultConfigurationFileName(Class clazz) {
177         return ClassUtils.getShortName(clazz) + DEFAULT_RESOURCE_EXTENTION;
178     }
179 
180 }