struts-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From lukaszlen...@apache.org
Subject [26/57] [partial] struts git commit: Merges xwork packages into struts
Date Wed, 17 Jun 2015 21:09:26 GMT
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/validator/validators/VisitorFieldValidator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/VisitorFieldValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/VisitorFieldValidator.java
new file mode 100644
index 0000000..e0be5f0
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/VisitorFieldValidator.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright 2002-2006,2009 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.opensymphony.xwork2.validator.validators;
+
+import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.inject.Inject;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.validator.ActionValidatorManager;
+import com.opensymphony.xwork2.validator.DelegatingValidatorContext;
+import com.opensymphony.xwork2.validator.ValidationException;
+import com.opensymphony.xwork2.validator.ValidatorContext;
+
+import java.util.Collection;
+
+
+/**
+ * <!-- START SNIPPET: javadoc -->
+ * The VisitorFieldValidator allows you to forward validation to object
+ * properties of your action using the object's own validation files.  This
+ * allows you to use the ModelDriven development pattern and manage your
+ * validations for your models in one place, where they belong, next to your
+ * model classes.  The VisitorFieldValidator can handle either simple Object
+ * properties, Collections of Objects, or Arrays.
+ * <!-- END SNIPPET: javadoc -->
+ * <p/>
+ *
+ * <!-- START SNIPPET: parameters -->
+ * <ul>
+ * <li>fieldName - field name if plain-validator syntax is used, not needed if field-validator syntax is used</li>
+ * <li>context - the context of which validation should take place. Optional</li>
+ * <li>appendPrefix - the prefix to be added to field. Optional </li>
+ * </ul>
+ * <!-- END SNIPPET: parameters -->
+ *
+ * <pre>
+ * <!-- START SNIPPET: example -->
+ *    &lt;validators&gt;
+ *        &lt;!-- Plain Validator Syntax --&gt;
+ *        &lt;validator type="visitor"&gt;
+ *            &lt;param name="fieldName"&gt;user&lt;/param&gt;
+ *            &lt;param name="context"&gt;myContext&lt;/param&gt;
+ *            &lt;param name="appendPrefix"&gt;true&lt;/param&gt;
+ *        &lt;/validator&gt;
+ *
+ *        &lt;!-- Field Validator Syntax --&gt;
+ *        &lt;field name="user"&gt;
+ *           &lt;field-validator type="visitor"&gt;
+ *              &lt;param name="context"&gt;myContext&lt;/param&gt;
+ *              &lt;param name="appendPrefix"&gt;true&lt;/param&gt;
+ *           &lt;/field-validator&gt;
+ *        &lt;/field&gt;
+ *    &lt;/validators&gt;
+ * <!-- END SNIPPET: example -->
+ * </pre>
+ *
+ * <!-- START SNIPPET: explanation -->
+ * <p>In the example above, if the acion's getUser() method return User object, XWork
+ * will look for User-myContext-validation.xml for the validators. Since appednPrefix is true,
+ * every field name will be prefixed with 'user' such that if the actual field name for 'name' is
+ * 'user.name' </p>
+ * <!-- END SNIPPET: explanation -->
+ *
+ * @author Jason Carreira
+ * @author Rainer Hermanns
+ * @version $Date$ $Id$
+ */
+public class VisitorFieldValidator extends FieldValidatorSupport {
+
+    private String context;
+    private boolean appendPrefix = true;
+    private ActionValidatorManager actionValidatorManager;
+
+
+    @Inject
+    public void setActionValidatorManager(ActionValidatorManager mgr) {
+        this.actionValidatorManager = mgr;
+    }
+
+    /**
+     * Sets whether the field name of this field validator should be prepended to the field name of
+     * the visited field to determine the full field name when an error occurs.  The default is
+     * true.
+     */
+    public void setAppendPrefix(boolean appendPrefix) {
+        this.appendPrefix = appendPrefix;
+    }
+
+    /**
+     * Flags whether the field name of this field validator should be prepended to the field name of
+     * the visited field to determine the full field name when an error occurs.  The default is
+     * true.
+     */
+    public boolean isAppendPrefix() {
+        return appendPrefix;
+    }
+
+    public void setContext(String context) {
+        this.context = context;
+    }
+
+    public String getContext() {
+        return context;
+    }
+
+    public void validate(Object object) throws ValidationException {
+        String fieldName = getFieldName();
+        Object value = this.getFieldValue(fieldName, object);
+        if (value == null) {
+            log.warn("The visited object is null, VisitorValidator will not be able to handle validation properly. Please make sure the visited object is not null for VisitorValidator to function properly");
+            return;
+        }
+        ValueStack stack = ActionContext.getContext().getValueStack();
+
+        stack.push(object);
+
+        String visitorContext = (context == null) ? ActionContext.getContext().getName() : context;
+
+        if (value instanceof Collection) {
+            Collection coll = (Collection) value;
+            Object[] array = coll.toArray();
+
+            validateArrayElements(array, fieldName, visitorContext);
+        } else if (value instanceof Object[]) {
+            Object[] array = (Object[]) value;
+
+            validateArrayElements(array, fieldName, visitorContext);
+        } else {
+            validateObject(fieldName, value, visitorContext);
+        }
+
+        stack.pop();
+    }
+
+    private void validateArrayElements(Object[] array, String fieldName, String visitorContext) throws ValidationException {
+        if (array == null) {
+            return;
+        }
+
+        for (int i = 0; i < array.length; i++) {
+            Object o = array[i];
+            if (o != null) {
+                validateObject(fieldName + "[" + i + "]", o, visitorContext);
+            }
+        }
+    }
+
+    private void validateObject(String fieldName, Object o, String visitorContext) throws ValidationException {
+        ValueStack stack = ActionContext.getContext().getValueStack();
+        stack.push(o);
+
+        ValidatorContext validatorContext;
+
+        if (appendPrefix) {
+            validatorContext = new AppendingValidatorContext(getValidatorContext(), o, fieldName, getMessage(o));
+        } else {
+            ValidatorContext parent = getValidatorContext();
+            validatorContext = new DelegatingValidatorContext(parent, DelegatingValidatorContext.makeTextProvider(o, parent), parent);
+        }
+
+        actionValidatorManager.validate(o, visitorContext, validatorContext);
+        stack.pop();
+    }
+
+
+    public static class AppendingValidatorContext extends DelegatingValidatorContext {
+        private String field;
+        private String message;
+        private ValidatorContext parent;
+
+        public AppendingValidatorContext(ValidatorContext parent, Object object, String field, String message) {
+            super(parent, makeTextProvider(object, parent), parent);
+
+            this.field = field;
+            this.message = message;
+            this.parent = parent;
+        }
+
+        /**
+         * Translates a simple field name into a full field name in Ognl syntax
+         *
+         * @param fieldName field name in OGNL syntax
+         * @return full field name in OGNL syntax
+         */
+        @Override
+        public String getFullFieldName(String fieldName) {
+            if (parent instanceof VisitorFieldValidator.AppendingValidatorContext) {
+                return parent.getFullFieldName(field + "." + fieldName);
+            }
+            return field + "." + fieldName;
+        }
+
+        public String getFieldNameWithField(String fieldName) {
+            return field + "." + fieldName;
+        }
+
+        @Override
+        public void addActionError(String anErrorMessage) {
+            super.addFieldError(getFieldNameWithField(field), message + anErrorMessage);
+        }
+
+        @Override
+        public void addFieldError(String fieldName, String errorMessage) {
+            super.addFieldError(getFieldNameWithField(fieldName), message + errorMessage);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/validator/validators/package.html
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/package.html b/core/src/main/java/com/opensymphony/xwork2/validator/validators/package.html
new file mode 100644
index 0000000..8b34399
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/package.html
@@ -0,0 +1 @@
+<body>XWork default validator classes.</body>

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/resources/com/opensymphony/xwork2/validator/validators/default.xml
----------------------------------------------------------------------
diff --git a/core/src/main/resources/com/opensymphony/xwork2/validator/validators/default.xml b/core/src/main/resources/com/opensymphony/xwork2/validator/validators/default.xml
new file mode 100644
index 0000000..fa8e742
--- /dev/null
+++ b/core/src/main/resources/com/opensymphony/xwork2/validator/validators/default.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE validators PUBLIC
+        "-//Apache Struts//XWork Validator Definition 1.0//EN"
+        "http://struts.apache.org/dtds/xwork-validator-definition-1.0.dtd">
+
+<!-- START SNIPPET: validators-default -->
+<validators>
+    <validator name="required" class="com.opensymphony.xwork2.validator.validators.RequiredFieldValidator"/>
+    <validator name="requiredstring" class="com.opensymphony.xwork2.validator.validators.RequiredStringValidator"/>
+    <validator name="int" class="com.opensymphony.xwork2.validator.validators.IntRangeFieldValidator"/>
+    <validator name="long" class="com.opensymphony.xwork2.validator.validators.LongRangeFieldValidator"/>
+    <validator name="short" class="com.opensymphony.xwork2.validator.validators.ShortRangeFieldValidator"/>
+    <validator name="double" class="com.opensymphony.xwork2.validator.validators.DoubleRangeFieldValidator"/>
+    <validator name="date" class="com.opensymphony.xwork2.validator.validators.DateRangeFieldValidator"/>
+    <validator name="expression" class="com.opensymphony.xwork2.validator.validators.ExpressionValidator"/>
+    <validator name="fieldexpression" class="com.opensymphony.xwork2.validator.validators.FieldExpressionValidator"/>
+    <validator name="email" class="com.opensymphony.xwork2.validator.validators.EmailValidator"/>
+    <validator name="url" class="com.opensymphony.xwork2.validator.validators.URLValidator"/>
+    <validator name="visitor" class="com.opensymphony.xwork2.validator.validators.VisitorFieldValidator"/>
+    <validator name="conversion" class="com.opensymphony.xwork2.validator.validators.ConversionErrorFieldValidator"/>
+    <validator name="stringlength" class="com.opensymphony.xwork2.validator.validators.StringLengthFieldValidator"/>
+    <validator name="regex" class="com.opensymphony.xwork2.validator.validators.RegexFieldValidator"/>
+    <validator name="conditionalvisitor" class="com.opensymphony.xwork2.validator.validators.ConditionalVisitorFieldValidator"/>
+</validators>
+<!--  END SNIPPET: validators-default -->

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/resources/com/opensymphony/xwork2/xwork-messages.properties
----------------------------------------------------------------------
diff --git a/core/src/main/resources/com/opensymphony/xwork2/xwork-messages.properties b/core/src/main/resources/com/opensymphony/xwork2/xwork-messages.properties
new file mode 100644
index 0000000..6068879
--- /dev/null
+++ b/core/src/main/resources/com/opensymphony/xwork2/xwork-messages.properties
@@ -0,0 +1,10 @@
+#
+# Copyright (c) 2002-2006 by OpenSymphony
+# All rights reserved.
+#
+
+xwork.error.action.execution=Error during Action invocation
+xwork.exception.missing-action=There is no Action mapped for action name {0}.
+xwork.exception.missing-package-action=There is no Action mapped for namespace {0} and action name {1}.
+xwork.default.invalid.fieldvalue=Invalid field value for field "{0}".
+

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/resources/xwork-1.0.dtd
----------------------------------------------------------------------
diff --git a/core/src/main/resources/xwork-1.0.dtd b/core/src/main/resources/xwork-1.0.dtd
new file mode 100644
index 0000000..0ab3cd5
--- /dev/null
+++ b/core/src/main/resources/xwork-1.0.dtd
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+   XWork Configuraion DTD.
+   Use the following DOCTYPE.
+   
+   <!DOCTYPE xwork PUBLIC 
+		"-//Apache Struts//XWork 1.0//EN"
+		"http://struts.apache.org/dtds/xwork-1.0.dtd">
+-->
+
+<!ELEMENT xwork (package|include)*>
+
+<!ELEMENT package (result-types?, interceptors?, default-interceptor-ref?, global-results?, action*)>
+<!ATTLIST package
+    name CDATA #REQUIRED
+    extends CDATA #IMPLIED
+    namespace CDATA #IMPLIED
+    abstract CDATA #IMPLIED
+    externalReferenceResolver NMTOKEN #IMPLIED
+>
+
+<!ELEMENT result-types (result-type+)>
+
+<!ELEMENT result-type (param*)>
+<!ATTLIST result-type
+    name CDATA #REQUIRED
+    class CDATA #REQUIRED
+    default (true|false) "false"
+>
+
+<!ELEMENT interceptors (interceptor|interceptor-stack)+>
+
+<!ELEMENT interceptor (param*)>
+<!ATTLIST interceptor
+    name CDATA #REQUIRED
+    class CDATA #REQUIRED
+>
+
+<!ELEMENT interceptor-stack (interceptor-ref+)>
+<!ATTLIST interceptor-stack
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT interceptor-ref (param*)>
+<!ATTLIST interceptor-ref
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT default-interceptor-ref (param*)>
+<!ATTLIST default-interceptor-ref
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT external-ref (#PCDATA)>
+<!ATTLIST external-ref
+    name NMTOKEN #REQUIRED
+    required (true|false) "true"
+>
+
+<!ELEMENT global-results (result+)>
+
+<!ELEMENT action (param|result|interceptor-ref|external-ref)*>
+<!ATTLIST action
+name CDATA #REQUIRED
+    class CDATA #REQUIRED
+    method CDATA #IMPLIED
+    converter CDATA #IMPLIED
+>
+
+<!ELEMENT param (#PCDATA)>
+<!ATTLIST param
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT result (#PCDATA|param)*>
+<!ATTLIST result
+    name CDATA #REQUIRED
+    type CDATA #IMPLIED
+>
+
+<!ELEMENT include (#PCDATA)>
+<!ATTLIST include
+    file CDATA #REQUIRED
+>
+
+

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/resources/xwork-1.1.1.dtd
----------------------------------------------------------------------
diff --git a/core/src/main/resources/xwork-1.1.1.dtd b/core/src/main/resources/xwork-1.1.1.dtd
new file mode 100644
index 0000000..973719e
--- /dev/null
+++ b/core/src/main/resources/xwork-1.1.1.dtd
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- START SNIPPET: xworkDtd -->
+
+<!--
+   XWork configuration DTD.
+   Use the following DOCTYPE
+   
+   <!DOCTYPE xwork PUBLIC 
+		"-//Apache Struts//XWork 1.0//EN"
+		"http://struts.apache.org/dtds/xwork-1.1.1.dtd">
+-->
+
+<!ELEMENT xwork (package|include)*>
+
+<!ELEMENT package (result-types?, interceptors?, default-interceptor-ref?, default-action-ref?, global-results?, global-exception-mappings?, action*)>
+<!ATTLIST package
+    name CDATA #REQUIRED
+    extends CDATA #IMPLIED
+    namespace CDATA #IMPLIED
+    abstract CDATA #IMPLIED
+    externalReferenceResolver NMTOKEN #IMPLIED
+>
+
+<!ELEMENT result-types (result-type+)>
+
+<!ELEMENT result-type (param*)>
+<!ATTLIST result-type
+    name CDATA #REQUIRED
+    class CDATA #REQUIRED
+    default (true|false) "false"
+>
+
+<!ELEMENT interceptors (interceptor|interceptor-stack)+>
+
+<!ELEMENT interceptor (param*)>
+<!ATTLIST interceptor
+    name CDATA #REQUIRED
+    class CDATA #REQUIRED
+>
+
+<!ELEMENT interceptor-stack (interceptor-ref+)>
+<!ATTLIST interceptor-stack
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT interceptor-ref (param*)>
+<!ATTLIST interceptor-ref
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT default-interceptor-ref (param*)>
+<!ATTLIST default-interceptor-ref
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT default-action-ref (param*)>
+<!ATTLIST default-action-ref
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT external-ref (#PCDATA)>
+<!ATTLIST external-ref
+    name NMTOKEN #REQUIRED
+    required (true|false) "true"
+>
+
+<!ELEMENT global-results (result+)>
+
+<!ELEMENT global-exception-mappings (exception-mapping+)>
+
+<!ELEMENT action (param|result|interceptor-ref|exception-mapping|external-ref)*>
+<!ATTLIST action
+    name CDATA #REQUIRED
+    class CDATA #IMPLIED
+    method CDATA #IMPLIED
+    converter CDATA #IMPLIED
+>
+
+<!ELEMENT param (#PCDATA)>
+<!ATTLIST param
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT result (#PCDATA|param)*>
+<!ATTLIST result
+    name CDATA #IMPLIED
+    type CDATA #IMPLIED
+>
+
+<!ELEMENT exception-mapping (#PCDATA|param)*>
+<!ATTLIST exception-mapping
+    name CDATA #IMPLIED
+    exception CDATA #REQUIRED
+    result CDATA #REQUIRED
+>
+
+<!ELEMENT include (#PCDATA)>
+<!ATTLIST include
+    file CDATA #REQUIRED
+>
+
+<!-- END SNIPPET: xworkDtd -->
+

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/resources/xwork-1.1.2.dtd
----------------------------------------------------------------------
diff --git a/core/src/main/resources/xwork-1.1.2.dtd b/core/src/main/resources/xwork-1.1.2.dtd
new file mode 100644
index 0000000..019f697
--- /dev/null
+++ b/core/src/main/resources/xwork-1.1.2.dtd
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- START SNIPPET: xworkDtd -->
+
+<!--
+   XWork configuration DTD.
+   Use the following DOCTYPE
+
+   <!DOCTYPE xwork PUBLIC
+		"-//Apache Struts//XWork 1.0//EN"
+		"http://struts.apache.org/dtds/xwork-1.1.2.dtd">
+-->
+
+<!ELEMENT xwork (parameters?, (package|include)*)>
+
+<!ELEMENT parameters (parameter*)>
+
+<!ELEMENT parameter (#PCDATA)>
+<!ATTLIST parameter
+    name CDATA #REQUIRED
+    value CDATA #REQUIRED
+>
+
+<!ELEMENT package (result-types?, interceptors?, default-interceptor-ref?, default-action-ref?, global-results?, global-exception-mappings?, action*)>
+<!ATTLIST package
+    name CDATA #REQUIRED
+    extends CDATA #IMPLIED
+    namespace CDATA #IMPLIED
+    abstract CDATA #IMPLIED
+    externalReferenceResolver NMTOKEN #IMPLIED
+>
+
+<!ELEMENT result-types (result-type+)>
+
+<!ELEMENT result-type (param*)>
+<!ATTLIST result-type
+    name CDATA #REQUIRED
+    class CDATA #REQUIRED
+    default (true|false) "false"
+>
+
+<!ELEMENT interceptors (interceptor|interceptor-stack)+>
+
+<!ELEMENT interceptor (param*)>
+<!ATTLIST interceptor
+    name CDATA #REQUIRED
+    class CDATA #REQUIRED
+>
+
+<!ELEMENT interceptor-stack (interceptor-ref+)>
+<!ATTLIST interceptor-stack
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT interceptor-ref (param*)>
+<!ATTLIST interceptor-ref
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT default-interceptor-ref (param*)>
+<!ATTLIST default-interceptor-ref
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT default-action-ref (param*)>
+<!ATTLIST default-action-ref
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT external-ref (#PCDATA)>
+<!ATTLIST external-ref
+    name NMTOKEN #REQUIRED
+    required (true|false) "true"
+>
+
+<!ELEMENT global-results (result+)>
+
+<!ELEMENT global-exception-mappings (exception-mapping+)>
+
+<!ELEMENT action (param|result|interceptor-ref|exception-mapping|external-ref)*>
+<!ATTLIST action
+    name CDATA #REQUIRED
+    class CDATA #IMPLIED
+    method CDATA #IMPLIED
+    converter CDATA #IMPLIED
+>
+
+<!ELEMENT param (#PCDATA)>
+<!ATTLIST param
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT result (#PCDATA|param)*>
+<!ATTLIST result
+    name CDATA #IMPLIED
+    type CDATA #IMPLIED
+>
+
+<!ELEMENT exception-mapping (#PCDATA|param)*>
+<!ATTLIST exception-mapping
+    name CDATA #IMPLIED
+    exception CDATA #REQUIRED
+    result CDATA #REQUIRED
+>
+
+<!ELEMENT include (#PCDATA)>
+<!ATTLIST include
+    file CDATA #REQUIRED
+>
+
+<!-- END SNIPPET: xworkDtd -->
+

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/resources/xwork-1.1.dtd
----------------------------------------------------------------------
diff --git a/core/src/main/resources/xwork-1.1.dtd b/core/src/main/resources/xwork-1.1.dtd
new file mode 100644
index 0000000..039328d
--- /dev/null
+++ b/core/src/main/resources/xwork-1.1.dtd
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+   XWork configuration DTD.
+   Use the following DOCTYPE
+   
+   <!DOCTYPE xwork PUBLIC 
+		"-//Apache Struts//XWork 1.0//EN"
+		"http://struts.apache.org/dtds/xwork-1.1.dtd">
+-->
+
+<!ELEMENT xwork (package|include)*>
+
+<!ELEMENT package (result-types?, interceptors?, default-interceptor-ref?, global-results?, global-exception-mappings?, action*)>
+<!ATTLIST package
+    name CDATA #REQUIRED
+    extends CDATA #IMPLIED
+    namespace CDATA #IMPLIED
+    abstract CDATA #IMPLIED
+    externalReferenceResolver NMTOKEN #IMPLIED
+>
+
+<!ELEMENT result-types (result-type+)>
+
+<!ELEMENT result-type (param*)>
+<!ATTLIST result-type
+    name CDATA #REQUIRED
+    class CDATA #REQUIRED
+    default (true|false) "false"
+>
+
+<!ELEMENT interceptors (interceptor|interceptor-stack)+>
+
+<!ELEMENT interceptor (param*)>
+<!ATTLIST interceptor
+    name CDATA #REQUIRED
+    class CDATA #REQUIRED
+>
+
+<!ELEMENT interceptor-stack (interceptor-ref+)>
+<!ATTLIST interceptor-stack
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT interceptor-ref (param*)>
+<!ATTLIST interceptor-ref
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT default-interceptor-ref (param*)>
+<!ATTLIST default-interceptor-ref
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT external-ref (#PCDATA)>
+<!ATTLIST external-ref
+    name NMTOKEN #REQUIRED
+    required (true|false) "true"
+>
+
+<!ELEMENT global-results (result+)>
+
+<!ELEMENT global-exception-mappings (exception-mapping+)>
+
+<!ELEMENT action (param|result|interceptor-ref|exception-mapping|external-ref)*>
+<!ATTLIST action
+    name CDATA #REQUIRED
+    class CDATA #IMPLIED
+    method CDATA #IMPLIED
+    converter CDATA #IMPLIED
+>
+
+<!ELEMENT param (#PCDATA)>
+<!ATTLIST param
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT result (#PCDATA|param)*>
+<!ATTLIST result
+    name CDATA #IMPLIED
+    type CDATA #IMPLIED
+>
+
+<!ELEMENT exception-mapping (#PCDATA|param)*>
+<!ATTLIST exception-mapping
+    name CDATA #IMPLIED
+    exception CDATA #REQUIRED
+    result CDATA #REQUIRED
+>
+
+<!ELEMENT include (#PCDATA)>
+<!ATTLIST include
+    file CDATA #REQUIRED
+>
+
+

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/resources/xwork-2.0.dtd
----------------------------------------------------------------------
diff --git a/core/src/main/resources/xwork-2.0.dtd b/core/src/main/resources/xwork-2.0.dtd
new file mode 100644
index 0000000..e095e26
--- /dev/null
+++ b/core/src/main/resources/xwork-2.0.dtd
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- START SNIPPET: xworkDtd -->
+
+<!--
+   XWork configuration DTD.
+   Use the following DOCTYPE
+   
+   <!DOCTYPE xwork PUBLIC 
+	"-//Apache Struts//XWork 2.0//EN"
+	"http://struts.apache.org/dtds/xwork-2.0.dtd">
+-->
+
+<!ELEMENT xwork (package|include|bean|constant)*>
+
+<!ELEMENT package (result-types?, interceptors?, default-interceptor-ref?, default-action-ref?, default-class-ref?, global-results?, global-exception-mappings?, action*)>
+<!ATTLIST package
+    name CDATA #REQUIRED
+    extends CDATA #IMPLIED
+    namespace CDATA #IMPLIED
+    abstract CDATA #IMPLIED
+>
+
+<!ELEMENT result-types (result-type+)>
+
+<!ELEMENT result-type (param*)>
+<!ATTLIST result-type
+    name CDATA #REQUIRED
+    class CDATA #REQUIRED
+    default (true|false) "false"
+>
+
+<!ELEMENT interceptors (interceptor|interceptor-stack)+>
+
+<!ELEMENT interceptor (param*)>
+<!ATTLIST interceptor
+    name CDATA #REQUIRED
+    class CDATA #REQUIRED
+>
+
+<!ELEMENT interceptor-stack (interceptor-ref*)>
+<!ATTLIST interceptor-stack
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT interceptor-ref (param*)>
+<!ATTLIST interceptor-ref
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT default-interceptor-ref (#PCDATA)>
+<!ATTLIST default-interceptor-ref
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT default-action-ref (#PCDATA)>
+<!ATTLIST default-action-ref
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT default-class-ref (#PCDATA)>
+<!ATTLIST default-class-ref
+   class CDATA #REQUIRED
+>
+
+<!ELEMENT global-results (result+)>
+
+<!ELEMENT global-exception-mappings (exception-mapping+)>
+
+<!ELEMENT action (param|result|interceptor-ref|exception-mapping)*>
+<!ATTLIST action
+    name CDATA #REQUIRED
+    class CDATA #IMPLIED
+    method CDATA #IMPLIED
+    converter CDATA #IMPLIED
+>
+
+<!ELEMENT param (#PCDATA)>
+<!ATTLIST param
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT result (#PCDATA|param)*>
+<!ATTLIST result
+    name CDATA #IMPLIED
+    type CDATA #IMPLIED
+>
+
+<!ELEMENT exception-mapping (#PCDATA|param)*>
+<!ATTLIST exception-mapping
+    name CDATA #IMPLIED
+    exception CDATA #REQUIRED
+    result CDATA #REQUIRED
+>
+
+<!ELEMENT include (#PCDATA)>
+<!ATTLIST include
+    file CDATA #REQUIRED
+>
+
+<!ELEMENT bean (#PCDATA)>
+<!ATTLIST bean
+    type CDATA #IMPLIED
+    name CDATA #IMPLIED
+    class CDATA #REQUIRED
+    scope CDATA #IMPLIED
+    static CDATA #IMPLIED
+    optional CDATA #IMPLIED
+>
+
+<!ELEMENT constant (#PCDATA)>
+<!ATTLIST constant
+    name CDATA #REQUIRED
+    value CDATA #REQUIRED    
+>
+
+<!-- END SNIPPET: xworkDtd -->
+

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/resources/xwork-2.1.3.dtd
----------------------------------------------------------------------
diff --git a/core/src/main/resources/xwork-2.1.3.dtd b/core/src/main/resources/xwork-2.1.3.dtd
new file mode 100644
index 0000000..6893f97
--- /dev/null
+++ b/core/src/main/resources/xwork-2.1.3.dtd
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- START SNIPPET: xworkDtd -->
+
+<!--
+   XWork configuration DTD.
+   Use the following DOCTYPE
+
+   <!DOCTYPE xwork PUBLIC
+	"-//Apache Struts//XWork 2.1.3//EN"
+	"http://struts.apache.org/dtds/xwork-2.1.3.dtd">
+-->
+
+<!ELEMENT xwork ((package|include|bean|constant)*, unknown-handler-stack?)>
+<!ATTLIST xwork
+    order CDATA #IMPLIED
+>
+
+<!ELEMENT package (result-types?, interceptors?, default-interceptor-ref?, default-action-ref?, default-class-ref?, global-results?, global-exception-mappings?, action*)>
+<!ATTLIST package
+    name CDATA #REQUIRED
+    extends CDATA #IMPLIED
+    namespace CDATA #IMPLIED
+    abstract CDATA #IMPLIED
+>
+
+<!ELEMENT result-types (result-type+)>
+
+<!ELEMENT result-type (param*)>
+<!ATTLIST result-type
+    name CDATA #REQUIRED
+    class CDATA #REQUIRED
+    default (true|false) "false"
+>
+
+<!ELEMENT interceptors (interceptor|interceptor-stack)+>
+
+<!ELEMENT interceptor (param*)>
+<!ATTLIST interceptor
+    name CDATA #REQUIRED
+    class CDATA #REQUIRED
+>
+
+<!ELEMENT interceptor-stack (interceptor-ref*)>
+<!ATTLIST interceptor-stack
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT interceptor-ref (param*)>
+<!ATTLIST interceptor-ref
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT default-interceptor-ref (#PCDATA)>
+<!ATTLIST default-interceptor-ref
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT default-action-ref (#PCDATA)>
+<!ATTLIST default-action-ref
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT default-class-ref (#PCDATA)>
+<!ATTLIST default-class-ref
+   class CDATA #REQUIRED
+>
+
+<!ELEMENT global-results (result+)>
+
+<!ELEMENT global-exception-mappings (exception-mapping+)>
+
+<!ELEMENT action (param|result|interceptor-ref|exception-mapping)*>
+<!ATTLIST action
+    name CDATA #REQUIRED
+    class CDATA #IMPLIED
+    method CDATA #IMPLIED
+    converter CDATA #IMPLIED
+>
+
+<!ELEMENT param (#PCDATA)>
+<!ATTLIST param
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT result (#PCDATA|param)*>
+<!ATTLIST result
+    name CDATA #IMPLIED
+    type CDATA #IMPLIED
+>
+
+<!ELEMENT exception-mapping (#PCDATA|param)*>
+<!ATTLIST exception-mapping
+    name CDATA #IMPLIED
+    exception CDATA #REQUIRED
+    result CDATA #REQUIRED
+>
+
+<!ELEMENT include (#PCDATA)>
+<!ATTLIST include
+    file CDATA #REQUIRED
+>
+
+<!ELEMENT bean (#PCDATA)>
+<!ATTLIST bean
+    type CDATA #IMPLIED
+    name CDATA #IMPLIED
+    class CDATA #REQUIRED
+    scope CDATA #IMPLIED
+    static CDATA #IMPLIED
+    optional CDATA #IMPLIED
+>
+
+<!ELEMENT constant (#PCDATA)>
+<!ATTLIST constant
+    name CDATA #REQUIRED
+    value CDATA #REQUIRED
+>
+
+<!ELEMENT unknown-handler-stack (unknown-handler-ref*)>
+<!ELEMENT unknown-handler-ref (#PCDATA)>
+<!ATTLIST unknown-handler-ref
+    name CDATA #REQUIRED
+>
+
+<!-- END SNIPPET: xworkDtd -->
+

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/resources/xwork-2.1.dtd
----------------------------------------------------------------------
diff --git a/core/src/main/resources/xwork-2.1.dtd b/core/src/main/resources/xwork-2.1.dtd
new file mode 100644
index 0000000..a003753
--- /dev/null
+++ b/core/src/main/resources/xwork-2.1.dtd
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- START SNIPPET: xworkDtd -->
+
+<!--
+   XWork configuration DTD.
+   Use the following DOCTYPE
+
+   <!DOCTYPE xwork PUBLIC
+	"-//Apache Struts//XWork 2.1//EN"
+	"http://struts.apache.org/dtds/xwork-2.1.dtd">
+-->
+
+<!ELEMENT xwork ((package|include|bean|constant)*, unknown-handler-stack?)>
+
+<!ELEMENT package (result-types?, interceptors?, default-interceptor-ref?, default-action-ref?, default-class-ref?, global-results?, global-exception-mappings?, action*)>
+<!ATTLIST package
+    name CDATA #REQUIRED
+    extends CDATA #IMPLIED
+    namespace CDATA #IMPLIED
+    abstract CDATA #IMPLIED
+>
+
+<!ELEMENT result-types (result-type+)>
+
+<!ELEMENT result-type (param*)>
+<!ATTLIST result-type
+    name CDATA #REQUIRED
+    class CDATA #REQUIRED
+    default (true|false) "false"
+>
+
+<!ELEMENT interceptors (interceptor|interceptor-stack)+>
+
+<!ELEMENT interceptor (param*)>
+<!ATTLIST interceptor
+    name CDATA #REQUIRED
+    class CDATA #REQUIRED
+>
+
+<!ELEMENT interceptor-stack (interceptor-ref*)>
+<!ATTLIST interceptor-stack
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT interceptor-ref (param*)>
+<!ATTLIST interceptor-ref
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT default-interceptor-ref (#PCDATA)>
+<!ATTLIST default-interceptor-ref
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT default-action-ref (#PCDATA)>
+<!ATTLIST default-action-ref
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT default-class-ref (#PCDATA)>
+<!ATTLIST default-class-ref
+   class CDATA #REQUIRED
+>
+
+<!ELEMENT global-results (result+)>
+
+<!ELEMENT global-exception-mappings (exception-mapping+)>
+
+<!ELEMENT action (param|result|interceptor-ref|exception-mapping)*>
+<!ATTLIST action
+    name CDATA #REQUIRED
+    class CDATA #IMPLIED
+    method CDATA #IMPLIED
+    converter CDATA #IMPLIED
+>
+
+<!ELEMENT param (#PCDATA)>
+<!ATTLIST param
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT result (#PCDATA|param)*>
+<!ATTLIST result
+    name CDATA #IMPLIED
+    type CDATA #IMPLIED
+>
+
+<!ELEMENT exception-mapping (#PCDATA|param)*>
+<!ATTLIST exception-mapping
+    name CDATA #IMPLIED
+    exception CDATA #REQUIRED
+    result CDATA #REQUIRED
+>
+
+<!ELEMENT include (#PCDATA)>
+<!ATTLIST include
+    file CDATA #REQUIRED
+>
+
+<!ELEMENT bean (#PCDATA)>
+<!ATTLIST bean
+    type CDATA #IMPLIED
+    name CDATA #IMPLIED
+    class CDATA #REQUIRED
+    scope CDATA #IMPLIED
+    static CDATA #IMPLIED
+    optional CDATA #IMPLIED
+>
+
+<!ELEMENT constant (#PCDATA)>
+<!ATTLIST constant
+    name CDATA #REQUIRED
+    value CDATA #REQUIRED
+>
+
+<!ELEMENT unknown-handler-stack (unknown-handler-ref*)>
+<!ELEMENT unknown-handler-ref (#PCDATA)>
+<!ATTLIST unknown-handler-ref
+    name CDATA #REQUIRED
+>
+
+<!-- END SNIPPET: xworkDtd -->
+

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/resources/xwork-2.3.dtd
----------------------------------------------------------------------
diff --git a/core/src/main/resources/xwork-2.3.dtd b/core/src/main/resources/xwork-2.3.dtd
new file mode 100644
index 0000000..b983ff9
--- /dev/null
+++ b/core/src/main/resources/xwork-2.3.dtd
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- START SNIPPET: xworkDtd -->
+
+<!--
+   XWork configuration DTD.
+   Use the following DOCTYPE
+
+   <!DOCTYPE xwork PUBLIC
+	"-//Apache Struts//XWork 2.3//EN"
+	"http://struts.apache.org/dtds/xwork-2.3.dtd">
+-->
+
+<!ELEMENT xwork ((package|include|bean|constant)*, unknown-handler-stack?)>
+<!ATTLIST xwork
+    order CDATA #IMPLIED
+>
+
+<!ELEMENT package (result-types?, interceptors?, default-interceptor-ref?, default-action-ref?, default-class-ref?, global-results?, global-exception-mappings?, action*)>
+<!ATTLIST package
+    name CDATA #REQUIRED
+    extends CDATA #IMPLIED
+    namespace CDATA #IMPLIED
+    abstract CDATA #IMPLIED
+    strict-method-invocation CDATA #IMPLIED
+>
+
+<!ELEMENT result-types (result-type+)>
+
+<!ELEMENT result-type (param*)>
+<!ATTLIST result-type
+    name CDATA #REQUIRED
+    class CDATA #REQUIRED
+    default (true|false) "false"
+>
+
+<!ELEMENT interceptors (interceptor|interceptor-stack)+>
+
+<!ELEMENT interceptor (param*)>
+<!ATTLIST interceptor
+    name CDATA #REQUIRED
+    class CDATA #REQUIRED
+>
+
+<!ELEMENT interceptor-stack (interceptor-ref*)>
+<!ATTLIST interceptor-stack
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT interceptor-ref (param*)>
+<!ATTLIST interceptor-ref
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT default-interceptor-ref (#PCDATA)>
+<!ATTLIST default-interceptor-ref
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT default-action-ref (#PCDATA)>
+<!ATTLIST default-action-ref
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT default-class-ref (#PCDATA)>
+<!ATTLIST default-class-ref
+   class CDATA #REQUIRED
+>
+
+<!ELEMENT global-results (result+)>
+
+<!ELEMENT global-exception-mappings (exception-mapping+)>
+
+<!ELEMENT action ((param|result|interceptor-ref|exception-mapping)*,allowed-methods?)>
+<!ATTLIST action
+    name CDATA #REQUIRED
+    class CDATA #IMPLIED
+    method CDATA #IMPLIED
+    converter CDATA #IMPLIED
+>
+
+<!ELEMENT param (#PCDATA)>
+<!ATTLIST param
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT result (#PCDATA|param)*>
+<!ATTLIST result
+    name CDATA #IMPLIED
+    type CDATA #IMPLIED
+>
+
+<!ELEMENT exception-mapping (#PCDATA|param)*>
+<!ATTLIST exception-mapping
+    name CDATA #IMPLIED
+    exception CDATA #REQUIRED
+    result CDATA #REQUIRED
+>
+
+<!ELEMENT allowed-methods (#PCDATA)>
+
+<!ELEMENT include (#PCDATA)>
+<!ATTLIST include
+    file CDATA #REQUIRED
+>
+
+<!ELEMENT bean (#PCDATA)>
+<!ATTLIST bean
+    type CDATA #IMPLIED
+    name CDATA #IMPLIED
+    class CDATA #REQUIRED
+    scope CDATA #IMPLIED
+    static CDATA #IMPLIED
+    optional CDATA #IMPLIED
+>
+
+<!ELEMENT constant (#PCDATA)>
+<!ATTLIST constant
+    name CDATA #REQUIRED
+    value CDATA #REQUIRED
+>
+
+<!ELEMENT unknown-handler-stack (unknown-handler-ref*)>
+<!ELEMENT unknown-handler-ref (#PCDATA)>
+<!ATTLIST unknown-handler-ref
+    name CDATA #REQUIRED
+>
+
+<!-- END SNIPPET: xworkDtd -->
+

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/resources/xwork-default.xml
----------------------------------------------------------------------
diff --git a/core/src/main/resources/xwork-default.xml b/core/src/main/resources/xwork-default.xml
new file mode 100644
index 0000000..dba9d68
--- /dev/null
+++ b/core/src/main/resources/xwork-default.xml
@@ -0,0 +1,67 @@
+<!DOCTYPE xwork PUBLIC
+        "-//Apache Struts//XWork 2.0//EN"
+        "http://struts.apache.org/dtds/xwork-2.0.dtd">
+
+<xwork>
+    <package name="xwork-default" abstract="true">
+
+        <!-- START SNIPPET: xwork2-default-result-types -->
+        <result-types>
+            <result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>
+        </result-types>
+
+        <!-- END SNIPPET: xwork2-default-result-types -->
+
+        <interceptors>
+            <!-- START SNIPPET: xwork2-default-interceptors -->
+
+            <interceptor name="timer" class="com.opensymphony.xwork2.interceptor.TimerInterceptor"/>
+            <interceptor name="logger" class="com.opensymphony.xwork2.interceptor.LoggingInterceptor"/>
+            <interceptor name="chain" class="com.opensymphony.xwork2.interceptor.ChainingInterceptor"/>
+            <interceptor name="staticParams" class="com.opensymphony.xwork2.interceptor.StaticParametersInterceptor"/>
+            <interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>
+            <interceptor name="filterParams" class="com.opensymphony.xwork2.interceptor.ParameterFilterInterceptor"/>
+            <interceptor name="removeParams" class="com.opensymphony.xwork2.interceptor.ParameterRemoverInterceptor"/>
+            <interceptor name="modelDriven" class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/>
+            <interceptor name="scopedModelDriven"
+                         class="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor"/>
+            <interceptor name="validation" class="com.opensymphony.xwork2.validator.ValidationInterceptor"/>
+            <interceptor name="workflow" class="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor"/>
+            <interceptor name="prepare" class="com.opensymphony.xwork2.interceptor.PrepareInterceptor"/>
+            <interceptor name="conversionError" class="com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor"/>
+            <interceptor name="alias" class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/>
+            <interceptor name="exception" class="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor"/>
+            <interceptor name="i18n" class="com.opensymphony.xwork2.interceptor.I18nInterceptor"/>
+
+            <!-- END SNIPPET: xwork2-default-interceptors -->
+
+            <!--interceptor name="static-params" class="com.opensymphony.xwork2.interceptor.StaticParametersInterceptor"/>
+            <interceptor name="filter-params" class="com.opensymphony.xwork2.interceptor.ParameterFilterInterceptor"/>
+            <interceptor name="remove-params" class="com.opensymphony.xwork2.interceptor.ParameterRemoverInterceptor"/>
+            <interceptor name="model-driven" class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/>
+            <interceptor name="scoped-model-driven"
+                         class="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor"/-->
+
+            <!-- START SNIPPET: xwork2-default-interceptor-stack -->
+
+            <interceptor-stack name="emptyStack"/>
+
+            <interceptor-stack name="defaultStack">
+                <interceptor-ref name="staticParams"/>
+                <interceptor-ref name="params"/>
+                <interceptor-ref name="conversionError"/>
+            </interceptor-stack>
+            <interceptor-stack name="validationWorkflowStack">
+                <interceptor-ref name="defaultStack"/>
+                <interceptor-ref name="validation"/>
+                <interceptor-ref name="workflow"/>
+            </interceptor-stack>
+
+            <!-- END SNIPPET: xwork2-default-interceptor-stack -->
+
+        </interceptors>
+
+        <default-class-ref class="com.opensymphony.xwork2.ActionSupport"/>
+
+    </package>
+</xwork>

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/resources/xwork-validator-1.0.2.dtd
----------------------------------------------------------------------
diff --git a/core/src/main/resources/xwork-validator-1.0.2.dtd b/core/src/main/resources/xwork-validator-1.0.2.dtd
new file mode 100644
index 0000000..a697a13
--- /dev/null
+++ b/core/src/main/resources/xwork-validator-1.0.2.dtd
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  XWork Validators DTD.
+  Used the following DOCTYPE.
+  
+  <!DOCTYPE validators PUBLIC 
+  		"-//Apache Struts//XWork Validator 1.0.2//EN"
+  		"http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
+-->
+
+
+<!ELEMENT validators (field|validator)+>
+
+<!ELEMENT field (field-validator+)>
+<!ATTLIST field
+	name CDATA #REQUIRED
+>
+
+<!ELEMENT field-validator (param*, message)>
+<!ATTLIST field-validator
+	type CDATA #REQUIRED
+    short-circuit (true|false) "false"
+>
+
+<!ELEMENT validator (param*, message)>
+<!ATTLIST validator
+	type CDATA #REQUIRED
+    short-circuit (true|false) "false"
+>
+
+<!ELEMENT param (#PCDATA)>
+<!ATTLIST param
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT message (#PCDATA)>
+<!ATTLIST message
+    key CDATA #IMPLIED
+>
+
+

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/resources/xwork-validator-1.0.3.dtd
----------------------------------------------------------------------
diff --git a/core/src/main/resources/xwork-validator-1.0.3.dtd b/core/src/main/resources/xwork-validator-1.0.3.dtd
new file mode 100644
index 0000000..e474b65
--- /dev/null
+++ b/core/src/main/resources/xwork-validator-1.0.3.dtd
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  XWork Validators DTD.
+  Used the following DOCTYPE.
+
+  <!DOCTYPE validators PUBLIC
+  		"-//Apache Struts//XWork Validator 1.0.3//EN"
+  		"http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
+-->
+
+
+<!ELEMENT validators (field|validator)+>
+
+<!ELEMENT field (field-validator+)>
+<!ATTLIST field
+	name CDATA #REQUIRED
+>
+
+<!ELEMENT field-validator (param*, message)>
+<!ATTLIST field-validator
+	type CDATA #REQUIRED
+    short-circuit (true|false) "false"
+>
+
+<!ELEMENT validator (param*, message)>
+<!ATTLIST validator
+	type CDATA #REQUIRED
+    short-circuit (true|false) "false"
+>
+
+<!ELEMENT param (#PCDATA)>
+<!ATTLIST param
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT message (#PCDATA|param)*>
+<!ATTLIST message
+    key CDATA #IMPLIED
+>
+
+

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/resources/xwork-validator-1.0.dtd
----------------------------------------------------------------------
diff --git a/core/src/main/resources/xwork-validator-1.0.dtd b/core/src/main/resources/xwork-validator-1.0.dtd
new file mode 100644
index 0000000..4f5600b
--- /dev/null
+++ b/core/src/main/resources/xwork-validator-1.0.dtd
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  XWork Validators DTD.
+  Used the following DOCTYPE.
+  
+  <!DOCTYPE validators PUBLIC 
+  		"-//Apache Struts//XWork Validator 1.0//EN"
+  		"http://struts.apache.org/dtds/xwork-validator-1.0.dtd">
+-->
+
+
+<!ELEMENT validators (field*,validator*)>
+
+<!ELEMENT field (field-validator+)>
+<!ATTLIST field
+	name CDATA #REQUIRED
+>
+
+<!ELEMENT field-validator (param*, message)>
+<!ATTLIST field-validator
+	type CDATA #REQUIRED
+>
+
+<!ELEMENT validator (param*, message)>
+<!ATTLIST validator
+	type CDATA #REQUIRED
+>
+
+<!ELEMENT param (#PCDATA)>
+<!ATTLIST param
+    name CDATA #REQUIRED
+>
+
+<!ELEMENT message (#PCDATA)>
+<!ATTLIST message
+    key CDATA #IMPLIED
+>
+
+

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/resources/xwork-validator-config-1.0.dtd
----------------------------------------------------------------------
diff --git a/core/src/main/resources/xwork-validator-config-1.0.dtd b/core/src/main/resources/xwork-validator-config-1.0.dtd
new file mode 100644
index 0000000..d860269
--- /dev/null
+++ b/core/src/main/resources/xwork-validator-config-1.0.dtd
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  XWork Validator Config DTD.
+  Used the following DOCTYPE.
+
+  <!DOCTYPE validators PUBLIC
+  		"-//Apache Struts//XWork Validator Config 1.0//EN"
+  		"http://struts.apache.org/dtds/xwork-validator-config-1.0.dtd">
+-->
+<!ELEMENT validators (validator)+>
+
+<!ELEMENT validator (#PCDATA)>
+<!ATTLIST validator
+	name CDATA #REQUIRED
+    class CDATA #REQUIRED
+>

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/resources/xwork-validator-definition-1.0.dtd
----------------------------------------------------------------------
diff --git a/core/src/main/resources/xwork-validator-definition-1.0.dtd b/core/src/main/resources/xwork-validator-definition-1.0.dtd
new file mode 100644
index 0000000..33b22fb
--- /dev/null
+++ b/core/src/main/resources/xwork-validator-definition-1.0.dtd
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  XWork Validators Definition DTD.
+  Used the following DOCTYPE.
+
+  <!DOCTYPE validators PUBLIC
+  		"-//Apache Struts//XWork Validator Definition 1.0//EN"
+  		"http://struts.apache.org/dtds/xwork-validator-definition-1.0.dtd">
+-->
+
+<!ELEMENT validators (validator*)>
+
+<!ELEMENT validator (#PCDATA)>
+<!ATTLIST validator
+    name CDATA #REQUIRED
+    class CDATA #REQUIRED
+>
+

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/test/java/PackagelessAction.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/PackagelessAction.java b/core/src/test/java/PackagelessAction.java
new file mode 100644
index 0000000..8c792c0
--- /dev/null
+++ b/core/src/test/java/PackagelessAction.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2002-2003,2009 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import com.opensymphony.xwork2.ActionSupport;
+
+
+/**
+ * @author Mark Woon
+ */
+public class PackagelessAction extends ActionSupport {
+
+    /**
+     * Default constructor.
+     */
+    public PackagelessAction() {
+    }
+
+
+    @Override
+    public String execute() {
+        // from action's bundle
+        System.out.println(getText("actionProperty"));
+
+        // from default bundle
+        System.out.println(getText("foo.range"));
+
+        // nonexistant
+        System.out.println(getText("non.existant"));
+
+        return NONE;
+    }
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/test/java/com/opensymphony/xwork2/ActionContextTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/opensymphony/xwork2/ActionContextTest.java b/core/src/test/java/com/opensymphony/xwork2/ActionContextTest.java
new file mode 100644
index 0000000..fb5a538
--- /dev/null
+++ b/core/src/test/java/com/opensymphony/xwork2/ActionContextTest.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2002-2006,2009 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.opensymphony.xwork2;
+
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.util.ValueStackFactory;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ * Unit test for {@link ActionContext}.
+ *
+ * @author Jason Carreira
+ */
+public class ActionContextTest extends XWorkTestCase {
+
+    private static final String APPLICATION_KEY = "com.opensymphony.xwork2.ActionContextTest.application";
+    private static final String SESSION_KEY = "com.opensymphony.xwork2.ActionContextTest.session";
+    private static final String PARAMETERS_KEY = "com.opensymphony.xwork2.ActionContextTest.params";
+    private static final String ACTION_NAME = "com.opensymphony.xwork2.ActionContextTest.actionName";
+
+    private ActionContext context;
+
+    @Override public void setUp() throws Exception {
+        super.setUp();
+        ValueStack valueStack = container.getInstance(ValueStackFactory.class).createValueStack();
+        Map<String, Object> extraContext = valueStack.getContext();
+        Map<String, Object> application = new HashMap<>();
+        application.put(APPLICATION_KEY, APPLICATION_KEY);
+
+        Map<String, Object> session = new HashMap<>();
+        session.put(SESSION_KEY, SESSION_KEY);
+
+        Map<String, Object> params = new HashMap<>();
+        params.put(PARAMETERS_KEY, PARAMETERS_KEY);
+        extraContext.put(ActionContext.APPLICATION, application);
+        extraContext.put(ActionContext.SESSION, session);
+        extraContext.put(ActionContext.PARAMETERS, params);
+        extraContext.put(ActionContext.ACTION_NAME, ACTION_NAME);
+        context = new ActionContext(extraContext);
+        ActionContext.setContext(context);
+    }
+
+    public void testContextParams() {
+        assertTrue(ActionContext.getContext().getApplication().containsKey(APPLICATION_KEY));
+        assertTrue(ActionContext.getContext().getSession().containsKey(SESSION_KEY));
+        assertTrue(ActionContext.getContext().getParameters().containsKey(PARAMETERS_KEY));
+        assertEquals(ActionContext.getContext().getName(), ACTION_NAME);
+    }
+
+    public void testGetContext() {
+        ActionContext threadContext = ActionContext.getContext();
+        assertEquals(context, threadContext);
+    }
+
+    public void testNewActionContextCanFindDefaultTexts() {
+        ValueStack valueStack = context.getValueStack();
+        String actionErrorMessage = (String) valueStack.findValue("getText('xwork.error.action.execution')");
+        assertNotNull(actionErrorMessage);
+        assertEquals("Error during Action invocation", actionErrorMessage);
+    }
+
+    public void testApplication() {
+        Map<String, Object> app = new HashMap<>();
+        context.setApplication(app);
+        assertEquals(app, context.getApplication());
+    }
+
+    public void testContextMap() {
+        Map<String, Object> map = new HashMap<>();
+        context.setContextMap(map);
+        assertEquals(map, context.getContextMap());
+    }
+
+    public void testParameters() {
+        Map<String, Object> param = new HashMap<>();
+        context.setParameters(param);
+        assertEquals(param, context.getParameters());
+    }
+
+    public void testConversionErrors() {
+        Map<String, Object> errors = context.getConversionErrors();
+        assertNotNull(errors);
+        assertEquals(0, errors.size());
+
+        Map<String, Object> errors2 = new HashMap<>();
+        context.setConversionErrors(errors);
+        assertEquals(errors2, context.getConversionErrors());
+    }
+
+    public void testStaticMethods() {
+        assertEquals(context, ActionContext.getContext());
+
+        ActionContext context2 = new ActionContext(null);
+        ActionContext.setContext(context2);
+
+        assertEquals(context2, ActionContext.getContext());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/test/java/com/opensymphony/xwork2/ActionContextThreadLocalTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/opensymphony/xwork2/ActionContextThreadLocalTest.java b/core/src/test/java/com/opensymphony/xwork2/ActionContextThreadLocalTest.java
new file mode 100644
index 0000000..d29aa32
--- /dev/null
+++ b/core/src/test/java/com/opensymphony/xwork2/ActionContextThreadLocalTest.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2002-2006,2009 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.opensymphony.xwork2;
+
+import junit.framework.TestCase;
+
+import java.util.HashMap;
+
+
+/**
+ * Simple Test ActionContext's ThreadLocal
+ * 
+ * @author tm_jee
+ * @version $Date$ $Id$
+ */
+public class ActionContextThreadLocalTest extends TestCase {
+
+	
+	public void testGetContext() throws Exception {
+	    ActionContext.setContext(null);
+		assertNull(ActionContext.getContext());
+	}
+	
+	public void testSetContext() throws Exception {
+		ActionContext context = new ActionContext(new HashMap<String, Object>());
+		ActionContext.setContext(context);
+		assertEquals(context, ActionContext.getContext());
+	}
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/test/java/com/opensymphony/xwork2/ActionInvocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/opensymphony/xwork2/ActionInvocationTest.java b/core/src/test/java/com/opensymphony/xwork2/ActionInvocationTest.java
new file mode 100644
index 0000000..58d02dd
--- /dev/null
+++ b/core/src/test/java/com/opensymphony/xwork2/ActionInvocationTest.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2002-2003,2009 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.opensymphony.xwork2;
+
+import com.opensymphony.xwork2.config.entities.ActionConfig;
+import com.opensymphony.xwork2.config.providers.XmlConfigurationProvider;
+
+import java.util.HashMap;
+
+
+/**
+ * @author $Author$
+ * @version $Revision$
+ */
+public class ActionInvocationTest extends XWorkTestCase {
+
+    public void testCommandInvocation() throws Exception {
+        ActionProxy baseActionProxy = actionProxyFactory.createActionProxy(
+                "baz", "commandTest", null, null);
+        assertEquals("success", baseActionProxy.execute());
+
+        ActionProxy commandActionProxy = actionProxyFactory.createActionProxy(
+                "baz", "myCommand", null, null);
+        assertEquals(SimpleAction.COMMAND_RETURN_CODE, commandActionProxy.execute());
+    }
+
+    public void testCommandInvocationDoMethod() throws Exception {
+        ActionProxy baseActionProxy = actionProxyFactory.createActionProxy(
+                "baz", "doMethodTest", null, null);
+        assertEquals("input", baseActionProxy.execute());
+    }
+
+    public void testCommandInvocationUnknownHandler() throws Exception {
+
+        DefaultActionProxy baseActionProxy = (DefaultActionProxy) actionProxyFactory.createActionProxy(
+                "baz", "unknownMethodTest", "unknownmethod", null);
+        UnknownHandler unknownHandler = new UnknownHandler() {
+			public ActionConfig handleUnknownAction(String namespace, String actionName) throws XWorkException { return null;}
+			public Result handleUnknownResult(ActionContext actionContext, String actionName, ActionConfig actionConfig, String resultCode) throws XWorkException {
+				return null;
+			}
+			public Object handleUnknownActionMethod(Object action, String methodName) throws NoSuchMethodException {
+				if (methodName.equals("unknownmethod")) {
+					return "found";
+				} else {
+					return null;
+				}
+			}
+        };
+
+        UnknownHandlerManagerMock uhm = new UnknownHandlerManagerMock();
+        uhm.addUnknownHandler(unknownHandler);
+        ((DefaultActionInvocation)baseActionProxy.getInvocation()).setUnknownHandlerManager(uhm);
+
+        assertEquals("found", baseActionProxy.execute());
+    }
+
+    public void testResultReturnInvocationAndWired() throws Exception {
+        ActionProxy baseActionProxy = actionProxyFactory.createActionProxy(
+                "baz", "resultAction", null, null);
+        assertEquals(null, baseActionProxy.execute());
+        assertTrue(SimpleAction.resultCalled);
+    }
+
+    public void testSimple() {
+        HashMap<String, Object> params = new HashMap<>();
+        params.put("blah", "this is blah");
+
+        HashMap<String, Object> extraContext = new HashMap<>();
+        extraContext.put(ActionContext.PARAMETERS, params);
+
+        try {
+            ActionProxy proxy = actionProxyFactory.createActionProxy( "", "Foo", null, extraContext);
+            proxy.execute();
+            assertEquals("this is blah", proxy.getInvocation().getStack().findValue("[1].blah"));
+        } catch (Exception e) {
+            e.printStackTrace();
+            fail();
+        }
+    }
+
+    @Override protected void setUp() throws Exception {
+        super.setUp();
+
+        // ensure we're using the default configuration, not simple config
+        XmlConfigurationProvider configurationProvider = new XmlConfigurationProvider("xwork-sample.xml");
+        container.inject(configurationProvider);
+        loadConfigurationProviders(configurationProvider);
+    }
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/test/java/com/opensymphony/xwork2/ActionNestingTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/opensymphony/xwork2/ActionNestingTest.java b/core/src/test/java/com/opensymphony/xwork2/ActionNestingTest.java
new file mode 100644
index 0000000..ee996e5
--- /dev/null
+++ b/core/src/test/java/com/opensymphony/xwork2/ActionNestingTest.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2002-2003,2009 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.opensymphony.xwork2;
+
+import com.opensymphony.xwork2.config.Configuration;
+import com.opensymphony.xwork2.config.ConfigurationProvider;
+import com.opensymphony.xwork2.config.entities.ActionConfig;
+import com.opensymphony.xwork2.config.entities.PackageConfig;
+import com.opensymphony.xwork2.config.entities.ResultConfig;
+import com.opensymphony.xwork2.inject.ContainerBuilder;
+import com.opensymphony.xwork2.mock.MockResult;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.util.location.LocatableProperties;
+
+import java.util.HashMap;
+
+
+/**
+ * ActionNestingTest
+ *
+ * @author Jason Carreira
+ *         Created Mar 5, 2003 2:02:01 PM
+ */
+public class ActionNestingTest extends XWorkTestCase {
+
+    public static final String VALUE = "myValue";
+    public static final String NESTED_VALUE = "myNestedValue";
+    public static final String KEY = "myProperty";
+    public static final String NESTED_KEY = "nestedProperty";
+    public static final String NAMESPACE = "NestedActionTest";
+    public static final String SIMPLE_ACTION_NAME = "SimpleAction";
+    public static final String NO_STACK_ACTION_NAME = "NoStackNestedAction";
+    public static final String STACK_ACTION_NAME = "StackNestedAction";
+
+
+    private ActionContext context;
+
+
+    public String getMyProperty() {
+        return VALUE;
+    }
+
+    @Override public void setUp() throws Exception {
+        super.setUp();
+        loadConfigurationProviders(new NestedTestConfigurationProvider());
+
+        context = ActionContext.getContext();
+        context.getValueStack().push(this);
+    }
+
+    @Override protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    public void testNestedContext() throws Exception {
+        assertEquals(context, ActionContext.getContext());
+        ActionProxy proxy = actionProxyFactory.createActionProxy(NAMESPACE, SIMPLE_ACTION_NAME, null);
+        proxy.execute();
+        assertEquals(context, ActionContext.getContext());
+    }
+
+    public void testNestedNoValueStack() throws Exception {
+        ValueStack stack = ActionContext.getContext().getValueStack();
+        assertEquals(VALUE, stack.findValue(KEY));
+
+        ActionProxy proxy = actionProxyFactory.createActionProxy(NAMESPACE, NO_STACK_ACTION_NAME, null);
+        proxy.execute();
+        stack = ActionContext.getContext().getValueStack();
+        assertEquals(stack.findValue(KEY), VALUE);
+        assertNull(stack.findValue(NESTED_KEY));
+    }
+
+    public void testNestedValueStack() throws Exception {
+        ValueStack stack = ActionContext.getContext().getValueStack();
+        assertEquals(VALUE, stack.findValue(KEY));
+
+        HashMap<String, Object> extraContext = new HashMap<>();
+        extraContext.put(ActionContext.VALUE_STACK, stack);
+
+        ActionProxy proxy = actionProxyFactory.createActionProxy(NAMESPACE, STACK_ACTION_NAME, extraContext);
+        proxy.execute();
+        assertEquals(context, ActionContext.getContext());
+        assertEquals(stack, ActionContext.getContext().getValueStack());
+        assertEquals(VALUE, stack.findValue(KEY));
+        assertEquals(NESTED_VALUE, stack.findValue(NESTED_KEY));
+        assertEquals(3, stack.size());
+    }
+
+
+    class NestedTestConfigurationProvider implements ConfigurationProvider {
+        private Configuration configuration;
+        public void destroy() {
+        }
+        public void init(Configuration configuration) {
+            this.configuration = configuration;
+        }
+
+        public void register(ContainerBuilder builder, LocatableProperties props) {
+        }
+        
+        public void loadPackages() {
+            
+            PackageConfig packageContext = new PackageConfig.Builder("nestedActionTest")
+                .addActionConfig(SIMPLE_ACTION_NAME, new ActionConfig.Builder("nestedActionTest", SIMPLE_ACTION_NAME, SimpleAction.class.getName())
+                        .addResultConfig(new ResultConfig.Builder(Action.SUCCESS, MockResult.class.getName()).build())
+                        .addResultConfig(new ResultConfig.Builder(Action.ERROR, MockResult.class.getName()).build())
+                        .build())
+                .addActionConfig(NO_STACK_ACTION_NAME, new ActionConfig.Builder("nestedActionTest", NO_STACK_ACTION_NAME, NestedAction.class.getName())
+                        .addResultConfig(new ResultConfig.Builder(Action.SUCCESS, MockResult.class.getName()).build())
+                        .methodName("noStack")
+                        .build())
+                .addActionConfig(STACK_ACTION_NAME, new ActionConfig.Builder("nestedActionTest", STACK_ACTION_NAME, NestedAction.class.getName())
+                        .addResultConfig(new ResultConfig.Builder(Action.SUCCESS, MockResult.class.getName()).build())
+                        .methodName("stack")
+                        .build())
+                .namespace(NAMESPACE)
+                .build();
+            configuration.addPackageConfig("nestedActionTest", packageContext);
+        }
+
+        /**
+         * Tells whether the ConfigurationProvider should reload its configuration
+         *
+         * @return
+         */
+        public boolean needsReload() {
+            return false;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/test/java/com/opensymphony/xwork2/ActionSupportTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/opensymphony/xwork2/ActionSupportTest.java b/core/src/test/java/com/opensymphony/xwork2/ActionSupportTest.java
new file mode 100644
index 0000000..98a5dac
--- /dev/null
+++ b/core/src/test/java/com/opensymphony/xwork2/ActionSupportTest.java
@@ -0,0 +1,361 @@
+/*
+ * Copyright 2002-2006,2009 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.opensymphony.xwork2;
+
+import com.opensymphony.xwork2.util.ValueStack;
+
+import java.util.*;
+
+/**
+ * Unit test for {@link ActionSupport}.
+ *
+ * @author Claus Ibsen
+ */
+public class ActionSupportTest extends XWorkTestCase {
+
+    private ActionSupport as;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        as = new ActionSupport();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        as = null;
+    }
+
+    public void testNothingDoneOnActionSupport() throws Exception {
+        assertEquals(false, as.hasErrors());
+
+        assertNotNull(as.getActionErrors());
+        assertEquals(0, as.getActionErrors().size());
+        assertEquals(false, as.hasActionErrors());
+
+        assertNotNull(as.getActionMessages());
+        assertEquals(0, as.getActionMessages().size());
+        assertEquals(false, as.hasActionMessages());
+
+        assertNotNull(as.getFieldErrors());
+        assertEquals(0, as.getFieldErrors().size());
+        assertEquals(false, as.hasFieldErrors());
+
+        assertNull(as.getText(null));
+
+        try {
+            as.pause(null);
+        } catch (Exception e) {
+            fail("Should not fail");
+        }
+
+        assertEquals(Action.INPUT, as.input());
+        assertEquals(Action.SUCCESS, as.doDefault());
+        assertEquals(Action.SUCCESS, as.execute());
+        try {
+            as.clone();
+            fail("Failure expected for clone()");
+        } catch (CloneNotSupportedException e) {
+            // success!
+        }
+
+
+        assertNull(as.getText(null, (List) null));
+        assertNull(as.getText(null, (String) null));
+        assertNull(as.getText(null, (String[]) null));
+
+        assertNull(as.getText(null, (String) null, (List) null));
+        assertNull(as.getText(null, (String) null, (String) null));
+        assertNull(as.getText(null, (String) null, (String[]) null));
+
+        assertNull(as.getText(null, (String) null, (List) null, (ValueStack) null));
+        assertNull(as.getText(null, (String) null, (String[]) null, (ValueStack) null));
+
+        assertNotNull(as.getLocale());
+        assertEquals(ActionContext.getContext().getLocale(), as.getLocale());
+
+        assertNull(as.getTexts()); // can not find a bundle
+        assertEquals("not.in.bundle", as.getText("not.in.bundle"));
+    }
+
+    public void testActionErrors() {
+        assertEquals(false, as.hasActionErrors());
+        assertEquals(0, as.getActionErrors().size());
+        as.addActionError("Damm");
+        assertEquals(1, as.getActionErrors().size());
+        assertEquals("Damm", as.getActionErrors().iterator().next());
+        assertEquals(true, as.hasActionErrors());
+        assertEquals(true, as.hasErrors());
+
+        as.clearErrorsAndMessages();
+        assertEquals(false, as.hasActionErrors());
+        assertEquals(false, as.hasErrors());
+    }
+
+    public void testActionMessages() {
+        assertEquals(false, as.hasActionMessages());
+        assertEquals(0, as.getActionMessages().size());
+        as.addActionMessage("Killroy was here");
+        assertEquals(1, as.getActionMessages().size());
+        assertEquals("Killroy was here", as.getActionMessages().iterator().next());
+        assertEquals(true, as.hasActionMessages());
+
+        assertEquals(false, as.hasActionErrors()); // does not count as a error
+        assertEquals(false, as.hasErrors()); // does not count as a error
+
+        as.clearErrorsAndMessages();
+        assertEquals(false, as.hasActionMessages());
+        assertEquals(false, as.hasErrors());
+    }
+
+    public void testFieldErrors() {
+        assertEquals(false, as.hasFieldErrors());
+        assertEquals(0, as.getFieldErrors().size());
+        as.addFieldError("username", "Admin is not allowed as username");
+        List<String> errors = as.getFieldErrors().get("username");
+        assertEquals(1, errors.size());
+        assertEquals("Admin is not allowed as username", errors.get(0));
+
+        assertEquals(true, as.hasFieldErrors());
+        assertEquals(true, as.hasErrors());
+
+        as.clearErrorsAndMessages();
+        assertEquals(false, as.hasFieldErrors());
+        assertEquals(false, as.hasErrors());
+    }
+
+    public void testDeprecated() throws Exception {
+        assertNotNull(as.getErrorMessages());
+        assertEquals(0, as.getErrorMessages().size());
+
+        assertNotNull(as.getErrors());
+        assertEquals(0, as.getErrors().size());
+    }
+
+    public void testLocale() {
+        Locale defLocale = Locale.getDefault();
+        ActionContext.getContext().setLocale(null);
+
+        // will never return null, if no locale is set then default is returned
+        assertNotNull(as.getLocale());
+        assertEquals(defLocale, as.getLocale());
+
+        ActionContext.getContext().setLocale(Locale.ITALY);
+        assertEquals(Locale.ITALY, as.getLocale());
+
+        ActionContext.setContext(new ActionContext(new HashMap<String, Object>()));
+        assertEquals(defLocale, as.getLocale()); // ActionContext will create a new context, when it was set to null before
+    }
+
+    public void testMyActionSupport() throws Exception {
+        ActionContext.getContext().setLocale(new Locale("da"));
+        MyActionSupport mas = new MyActionSupport();
+
+        assertEquals("santa", mas.doDefault());
+        assertNotNull(mas.getTexts());
+
+        assertEquals(false, mas.hasActionMessages());
+        mas.validate();
+        assertEquals(true, mas.hasActionMessages());
+    }
+
+    public void testSimpleGetTexts() throws Exception {
+        ActionContext.getContext().setLocale(new Locale("da"));
+        MyActionSupport mas = new MyActionSupport();
+
+        checkGetTexts(mas);
+    }
+
+    public void testSimpleGetTextsWithInjectedTextProvider() throws Exception {
+        ActionContext.getContext().setLocale(new Locale("da"));
+        MyActionSupport mas = new MyActionSupport();
+
+        TextProvider textProvider = container.getInstance(TextProvider.class, "system");
+
+        assertNotNull(textProvider);
+
+        container.inject(mas);
+
+        checkGetTexts(mas);
+    }
+
+    private void checkGetTexts(MyActionSupport mas) {
+        assertEquals("Hello World", mas.getText("hello"));
+        assertEquals("not.in.bundle", mas.getText("not.in.bundle"));
+
+        assertEquals("Hello World", mas.getText("hello", "this is default"));
+        assertEquals("this is default", mas.getText("not.in.bundle", "this is default"));
+
+        List nullList = null;
+        assertEquals("Hello World", mas.getText("hello", nullList));
+
+        String[] nullStrings = null;
+        assertEquals("Hello World", mas.getText("hello", nullStrings));
+    }
+
+    public void testGetTextsWithArgs() throws Exception {
+        ActionContext.getContext().setLocale(new Locale("da"));
+        MyActionSupport mas = new MyActionSupport();
+
+        assertEquals("Hello World", mas.getText("hello", "this is default", "from me")); // no args in bundle
+        assertEquals("Hello World from me", mas.getText("hello.0", "this is default", "from me"));
+        assertEquals("this is default", mas.getText("not.in.bundle", "this is default", "from me"));
+        assertEquals("this is default from me", mas.getText("not.in.bundle", "this is default {0}", "from me"));
+
+        assertEquals("not.in.bundle", mas.getText("not.in.bundle"));
+    }
+
+    public void testGetTextsWithListArgs() throws Exception {
+        ActionContext.getContext().setLocale(new Locale("da"));
+        MyActionSupport mas = new MyActionSupport();
+
+        List<Object> args = new ArrayList<>();
+        args.add("Santa");
+        args.add("loud");
+        assertEquals("Hello World", mas.getText("hello", "this is default", args)); // no args in bundle
+        assertEquals("Hello World Santa", mas.getText("hello.0", "this is default", args)); // only 1 arg in bundle
+        assertEquals("Hello World. This is Santa speaking loud", mas.getText("hello.1", "this is default", args));
+
+        assertEquals("this is default", mas.getText("not.in.bundle", "this is default", args));
+        assertEquals("this is default Santa", mas.getText("not.in.bundle", "this is default {0}", args));
+        assertEquals("this is default Santa speaking loud", mas.getText("not.in.bundle", "this is default {0} speaking {1}", args));
+
+        assertEquals("Hello World", mas.getText("hello", args)); // no args in bundle
+        assertEquals("Hello World Santa", mas.getText("hello.0", args)); // only 1 arg in bundle
+        assertEquals("Hello World. This is Santa speaking loud", mas.getText("hello.1", args));
+
+        assertEquals("not.in.bundle", mas.getText("not.in.bundle", args));
+
+        assertEquals("Hello World", mas.getText("hello", "this is default", (List) null));
+        assertEquals("this is default", mas.getText("not.in.bundle", "this is default", (List) null));
+    }
+
+    public void testGetTextsWithArrayArgs() throws Exception {
+        ActionContext.getContext().setLocale(new Locale("da"));
+        MyActionSupport mas = new MyActionSupport();
+
+        String[] args = {"Santa", "loud"};
+        assertEquals("Hello World", mas.getText("hello", "this is default", args)); // no args in bundle
+        assertEquals("Hello World Santa", mas.getText("hello.0", "this is default", args)); // only 1 arg in bundle
+        assertEquals("Hello World. This is Santa speaking loud", mas.getText("hello.1", "this is default", args));
+
+        assertEquals("this is default", mas.getText("not.in.bundle", "this is default", args));
+        assertEquals("this is default Santa", mas.getText("not.in.bundle", "this is default {0}", args));
+        assertEquals("this is default Santa speaking loud", mas.getText("not.in.bundle", "this is default {0} speaking {1}", args));
+
+        assertEquals("Hello World", mas.getText("hello", args)); // no args in bundle
+        assertEquals("Hello World Santa", mas.getText("hello.0", args)); // only 1 arg in bundle
+        assertEquals("Hello World. This is Santa speaking loud", mas.getText("hello.1", args));
+
+        assertEquals("not.in.bundle", mas.getText("not.in.bundle", args));
+
+        assertEquals("Hello World", mas.getText("hello", "this is default", (String[]) null));
+        assertEquals("this is default", mas.getText("not.in.bundle", "this is default", (String[]) null));
+    }
+
+    public void testGetTextsWithListAndStack() throws Exception {
+        ActionContext.getContext().setLocale(new Locale("da"));
+        MyActionSupport mas = new MyActionSupport();
+
+        ValueStack stack = ActionContext.getContext().getValueStack();
+
+        List<Object> args = new ArrayList<>();
+        args.add("Santa");
+        args.add("loud");
+        assertEquals("Hello World", mas.getText("hello", "this is default", args, stack)); // no args in bundle
+        assertEquals("Hello World Santa", mas.getText("hello.0", "this is default", args, stack)); // only 1 arg in bundle
+        assertEquals("Hello World. This is Santa speaking loud", mas.getText("hello.1", "this is default", args, stack));
+
+        assertEquals("this is default", mas.getText("not.in.bundle", "this is default", args, stack));
+        assertEquals("this is default Santa", mas.getText("not.in.bundle", "this is default {0}", args, stack));
+        assertEquals("this is default Santa speaking loud", mas.getText("not.in.bundle", "this is default {0} speaking {1}", args, stack));
+    }
+
+    public void testGetTextsWithArrayAndStack() throws Exception {
+        ActionContext.getContext().setLocale(new Locale("da"));
+        MyActionSupport mas = new MyActionSupport();
+
+        ValueStack stack = ActionContext.getContext().getValueStack();
+
+        String[] args = {"Santa", "loud"};
+        assertEquals("Hello World", mas.getText("hello", "this is default", args, stack)); // no args in bundle
+        assertEquals("Hello World Santa", mas.getText("hello.0", "this is default", args, stack)); // only 1 arg in bundle
+        assertEquals("Hello World. This is Santa speaking loud", mas.getText("hello.1", "this is default", args, stack));
+
+        assertEquals("this is default", mas.getText("not.in.bundle", "this is default", args, stack));
+        assertEquals("this is default Santa", mas.getText("not.in.bundle", "this is default {0}", args, stack));
+        assertEquals("this is default Santa speaking loud", mas.getText("not.in.bundle", "this is default {0} speaking {1}", args, stack));
+    }
+
+    public void testGetBundle() throws Exception {
+        ActionContext.getContext().setLocale(new Locale("da"));
+        MyActionSupport mas = new MyActionSupport();
+
+        ResourceBundle rb = ResourceBundle.getBundle(MyActionSupport.class.getName(), new Locale("da"));
+        assertEquals(rb, mas.getTexts(MyActionSupport.class.getName()));
+    }
+
+    public void testFormattingSupport() throws Exception {
+        ActionContext.getContext().setLocale(new Locale("da"));
+        MyActionSupport mas = new MyActionSupport();
+        ActionContext.getContext().getValueStack().push(mas);
+
+        mas.setVal(234d);
+
+        String formatted = mas.getFormatted("format.number", "val");
+
+        assertEquals("234,0", formatted);
+    }
+
+    public void testFormattingSupportWithConversionError() throws Exception {
+        ActionContext.getContext().getConversionErrors().put("val", new String[]{"4567def"});
+        ActionContext.getContext().setLocale(new Locale("da"));
+        MyActionSupport mas = new MyActionSupport();
+        ActionContext.getContext().getValueStack().push(mas);
+
+        mas.setVal(234d);
+
+        String formatted = mas.getFormatted("format.number", "val");
+
+        assertEquals("4567def", formatted);
+    }
+
+    private class MyActionSupport extends ActionSupport {
+
+        private Double val;
+
+        @Override
+        public String doDefault() throws Exception {
+            return "santa";
+        }
+
+        @Override
+        public void validate() {
+            super.validate(); // to have code coverage
+            addActionMessage("validation was called");
+        }
+
+        public Double getVal() {
+            return val;
+        }
+
+        public void setVal(Double val) {
+            this.val = val;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/test/java/com/opensymphony/xwork2/AnnotatedTestBean.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/opensymphony/xwork2/AnnotatedTestBean.java b/core/src/test/java/com/opensymphony/xwork2/AnnotatedTestBean.java
new file mode 100644
index 0000000..98a5d96
--- /dev/null
+++ b/core/src/test/java/com/opensymphony/xwork2/AnnotatedTestBean.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2002-2006,2009 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.opensymphony.xwork2;
+
+import com.opensymphony.xwork2.validator.annotations.IntRangeFieldValidator;
+import com.opensymphony.xwork2.validator.annotations.RequiredStringValidator;
+import com.opensymphony.xwork2.validator.annotations.Validations;
+
+import java.util.Date;
+
+
+/**
+ * AnnotatedTestBean
+ * @author Jason Carreira
+ * @author Rainer Hermanns
+ * Created Aug 4, 2003 12:39:53 AM
+ */
+public class AnnotatedTestBean {
+    //~ Instance fields ////////////////////////////////////////////////////////
+
+    private Date birth;
+    private String name;
+    private int count;
+
+    //~ Constructors ///////////////////////////////////////////////////////////
+
+    public AnnotatedTestBean() {
+    }
+
+    //~ Methods ////////////////////////////////////////////////////////////////
+
+    public void setBirth(Date birth) {
+        this.birth = birth;
+    }
+
+    public Date getBirth() {
+        return birth;
+    }
+
+    @Validations(
+            intRangeFields = {
+                @IntRangeFieldValidator(shortCircuit = true, min = "1", max="100", key="invalid.count", message = "Invalid Count!"),
+                @IntRangeFieldValidator(shortCircuit = true, min = "20", max="28", key="invalid.count.bad", message = "Smaller Invalid Count: ${count}")
+            }
+
+    )
+    public void setCount(int count) {
+        this.count = count;
+    }
+
+    public int getCount() {
+        return count;
+    }
+
+    @RequiredStringValidator(message = "You must enter a name.")
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+}


Mime
View raw message