View Javadoc

1   package org.apache.struts2.oval.interceptor;
2   
3   import com.opensymphony.xwork2.inject.Inject;
4   import com.opensymphony.xwork2.util.FileManager;
5   import com.opensymphony.xwork2.util.logging.Logger;
6   import com.opensymphony.xwork2.util.logging.LoggerFactory;
7   import net.sf.oval.configuration.Configurer;
8   import net.sf.oval.configuration.annotation.AnnotationsConfigurer;
9   import net.sf.oval.configuration.annotation.JPAAnnotationsConfigurer;
10  import net.sf.oval.configuration.xml.XMLConfigurer;
11  
12  import java.util.ArrayList;
13  import java.util.HashMap;
14  import java.util.List;
15  import java.util.Map;
16  import java.util.Set;
17  import java.util.TreeSet;
18  
19  
20  public class DefaultOValValidationManager implements OValValidationManager {
21      private static final Logger LOG = LoggerFactory.getLogger(DefaultOValValidationManager.class);
22  
23      protected static final String VALIDATION_CONFIG_SUFFIX = "-validation.xml";
24      protected final Map<String, List<Configurer>> validatorCache = new HashMap<String, List<Configurer>>();
25      protected final Map<String, Configurer> validatorFileCache = new HashMap<String, Configurer>();
26  
27      protected boolean validateJPAAnnotations;
28  
29      public synchronized List<Configurer> getConfigurers(Class clazz, String context, boolean validateJPAAnnotations) {
30          this.validateJPAAnnotations =validateJPAAnnotations;
31          final String validatorKey = buildValidatorKey(clazz, context);
32  
33          if (validatorCache.containsKey(validatorKey)) {
34              if (FileManager.isReloadingConfigs()) {
35                  List<Configurer> configurers = buildXMLConfigurers(clazz, context, true, null);
36  
37                  //add an annotation configurer
38                  addAditionalConfigurers(configurers);
39                  validatorCache.put(validatorKey, configurers);
40              }
41          } else {
42              List<Configurer> configurers = buildXMLConfigurers(clazz, context, false, null);
43  
44              //add an annotation configurer
45              addAditionalConfigurers(configurers);
46              validatorCache.put(validatorKey, configurers);
47          }
48  
49          // get the set of validator configs
50          return validatorCache.get(validatorKey);
51      }
52  
53      private void addAditionalConfigurers(List<Configurer> configurers) {
54          AnnotationsConfigurer annotationsConfigurer = new AnnotationsConfigurer();
55          configurers.add(annotationsConfigurer);
56  
57          if (validateJPAAnnotations) {
58              if (LOG.isDebugEnabled())
59                  LOG.debug("Adding support for JPA annotations validations in OVal");
60              configurers.add(new JPAAnnotationsConfigurer());
61          }
62      }
63  
64      protected static String buildValidatorKey(Class clazz, String context) {
65          StringBuilder sb = new StringBuilder(clazz.getName());
66          sb.append("/");
67          sb.append(context);
68          return sb.toString();
69      }
70  
71      private List<Configurer> buildXMLConfigurers(Class clazz, String context, boolean checkFile, Set<String> checked) {
72          List<Configurer> configurers = new ArrayList<Configurer>();
73  
74          if (checked == null) {
75              checked = new TreeSet<String>();
76          } else if (checked.contains(clazz.getName())) {
77              return configurers;
78          }
79  
80          if (clazz.isInterface()) {
81              for (Class anInterface : clazz.getInterfaces()) {
82                  configurers.addAll(buildXMLConfigurers(anInterface, context, checkFile, checked));
83              }
84          } else {
85              if (!clazz.equals(Object.class)) {
86                  configurers.addAll(buildXMLConfigurers(clazz.getSuperclass(), context, checkFile, checked));
87              }
88          }
89  
90          // look for validators for implemented interfaces
91          for (Class anInterface1 : clazz.getInterfaces()) {
92              if (checked.contains(anInterface1.getName())) {
93                  continue;
94              }
95  
96              addIfNotNull(configurers, buildClassValidatorConfigs(anInterface1, checkFile));
97  
98              if (context != null) {
99                  addIfNotNull(configurers, buildAliasValidatorConfigs(anInterface1, context, checkFile));
100             }
101 
102             checked.add(anInterface1.getName());
103         }
104 
105         addIfNotNull(configurers, buildClassValidatorConfigs(clazz, checkFile));
106 
107         if (context != null) {
108             addIfNotNull(configurers, buildAliasValidatorConfigs(clazz, context, checkFile));
109         }
110 
111         checked.add(clazz.getName());
112 
113         return configurers;
114     }
115 
116     protected void addIfNotNull(List<Configurer> configurers, Configurer configurer) {
117         if (configurer != null)
118             configurers.add(configurer);
119     }
120 
121 
122     protected XMLConfigurer buildAliasValidatorConfigs(Class aClass, String context, boolean checkFile) {
123         String fileName = aClass.getName().replace('.', '/') + "-" + context + VALIDATION_CONFIG_SUFFIX;
124 
125         return loadFile(fileName, aClass, checkFile);
126     }
127 
128     protected XMLConfigurer buildClassValidatorConfigs(Class aClass, boolean checkFile) {
129         String fileName = aClass.getName().replace('.', '/') + VALIDATION_CONFIG_SUFFIX;
130 
131         return loadFile(fileName, aClass, checkFile);
132     }
133 
134     protected XMLConfigurer loadFile(String fileName, Class clazz, boolean checkFile) {
135         if ((checkFile && FileManager.fileNeedsReloading(fileName, clazz)) || !validatorFileCache.containsKey(fileName)) {
136             java.io.InputStream is = null;
137 
138             try {
139                 is = FileManager.loadFile(fileName, clazz);
140 
141                 if (is != null) {
142                     if (LOG.isDebugEnabled())
143                         LOG.debug("Loading validation xml file [#0]", fileName);
144                     XMLConfigurer configurer = new XMLConfigurer();
145                     configurer.fromXML(is);
146                     validatorFileCache.put(fileName, configurer);
147                     return configurer;
148                 }
149             } finally {
150                 if (is != null) {
151                     try {
152                         is.close();
153                     } catch (java.io.IOException e) {
154                         LOG.error("Unable to close input stream for [#0] ", e, fileName);
155                     }
156                 }
157             }
158         } else {
159             return (XMLConfigurer) validatorFileCache.get(fileName);
160         }
161 
162         return null;
163     }
164 }