Author: musachy
Date: Mon Mar 30 00:15:50 2009
New Revision: 759802
URL: http://svn.apache.org/viewvc?rev=759802&view=rev
Log:
Add XML support
Added:
struts/sandbox/trunk/struts2-oval-plugin/src/main/java/org/apache/struts2/interceptor/DefaultOValValidationManager.java
struts/sandbox/trunk/struts2-oval-plugin/src/main/java/org/apache/struts2/interceptor/OValValidationManager.java
struts/sandbox/trunk/struts2-oval-plugin/src/test/java/org/apache/struts2/interceptor/SimpleFieldsXml.java
struts/sandbox/trunk/struts2-oval-plugin/src/test/resources/org/apache/struts2/interceptor/SimpleFieldsXml-validation.xml
Modified:
struts/sandbox/trunk/struts2-oval-plugin/pom.xml
struts/sandbox/trunk/struts2-oval-plugin/src/main/java/org/apache/struts2/interceptor/OValValidationInterceptor.java
struts/sandbox/trunk/struts2-oval-plugin/src/main/resources/struts-plugin.xml
struts/sandbox/trunk/struts2-oval-plugin/src/test/java/org/apache/struts2/interceptor/OValValidationInterceptorTest.java
struts/sandbox/trunk/struts2-oval-plugin/src/test/resources/oval-test.xml
Modified: struts/sandbox/trunk/struts2-oval-plugin/pom.xml
URL:
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-oval-plugin/pom.xml?rev=759802&r1=759801&r2=759802&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-oval-plugin/pom.xml (original)
+++ struts/sandbox/trunk/struts2-oval-plugin/pom.xml Mon Mar 30 00:15:50 2009
@@ -50,8 +50,14 @@
<version>1.31</version>
</dependency>
+ <dependency>
+ <groupId>com.thoughtworks.xstream</groupId>
+ <artifactId>xstream</artifactId>
+ <version>1.3.1</version>
+ </dependency>
+
<!-- Testing -->
- <dependency>
+ <dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<version>2.0</version>
Added:
struts/sandbox/trunk/struts2-oval-plugin/src/main/java/org/apache/struts2/interceptor/DefaultOValValidationManager.java
URL:
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-oval-plugin/src/main/java/org/apache/struts2/interceptor/DefaultOValValidationManager.java?rev=759802&view=auto
==============================================================================
---
struts/sandbox/trunk/struts2-oval-plugin/src/main/java/org/apache/struts2/interceptor/DefaultOValValidationManager.java
(added)
+++
struts/sandbox/trunk/struts2-oval-plugin/src/main/java/org/apache/struts2/interceptor/DefaultOValValidationManager.java
Mon Mar 30 00:15:50 2009
@@ -0,0 +1,139 @@
+package org.apache.struts2.interceptor;
+
+import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.util.FileManager;
+import com.opensymphony.xwork2.util.logging.Logger;
+import com.opensymphony.xwork2.util.logging.LoggerFactory;
+import net.sf.oval.configuration.xml.XMLConfigurer;
+import net.sf.oval.configuration.Configurer;
+
+import java.util.List;
+import java.util.Map;
+import java.util.ArrayList;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.HashMap;
+
+
+public class DefaultOValValidationManager implements OValValidationManager {
+ private static final Logger LOG =
LoggerFactory.getLogger(DefaultOValValidationManager.class);
+
+ private static final String VALIDATION_CONFIG_SUFFIX = "-validation.xml";
+ private final Map<String, List<Configurer>> validatorCache = new
HashMap<String, List<Configurer>>();
+ private final Map<String, Configurer> validatorFileCache = new
HashMap<String, Configurer>();
+
+ public synchronized List<Configurer> getConfigurers(Class clazz, String
context) {
+ final String validatorKey = buildValidatorKey(clazz, context);
+
+ if (validatorCache.containsKey(validatorKey)) {
+ if (FileManager.isReloadingConfigs()) {
+ validatorCache.put(validatorKey, buildXMLConfigurers(clazz,
context, true, null));
+ }
+ } else {
+ validatorCache.put(validatorKey, buildXMLConfigurers(clazz,
context, false, null));
+ }
+
+ // get the set of validator configs
+ return validatorCache.get(validatorKey);
+ }
+
+ protected static String buildValidatorKey(Class clazz, String context) {
+ StringBuilder sb = new StringBuilder(clazz.getName());
+ sb.append("/");
+ sb.append(context);
+ return sb.toString();
+ }
+
+ private List<Configurer> buildXMLConfigurers(Class clazz, String context,
boolean checkFile, Set<String> checked) {
+ List<Configurer> xmlConfigurers = new ArrayList<Configurer>();
+
+ if (checked == null) {
+ checked = new TreeSet<String>();
+ } else if (checked.contains(clazz.getName())) {
+ return xmlConfigurers;
+ }
+
+ if (clazz.isInterface()) {
+ for (Class anInterface : clazz.getInterfaces()) {
+ xmlConfigurers.addAll(buildXMLConfigurers(anInterface,
context, checkFile, checked));
+ }
+ } else {
+ if (!clazz.equals(Object.class)) {
+
xmlConfigurers.addAll(buildXMLConfigurers(clazz.getSuperclass(), context,
checkFile, checked));
+ }
+ }
+
+ // look for validators for implemented interfaces
+ for (Class anInterface1 : clazz.getInterfaces()) {
+ if (checked.contains(anInterface1.getName())) {
+ continue;
+ }
+
+ addIfNotNull(xmlConfigurers,
buildClassValidatorConfigs(anInterface1, checkFile));
+
+ if (context != null) {
+ addIfNotNull(xmlConfigurers,
buildAliasValidatorConfigs(anInterface1, context, checkFile));
+ }
+
+ checked.add(anInterface1.getName());
+ }
+
+ addIfNotNull(xmlConfigurers, buildClassValidatorConfigs(clazz,
checkFile));
+
+ if (context != null) {
+ addIfNotNull(xmlConfigurers, buildAliasValidatorConfigs(clazz,
context, checkFile));
+ }
+
+ checked.add(clazz.getName());
+
+ return xmlConfigurers;
+ }
+
+ protected void addIfNotNull(List<Configurer> configurers, Configurer
configurer) {
+ if (configurer != null)
+ configurers.add(configurer);
+ }
+
+
+ protected XMLConfigurer buildAliasValidatorConfigs(Class aClass, String
context, boolean checkFile) {
+ String fileName = aClass.getName().replace('.', '/') + "-" + context +
VALIDATION_CONFIG_SUFFIX;
+
+ return loadFile(fileName, aClass, checkFile);
+ }
+
+ protected XMLConfigurer buildClassValidatorConfigs(Class aClass, boolean
checkFile) {
+ String fileName = aClass.getName().replace('.', '/') +
VALIDATION_CONFIG_SUFFIX;
+
+ return loadFile(fileName, aClass, checkFile);
+ }
+
+ protected XMLConfigurer loadFile(String fileName, Class clazz, boolean
checkFile) {
+ if ((checkFile && FileManager.fileNeedsReloading(fileName, clazz)) ||
!validatorFileCache.containsKey(fileName)) {
+ java.io.InputStream is = null;
+
+ try {
+ is = FileManager.loadFile(fileName, clazz);
+
+ if (is != null) {
+ if (LOG.isDebugEnabled())
+ LOG.debug("Loading validation xml file [#0]",
fileName);
+ XMLConfigurer configurer = new XMLConfigurer();
+ configurer.fromXML(is);
+ validatorFileCache.put(fileName, configurer);
+ }
+ } finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (java.io.IOException e) {
+ LOG.error("Unable to close input stream for [#0] ", e,
fileName);
+ }
+ }
+ }
+ } else {
+ return (XMLConfigurer) validatorFileCache.get(fileName);
+ }
+
+ return null;
+ }
+}
\ No newline at end of file
Modified:
struts/sandbox/trunk/struts2-oval-plugin/src/main/java/org/apache/struts2/interceptor/OValValidationInterceptor.java
URL:
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-oval-plugin/src/main/java/org/apache/struts2/interceptor/OValValidationInterceptor.java?rev=759802&r1=759801&r2=759802&view=diff
==============================================================================
---
struts/sandbox/trunk/struts2-oval-plugin/src/main/java/org/apache/struts2/interceptor/OValValidationInterceptor.java
(original)
+++
struts/sandbox/trunk/struts2-oval-plugin/src/main/java/org/apache/struts2/interceptor/OValValidationInterceptor.java
Mon Mar 30 00:15:50 2009
@@ -31,9 +31,10 @@
import com.opensymphony.xwork2.util.logging.Logger;
import com.opensymphony.xwork2.util.logging.LoggerFactory;
import com.opensymphony.xwork2.util.ValueStack;
-import com.opensymphony.xwork2.util.reflection.ReflectionProvider;
import net.sf.oval.Validator;
import net.sf.oval.ConstraintViolation;
+import net.sf.oval.configuration.xml.XMLConfigurer;
+import net.sf.oval.configuration.Configurer;
import net.sf.oval.context.FieldContext;
import net.sf.oval.context.OValContext;
import net.sf.oval.context.MethodReturnValueContext;
@@ -50,11 +51,17 @@
public class OValValidationInterceptor extends MethodFilterInterceptor {
private static final Logger LOG =
LoggerFactory.getLogger(OValValidationInterceptor.class);
- private final static String VALIDATE_PREFIX = "validate";
- private final static String ALT_VALIDATE_PREFIX = "validateDo";
+ protected final static String VALIDATE_PREFIX = "validate";
+ protected final static String ALT_VALIDATE_PREFIX = "validateDo";
- private boolean alwaysInvokeValidate = true;
- private boolean programmatic = true;
+ protected boolean alwaysInvokeValidate = true;
+ protected boolean programmatic = true;
+ protected OValValidationManager validationManager;
+
+ @Inject
+ public void setValidationManager(OValValidationManager validationManager) {
+ this.validationManager = validationManager;
+ }
/**
* Determines if {...@link com.opensymphony.xwork2.Validateable}'s
<code>validate()</code> should be called,
@@ -81,13 +88,14 @@
ActionProxy proxy = invocation.getProxy();
ValueStack valueStack = invocation.getStack();
String methodName = proxy.getMethod();
+ String context = proxy.getActionName();
if (LOG.isDebugEnabled()) {
LOG.debug("Validating [#0/#1] with method [#2]",
invocation.getProxy().getNamespace(), invocation.getProxy().getActionName(),
methodName);
}
//OVal vallidatio (no XML yet)
- performOValValidation(action, valueStack, methodName);
+ performOValValidation(action, valueStack, methodName, context);
//Validatable.valiedate() and validateX()
performProgrammaticValidation(invocation, action);
@@ -109,15 +117,13 @@
PrefixMethodInvocationUtil.invokePrefixMethod(
invocation,
new String[]{VALIDATE_PREFIX, ALT_VALIDATE_PREFIX});
- }
- catch (Exception e) {
+ } catch (Exception e) {
// If any exception occurred while doing reflection, we want
// validate() to be executed
LOG.warn("An exception occured while executing the prefix
method", e);
exception = e;
}
-
if (alwaysInvokeValidate) {
validateable.validate();
}
@@ -129,10 +135,14 @@
}
}
- protected void performOValValidation(Object action, ValueStack valueStack,
String methodName) throws NoSuchMethodException {
- Validator validator = new Validator();
+ protected void performOValValidation(Object action, ValueStack valueStack,
String methodName, String context) throws NoSuchMethodException {
+ Class clazz = action.getClass();
+ //read validation from xmls
+ List<Configurer> configurers = validationManager.getConfigurers(clazz,
context);
+
+ Validator validator = configurers.isEmpty() ? new Validator() : new
Validator(configurers);
//if the method is annotated with a @Profiles annotation, use those
profiles
- Method method = action.getClass().getMethod(methodName, new Class[0]);
+ Method method = clazz.getMethod(methodName, new Class[0]);
if (method != null) {
Profiles profiles = method.getAnnotation(Profiles.class);
if (profiles != null) {
@@ -167,7 +177,7 @@
if (isActionError(violation))
validatorContext.addActionError(message);
else {
- String className = action.getClass().getName();
+ String className = clazz.getName();
//the default OVal message shows the field name as
ActionClass.fieldName
message = StringUtils.removeStart(message, className +
".");
validatorContext.addFieldError(extractFieldName(violation), message);
@@ -176,6 +186,7 @@
}
}
+
/**
* Get field name, used to add the validation error to fieldErrors
*/
Added:
struts/sandbox/trunk/struts2-oval-plugin/src/main/java/org/apache/struts2/interceptor/OValValidationManager.java
URL:
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-oval-plugin/src/main/java/org/apache/struts2/interceptor/OValValidationManager.java?rev=759802&view=auto
==============================================================================
---
struts/sandbox/trunk/struts2-oval-plugin/src/main/java/org/apache/struts2/interceptor/OValValidationManager.java
(added)
+++
struts/sandbox/trunk/struts2-oval-plugin/src/main/java/org/apache/struts2/interceptor/OValValidationManager.java
Mon Mar 30 00:15:50 2009
@@ -0,0 +1,51 @@
+package org.apache.struts2.interceptor;
+
+import net.sf.oval.configuration.xml.XMLConfigurer;
+import net.sf.oval.configuration.Configurer;
+
+import java.util.List;
+
+
+public interface OValValidationManager {
+ /**
+ * <p>This method 'collects' all the validator configurations for a given
+ * action invocation.</p>
+ * <p/>
+ * <p>It will traverse up the class hierarchy looking for validators for
every super class
+ * and directly implemented interface of the current action, as well as
adding validators for
+ * any alias of this invocation. Nifty!</p>
+ * <p/>
+ * <p>Given the following class structure:
+ * <pre>
+ * interface Thing;
+ * interface Animal extends Thing;
+ * interface Quadraped extends Animal;
+ * class AnimalImpl implements Animal;
+ * class QuadrapedImpl extends AnimalImpl implements Quadraped;
+ * class Dog extends QuadrapedImpl;
+ * </pre></p>
+ * <p/>
+ * <p>This method will look for the following config files for Dog:
+ * <pre>
+ * Animal
+ * Animal-context
+ * AnimalImpl
+ * AnimalImpl-context
+ * Quadraped
+ * Quadraped-context
+ * QuadrapedImpl
+ * QuadrapedImpl-context
+ * Dog
+ * Dog-context
+ * </pre></p>
+ * <p/>
+ * <p>Note that the validation rules for Thing is never looked for because
no class in the
+ * hierarchy directly implements Thing.</p>
+ *
+ * @param clazz the Class to look up validators for.
+ * @param context the context to use when looking up validators.
+ * updated.
+ * @return a list of xml configurers for the given class and context.
+ */
+ List<Configurer> getConfigurers(Class clazz, String context);
+}
Modified:
struts/sandbox/trunk/struts2-oval-plugin/src/main/resources/struts-plugin.xml
URL:
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-oval-plugin/src/main/resources/struts-plugin.xml?rev=759802&r1=759801&r2=759802&view=diff
==============================================================================
---
struts/sandbox/trunk/struts2-oval-plugin/src/main/resources/struts-plugin.xml
(original)
+++
struts/sandbox/trunk/struts2-oval-plugin/src/main/resources/struts-plugin.xml
Mon Mar 30 00:15:50 2009
@@ -26,6 +26,8 @@
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
+ <bean type="org.apache.struts2.interceptor.OValValidationManager"
class="org.apache.struts2.interceptor.DefaultOValValidationManager" />
+
<package name="oval-default" extends="struts-default">
<interceptors>
<interceptor name="ovalValidation"
class="org.apache.struts2.interceptor.OValValidationInterceptor" />
Modified:
struts/sandbox/trunk/struts2-oval-plugin/src/test/java/org/apache/struts2/interceptor/OValValidationInterceptorTest.java
URL:
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-oval-plugin/src/test/java/org/apache/struts2/interceptor/OValValidationInterceptorTest.java?rev=759802&r1=759801&r2=759802&view=diff
==============================================================================
---
struts/sandbox/trunk/struts2-oval-plugin/src/test/java/org/apache/struts2/interceptor/OValValidationInterceptorTest.java
(original)
+++
struts/sandbox/trunk/struts2-oval-plugin/src/test/java/org/apache/struts2/interceptor/OValValidationInterceptorTest.java
Mon Mar 30 00:15:50 2009
@@ -30,6 +30,17 @@
import java.util.Map;
public class OValValidationInterceptorTest extends XWorkTestCase {
+ public void testSimpleFieldsXML() throws Exception {
+ ActionProxy baseActionProxy =
actionProxyFactory.createActionProxy("oval", "simpleFieldsXML", null, null);
+ baseActionProxy.execute();
+
+ Map<String, List<String>> fieldErrors = ((ValidationAware)
baseActionProxy.getAction()).getFieldErrors();
+ assertNotNull(fieldErrors);
+ assertEquals(2, fieldErrors.size());
+ assertValue(fieldErrors, "firstName", Arrays.asList("firstName cannot
be null"));
+ assertValue(fieldErrors, "lastName", Arrays.asList("lastName cannot be
empty"));
+ }
+
public void testSimpleField() throws Exception {
ActionProxy baseActionProxy =
actionProxyFactory.createActionProxy("oval", "simpleField", null, null);
baseActionProxy.execute();
Added:
struts/sandbox/trunk/struts2-oval-plugin/src/test/java/org/apache/struts2/interceptor/SimpleFieldsXml.java
URL:
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-oval-plugin/src/test/java/org/apache/struts2/interceptor/SimpleFieldsXml.java?rev=759802&view=auto
==============================================================================
---
struts/sandbox/trunk/struts2-oval-plugin/src/test/java/org/apache/struts2/interceptor/SimpleFieldsXml.java
(added)
+++
struts/sandbox/trunk/struts2-oval-plugin/src/test/java/org/apache/struts2/interceptor/SimpleFieldsXml.java
Mon Mar 30 00:15:50 2009
@@ -0,0 +1,29 @@
+package org.apache.struts2.interceptor;
+
+import com.opensymphony.xwork2.ActionSupport;
+import net.sf.oval.constraint.NotEmpty;
+import net.sf.oval.constraint.NotNull;
+
+public class SimpleFieldsXml extends ActionSupport {
+ @NotNull
+ private String firstName;
+
+ @NotEmpty
+ private String lastName = "";
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+}
Added:
struts/sandbox/trunk/struts2-oval-plugin/src/test/resources/org/apache/struts2/interceptor/SimpleFieldsXml-validation.xml
URL:
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-oval-plugin/src/test/resources/org/apache/struts2/interceptor/SimpleFieldsXml-validation.xml?rev=759802&view=auto
==============================================================================
---
struts/sandbox/trunk/struts2-oval-plugin/src/test/resources/org/apache/struts2/interceptor/SimpleFieldsXml-validation.xml
(added)
+++
struts/sandbox/trunk/struts2-oval-plugin/src/test/resources/org/apache/struts2/interceptor/SimpleFieldsXml-validation.xml
Mon Mar 30 00:15:50 2009
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+<!DOCTYPE oval PUBLIC
+ "-//OVal/OVal Configuration DTD 1.3//EN"
+ "http://oval.sourceforge.net/oval-configuration-1.3.dtd">
+-->
+<oval xmlns="http://oval.sf.net/oval-configuration"
xmlns:xsi="http://http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://oval.sf.net/oval-configuration
http://oval.sourceforge.net/oval-configuration-1.3.xsd"
+>
+ <!-- define a constraint set -->
+ <constraintSet id="firstName">
+ <notNull message="{context} is null" />
+ </constraintSet>
+</oval>
\ No newline at end of file
Modified:
struts/sandbox/trunk/struts2-oval-plugin/src/test/resources/oval-test.xml
URL:
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-oval-plugin/src/test/resources/oval-test.xml?rev=759802&r1=759801&r2=759802&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-oval-plugin/src/test/resources/oval-test.xml
(original)
+++ struts/sandbox/trunk/struts2-oval-plugin/src/test/resources/oval-test.xml
Mon Mar 30 00:15:50 2009
@@ -4,6 +4,7 @@
>
<xwork>
+ <bean type="org.apache.struts2.interceptor.OValValidationManager"
class="org.apache.struts2.interceptor.DefaultOValValidationManager" />
<package namespace="oval" name="oval-test">
<result-types>
<result-type name="void"
class="org.apache.struts2.interceptor.VoidResult"/>
@@ -12,6 +13,10 @@
<interceptor name="ovalValidation"
class="org.apache.struts2.interceptor.OValValidationInterceptor"/>
</interceptors>
+ <action name="simpleFieldsXML"
class="org.apache.struts2.interceptor.SimpleFieldsXml">
+ <interceptor-ref name="ovalValidation"/>
+ <result type="void"></result>
+ </action>
<action name="simpleField"
class="org.apache.struts2.interceptor.SimpleField">
<interceptor-ref name="ovalValidation"/>
<result type="void"></result>