struts-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From lukaszlen...@apache.org
Subject [27/57] [partial] struts git commit: Merges xwork packages into struts
Date Wed, 17 Jun 2015 21:09:27 GMT
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/validator/validators/DateRangeFieldValidator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/DateRangeFieldValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/DateRangeFieldValidator.java
new file mode 100644
index 0000000..572d307
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/DateRangeFieldValidator.java
@@ -0,0 +1,95 @@
+/*
+ * 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 java.util.Date;
+
+/**
+ * <!-- START SNIPPET: javadoc -->
+ *
+ * Field Validator that checks if the date supplied is within a specific range.
+ *
+ * <b>NOTE:</b> If no date converter is specified, XWorkBasicConverter will kick
+ * in to do the date conversion, which by default using the <code>Date.SHORT</code> format using
+ * the a problematically specified locale else falling back to the system
+ * default locale.
+ *
+ *
+ * <!-- END SNIPPET: javadoc -->
+ *
+ * <p/>
+ *
+ * <!-- START SNIPPET: parameters -->
+ * <ul>
+ * 		<li>fieldName - The field name this validator is validating. Required if using Plain-Validator Syntax otherwise not required</li>
+ *      <li>min - the min date range. If not specified will not be checked.</li>
+ *      <li>max - the max date range. If not specified will not be checked.</li>
+ *      <li>parse - if set to true, minExpression and maxExpression will be evaluated to find min/max</li>
+ *      <li>minExpression - expression to calculate the minimum value (if none is specified, it will not be checked) </li>
+ *      <li>maxExpression - expression to calculate the maximum value (if none is specified, it will not be checked) </li>
+ * </ul>
+ *
+ * You can either use the min / max value or minExpression / maxExpression (when parse is set to true) -
+ * using expression can be slightly slower, see the example below.
+ * <!-- END SNIPPET: parameters -->
+ *
+ * <!-- START SNIPPET: parameters-warning -->
+ * Do not use ${minExpression} and ${maxExpression} as an expression as this will turn into infinitive loop!
+ * <!-- END SNIPPET: parameters-warning -->
+ *
+ * <pre>
+ * <!-- START SNIPPET: examples -->
+ * &lt;validators>
+ *     &lt;!-- Plain Validator syntax --&gt;
+ *     &lt;validator type="date"&gt;
+ *         &lt;param name="fieldName"&gt;birthday&lt;/param&gt;
+ *         &lt;param name="min"&gt;01/01/1990&lt;/param&gt;
+ *         &lt;param name="max"&gt;01/01/2000&lt;/param&gt;
+ *         &lt;message&gt;Birthday must be within ${min} and ${max}&lt;/message&gt;
+ *     &lt;/validator&gt;
+ *
+ *     &lt;!-- Field Validator Syntax --&gt;
+ *     &lt;field name="birthday"&gt;
+ *         &lt;field-validator type="date"&gt;
+ *      	   &lt;param name="min"&gt;01/01/1990&lt;/param&gt;
+ *             &lt;param name="max"&gt;01/01/2000&lt;/param&gt;
+ *             &lt;message&gt;Birthday must be within ${min} and ${max}&lt;/message&gt;
+ *     	   &lt;/field&gt;
+ *     &lt;/field&gt;
+ *
+ *     &lt;!-- Field Validator Syntax with expression --&gt;
+ *     &lt;field name="birthday"&gt;
+ *         &lt;field-validator type="date"&gt;
+ *             &lt;param name="minExpression"&gt;${minValue}&lt;/param&gt; &lt;!-- will be evaluated as: Date getMinValue() --&gt;
+ *             &lt;param name="maxExpression"&gt;${maxValue}&lt;/param&gt; &lt;!-- will be evaluated as: Date getMaxValue() --&gt;
+ *             &lt;message&gt;Age needs to be between ${min} and ${max}&lt;/message&gt;
+ *         &lt;/field-validator&gt;
+ *     &lt;/field&gt;
+ * &lt;/validators&gt;
+ * <!-- END SNIPPET: examples -->
+ * </pre>
+ *
+ *
+ * @author Jason Carreira
+ * @version $Date$ $Id$
+ */
+public final class DateRangeFieldValidator extends RangeValidatorSupport<Date> {
+
+    public DateRangeFieldValidator() {
+        super(Date.class);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/validator/validators/DoubleRangeFieldValidator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/DoubleRangeFieldValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/DoubleRangeFieldValidator.java
new file mode 100644
index 0000000..f0dfd80
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/DoubleRangeFieldValidator.java
@@ -0,0 +1,196 @@
+/*
+ * 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.validator.ValidationException;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * <!-- START SNIPPET: javadoc -->
+ * Field Validator that checks if the double specified is within a certain range.
+ * <!-- END SNIPPET: javadoc -->
+ *
+ *
+ * <!-- START SNIPPET: parameters -->
+ * <ul>
+ *     <li>fieldName - The field name this validator is validating. Required if using Plain-Validator Syntax otherwise not required</li>
+ *     <li>minInclusive - the minimum inclusive value in FloatValue format specified by Java language (if none is specified, it will not be checked) </li>
+ *     <li>maxInclusive - the maximum inclusive value in FloatValue format specified by Java language (if none is specified, it will not be checked) </li>
+ *     <li>minExclusive - the minimum exclusive value in FloatValue format specified by Java language (if none is specified, it will not be checked) </li>
+ *     <li>maxExclusive - the maximum exclusive value in FloatValue format specified by Java language (if none is specified, it will not be checked) </li>
+ *     <li>minInclusiveExpression - the minimum inclusive value specified as a OGNL expression (if none is specified, it will not be checked) </li>
+ *     <li>maxInclusiveExpression - the maximum inclusive value specified as a OGNL expression (if none is specified, it will not be checked) </li>
+ *     <li>minExclusiveExpression - the minimum exclusive value specified as a OGNL expression (if none is specified, it will not be checked) </li>
+ *     <li>maxExclusiveExpression - the maximum exclusive value specified as a OGNL expression (if none is specified, it will not be checked) </li>
+ * </ul>
+ *
+ * You can specify either minInclusive, maxInclusive, minExclusive and maxExclusive or minInclusiveExpression, maxInclusiveExpression,
+ * minExclusiveExpression and maxExclusiveExpression as a OGNL expression, see example below. You can always try to mix params
+ * but be aware that such behaviour was not tested.
+ * <!-- END SNIPPET: parameters -->
+ *
+ *
+ * <!-- START SNIPPET: parameters-warning -->
+ * Do not use ${minInclusiveExpression}, ${maxInclusiveExpression}, ${minExclusiveExpressionExpression} and ${maxExclusive}
+ * as an expression as this will turn into infinitive loop!
+ * <!-- END SNIPPET: parameters-warning -->
+ *
+ *
+ * <pre>
+ * <!-- START SNIPPET: examples -->
+ * &lt;validators>
+ *     &lt;!-- Plain Validator Syntax --&gt;
+ *         &lt;validator type="double">
+ *         &lt;param name="fieldName"&gt;percentage&lt;/param&gt;
+ *         &lt;param name="minInclusive"&gt;20.1&lt;/param&gt;
+ *         &lt;param name="maxInclusive"&gt;50.1&lt;/param&gt;
+ *         &lt;message&gt;Age needs to be between ${minInclusive} and ${maxInclusive} (inclusive)&lt;/message&gt;
+ *     &lt;/validator&gt;
+ *
+ *     &lt;!-- Field Validator Syntax --&gt;
+ *     &lt;field name="percentage"&gt;
+ *         &lt;field-validator type="double"&gt;
+ *             &lt;param name="minExclusive"&gt;0.123&lt;/param&gt;
+ *             &lt;param name="maxExclusive"&gt;99.98&lt;/param&gt;
+ *             &lt;message&gt;Percentage needs to be between ${minExclusive} and ${maxExclusive} (exclusive)&lt;/message&gt;
+ *         &lt;/field-validator&gt;
+ *     &lt;/field&gt;
+ *
+ *     &lt;!-- Field Validator Syntax with expression --&gt;
+ *     &lt;field name="percentage"&gt;
+ *         &lt;field-validator type="double"&gt;
+ *             &lt;param name="minExclusiveExpression"&gt;${minExclusiveValue}&lt;/param&gt; &lt;!-- will be evaluated as: Double getMinExclusiveValue() --&gt;
+ *             &lt;param name="maxExclusiveExpression"&gt;${maxExclusiveValue}&lt;/param&gt; &lt;!-- will be evaluated as: Double getMaxExclusiveValue() --&gt;
+ *             &lt;message&gt;Percentage needs to be between ${minExclusive} and ${maxExclusive} (exclusive)&lt;/message&gt;
+ *         &lt;/field-validator&gt;
+ *     &lt;/field&gt;
+ * &lt;/validators&gt;
+ * <!-- END SNIPPET: examples -->
+ * </pre>
+ *
+ * @author Rainer Hermanns
+ * @author Rene Gielen
+ *
+ * @version $Id$
+ */
+public class DoubleRangeFieldValidator extends FieldValidatorSupport {
+    
+    private Double maxInclusive = null;
+    private Double minInclusive = null;
+    private Double minExclusive = null;
+    private Double maxExclusive = null;
+
+    private String minInclusiveExpression;
+    private String maxInclusiveExpression;
+    private String minExclusiveExpression;
+    private String maxExclusiveExpression;
+
+    public void validate(Object object) throws ValidationException {
+        String fieldName = getFieldName();
+        Double value;
+        try {
+            Object obj = this.getFieldValue(fieldName, object);
+            if (obj == null) {
+                return;
+            }
+            value = Double.valueOf(obj.toString());
+        } catch (NumberFormatException e) {
+            return;
+        }
+
+        Double maxInclusiveToUse = getMaxInclusive();
+        Double minInclusiveToUse = getMinInclusive();
+        Double maxExclusiveToUse = getMaxExclusive();
+        Double minExclusiveToUse = getMinExclusive();
+
+        if ((maxInclusiveToUse != null && value.compareTo(maxInclusiveToUse) > 0) ||
+                (minInclusiveToUse != null && value.compareTo(minInclusiveToUse) < 0) ||
+                (maxExclusiveToUse != null && value.compareTo(maxExclusiveToUse) >= 0) ||
+                (minExclusiveToUse != null && value.compareTo(minExclusiveToUse) <= 0)) {
+            addFieldError(fieldName, object);
+        }
+    }
+
+    public void setMaxInclusive(Double maxInclusive) {
+        this.maxInclusive = maxInclusive;
+    }
+
+    public Double getMaxInclusive() {
+        if (maxInclusive != null) {
+            return maxInclusive;
+        } else if (StringUtils.isNotEmpty(maxInclusiveExpression)) {
+            return (Double) parse(maxInclusiveExpression, Double.class);
+        }
+        return maxInclusive;
+    }
+
+    public void setMinInclusive(Double minInclusive) {
+        this.minInclusive = minInclusive;
+    }
+
+    public Double getMinInclusive() {
+        if (minInclusive != null) {
+            return minInclusive;
+        } else if (StringUtils.isNotEmpty(minInclusiveExpression)) {
+            return (Double) parse(minInclusiveExpression, Double.class);
+        }
+        return null;
+    }
+
+    public void setMinExclusive(Double minExclusive) {
+        this.minExclusive = minExclusive;
+    }
+
+    public Double getMinExclusive() {
+        if (minExclusive != null) {
+            return minExclusive;
+        } else if (StringUtils.isNotEmpty(minExclusiveExpression)) {
+            return (Double) parse(minExclusiveExpression, Double.class);
+        }
+        return null;
+    }
+
+    public void setMaxExclusive(Double maxExclusive) {
+        this.maxExclusive = maxExclusive;
+    }
+
+    public Double getMaxExclusive() {
+        if (maxExclusive != null) {
+            return maxExclusive;
+        } else if (StringUtils.isNotEmpty(maxExclusiveExpression)) {
+            return (Double) parse(maxExclusiveExpression, Double.class);
+        }
+        return null;
+    }
+
+    public void setMinInclusiveExpression(String minInclusiveExpression) {
+        this.minInclusiveExpression = minInclusiveExpression;
+    }
+
+    public void setMaxInclusiveExpression(String maxInclusiveExpression) {
+        this.maxInclusiveExpression = maxInclusiveExpression;
+    }
+
+    public void setMinExclusiveExpression(String minExclusiveExpression) {
+        this.minExclusiveExpression = minExclusiveExpression;
+    }
+
+    public void setMaxExclusiveExpression(String maxExclusiveExpression) {
+        this.maxExclusiveExpression = maxExclusiveExpression;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/validator/validators/EmailValidator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/EmailValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/EmailValidator.java
new file mode 100644
index 0000000..d0dcf75
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/EmailValidator.java
@@ -0,0 +1,90 @@
+/*
+ * 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;
+
+
+/**
+ * <!-- START SNIPPET: javadoc -->
+ * EmailValidator checks that a given String field, if not empty, is a valid email address.
+ *
+ * The regular expression used to validate that the string is an email address is:
+ *
+ * <pre>
+ * \\b^['_a-z0-9-\\+]+(\\.['_a-z0-9-\\+]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*\\.([a-z]{2}|aero|arpa|asia|biz|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|nato|net|org|pro|tel|travel|xxx)$\\b
+ * </pre>
+ *
+ * You can also specify expression, caseSensitive and trim params as a OGNL expression, see the example below.
+ * <!-- END SNIPPET: javadoc -->
+ * 
+ * 
+ * <!-- START SNIPPET: parameters -->
+ * <ul>
+ * 		<li>fieldName - The field name this validator is validating. Required if using Plain-Validator Syntax otherwise not required</li>
+ * </ul>
+ * Check also documentation of the RegexpValidator for more details - the EmailValidator bases on it.
+ * <!-- END SNIPPET: parameters -->
+ *
+ * <!-- START SNIPPET: parameters-warning -->
+ * Do not use ${regexExpression}, ${caseSensitiveExpression} and ${trimExpression} as an expression as this will turn into infinitive loop!
+ * <!-- END SNIPPET: parameters-warning -->
+ * 
+ * <pre>
+ * <!-- START SNIPPET: example -->
+ *     &lt;!-- Plain Validator Syntax --&gt;
+ *     &lt;validators&gt;
+ *         &lt;validator type="email"&gt;
+ *             &lt;param name="fieldName"&gt;myEmail&lt;/param&gt;
+ *             &lt;message&gt;Must provide a valid email&lt;/message&gt;
+ *         &lt;/validator&gt;
+ *     &lt;/validators&gt;
+ *     
+ *     &lt;!-- Field Validator Syntax --&gt;
+ *     &lt;field name="myEmail"&gt;
+ *        &lt;field-validator type="email"&gt;
+ *           &lt;message&gt;Must provide a valid email&lt;/message&gt;
+ *        &lt;/field-validator&gt;
+ *     &lt;/field&gt;
+ *
+ *     &lt;!-- Field Validator Syntax with expressions --&gt;
+ *     &lt;!-- Only available when used with xml based configuration, if you want to have the same
+ *             flexibility with annotations use @RegexFieldValidator instead --&gt;
+ *     &lt;field name="myEmail"&gt;
+ *        &lt;field-validator type="email"&gt;
+ *           &lt;param name="regexExpression"&gt;${emailPattern}&lt;/param&gt; &lt;!-- will be evaluated as: String getEmailPattern() --&gt;
+ *           &lt;param name="caseSensitiveExpression"&gt;${emailCaseSensitive}&lt;/param&gt; &lt;!-- will be evaluated as: boolean getEmailCaseSensitive() --&gt;
+ *           &lt;param name="trimExpression"&gt;${trimEmail}&lt;/param&gt; &lt;!-- will be evaluated as: boolean getTrimEmail() --&gt;
+ *           &lt;message&gt;Must provide a valid email&lt;/message&gt;
+ *        &lt;/field-validator&gt;
+ *     &lt;/field&gt;
+ * <!-- END SNIPPET: example -->
+ * </pre>
+ *
+ * @author jhouse
+ * @author tm_jee
+ * @version $Date$ $Id$
+ */
+public class EmailValidator extends RegexFieldValidator {
+
+	// see XW-371 
+    public static final String EMAIL_ADDRESS_PATTERN =
+    	"\\b^['_a-z0-9-\\+]+(\\.['_a-z0-9-\\+]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*\\.([a-z]{2}|aero|arpa|asia|biz|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|nato|net|org|pro|tel|travel|xxx)$\\b";
+
+    public EmailValidator() {
+        setRegex(EMAIL_ADDRESS_PATTERN);
+        setCaseSensitive(false);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/validator/validators/ExpressionValidator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/ExpressionValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/ExpressionValidator.java
new file mode 100644
index 0000000..d7f129b
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/ExpressionValidator.java
@@ -0,0 +1,81 @@
+/*
+ * 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.validator.ValidationException;
+
+/**
+ * <!-- START SNIPPET: javadoc -->
+ * A Non-Field Level validator that validates based on regular expression supplied.
+ * <!-- END SNIPPET: javadoc -->
+ * <p/>
+ * 
+ * <!-- START SNIPPET: parameters -->
+ * <ul>
+ * 	 <li>expression - the Ognl expression to be evaluated against the stack (Must evaluate to a Boolean)</li>
+ * </ul>
+ * <!-- END SNIPPET: parameters -->
+ *
+ * 
+ * <pre>
+ * <!-- START SNIPPET: example -->
+ *     &lt;validators&gt;
+ *           &lt;validator type="expression"&gt;
+ *              &lt;param name="expression"&gt; .... &lt;/param&gt;
+ *              &lt;message&gt;Failed to meet Ognl Expression  .... &lt;/message&gt;
+ *           &lt;/validator&gt;
+ *     &lt;/validators&gt;
+ * <!-- END SNIPPET: example -->
+ * </pre>
+ *
+ * @author Jason Carreira
+ */
+public class ExpressionValidator extends ValidatorSupport {
+
+    private String expression;
+
+    public void setExpression(String expression) {
+        this.expression = expression;
+    }
+
+    public String getExpression() {
+        return expression;
+    }
+
+    public void validate(Object object) throws ValidationException {
+        Boolean answer = Boolean.FALSE;
+        Object obj = null;
+
+        try {
+            obj = getFieldValue(expression, object);
+        } catch (ValidationException e) {
+            throw e;
+        } catch (Exception e) {
+            // let this pass, but it will be logged right below
+        }
+
+        if ((obj != null) && (obj instanceof Boolean)) {
+            answer = (Boolean) obj;
+        } else {
+            log.warn("Got result of [{}] when trying to get Boolean.", obj);
+        }
+
+        if (!answer) {
+            log.debug("Validation failed on expression [{}] with validated object [{}]", expression, object);
+            addActionError(object);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/validator/validators/FieldExpressionValidator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/FieldExpressionValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/FieldExpressionValidator.java
new file mode 100644
index 0000000..197314b
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/FieldExpressionValidator.java
@@ -0,0 +1,97 @@
+/*
+ * 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.validator.ValidationException;
+
+
+/**
+ * <!-- START SNIPPET: javadoc -->
+ * Validates a field using an OGNL expression.
+ * <!-- END SNIPPET: javadoc -->
+ * <p/>
+ * 
+ * <!-- START SNIPPET: parameters -->
+ * <ul>
+ *    <li>fieldName - The field name this validator is validating. Required if using Plain-Validator Syntax otherwise not required</li>
+ *    <li>expression - The Ognl expression (must evaluate to a boolean) which is to be evalidated the stack</li>
+ * </ul>
+ * <!-- END SNIPPET: parameters -->
+ * 
+ * <pre>
+ * <!-- START SNIPPET: example -->
+ *    &lt;!-- Plain Validator Syntax --&gt;
+ *    &lt;validators&gt;
+ *        &lt;!-- Plain Validator Syntax --&gt;
+ *        &lt;validator type="fieldexpression"&gt;
+ *           &lt;param name="fieldName"&gt;myField&lt;/param&gt;
+ *           &lt;param name="expression"&gt;&lt;![CDATA[#myCreditLimit &gt; #myGirfriendCreditLimit]]&gt;&lt;/param&gt;
+ *           &lt;message&gt;My credit limit should be MORE than my girlfriend&lt;/message&gt;
+ *        &lt;validator&gt;
+ *        
+ *        &lt;!-- Field Validator Syntax --&gt;
+ *        &lt;field name="myField"&gt;
+ *            &lt;field-validator type="fieldexpression"&gt;
+ *                &lt;param name="expression"&gt;&lt;![CDATA[#myCreditLimit &gt; #myGirfriendCreditLimit]]&gt;&lt;/param&gt;
+ *                &lt;message&gt;My credit limit should be MORE than my girlfriend&lt;/message&gt;
+ *            &lt;/field-validator&gt;
+ *        &lt;/field&gt;
+ *        
+ *    &lt;/vaidators&gt;
+ * <!-- END SNIPPET: example -->
+ * </pre>
+ * 
+ *
+ * @author $Author$
+ * @version $Revision$
+ */
+public class FieldExpressionValidator extends FieldValidatorSupport {
+
+    private String expression;
+
+    public void setExpression(String expression) {
+        this.expression = expression;
+    }
+
+    public String getExpression() {
+        return expression;
+    }
+
+    public void validate(Object object) throws ValidationException {
+        String fieldName = getFieldName();
+
+        Boolean answer = Boolean.FALSE;
+        Object obj = null;
+
+        try {
+            obj = getFieldValue(expression, object);
+        } catch (ValidationException e) {
+            throw e;
+        } catch (Exception e) {
+            // let this pass, but it will be logged right below
+        }
+
+        if ((obj != null) && (obj instanceof Boolean)) {
+            answer = (Boolean) obj;
+        } else {
+            log.warn("Got result of {} when trying to get Boolean.", obj);
+        }
+
+        if (!answer.booleanValue()) {
+            addFieldError(fieldName, object);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/validator/validators/FieldValidatorSupport.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/FieldValidatorSupport.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/FieldValidatorSupport.java
new file mode 100644
index 0000000..4a3f147
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/FieldValidatorSupport.java
@@ -0,0 +1,48 @@
+/*
+ * 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.validator.FieldValidator;
+
+
+/**
+ * Base class for field validators.
+ *
+ * @author Jason Carreira
+ */
+public abstract class FieldValidatorSupport extends ValidatorSupport implements FieldValidator {
+
+    private String fieldName;
+    private String type;
+
+    public void setFieldName(String fieldName) {
+        this.fieldName = fieldName;
+    }
+
+    public String getFieldName() {
+        return fieldName;
+    }
+
+    @Override
+    public void setValidatorType(String type) {
+        this.type = type;
+    }
+
+    @Override
+    public String getValidatorType() {
+        return type;
+    }
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/validator/validators/IntRangeFieldValidator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/IntRangeFieldValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/IntRangeFieldValidator.java
new file mode 100644
index 0000000..bcc95d4
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/IntRangeFieldValidator.java
@@ -0,0 +1,83 @@
+/*
+ * 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;
+
+/**
+ * <!-- START SNIPPET: javadoc -->
+ * Field Validator that checks if the integer specified is within a certain range.
+ * <!-- END SNIPPET: javadoc -->
+ *
+ *
+ * <!-- START SNIPPET: parameters -->
+ * <ul>
+ * 		<li>fieldName - The field name this validator is validating. Required if using Plain-Validator Syntax otherwise not required</li>
+ * 		<li>min - the minimum value (if none is specified, it will not be checked) </li>
+ * 		<li>max - the maximum value (if none is specified, it will not be checked) </li>
+ *      <li>parse - if set to true, minExpression and maxExpression will be evaluated to find min/max</li>
+ *      <li>minExpression - expression to calculate the minimum value (if none is specified, it will not be checked) </li>
+ *      <li>maxExpression - expression to calculate the maximum value (if none is specified, it will not be checked) </li>
+ * </ul>
+ *
+ * You can either use the min / max value or minExpression / maxExpression (when parse is set to true) -
+ * using expression can be slightly slower, see the example below.
+ * <!-- END SNIPPET: parameters -->
+ *
+ * <!-- START SNIPPET: parameters-warning -->
+ * Do not use ${minExpression} and ${maxExpression} as an expression as this will turn into infinitive loop!
+ * <!-- END SNIPPET: parameters-warning -->
+ *
+ * <pre>
+ * <!-- START SNIPPET: examples -->
+ * &lt;validators>
+ *      &lt;!-- Plain Validator Syntax --&gt;
+ *      &lt;validator type="int">
+ *          &lt;param name="fieldName"&gt;age&lt;/param&gt;
+ *          &lt;param name="min"&gt;20&lt;/param&gt;
+ *          &lt;param name="max"&gt;50&lt;/param&gt;
+ *          &lt;message&gt;Age needs to be between ${min} and ${max}&lt;/message&gt;
+ *      &lt;/validator&gt;
+ *
+ *      &lt;!-- Field Validator Syntax --&gt;
+ *      &lt;field name="age"&gt;
+ *          &lt;field-validator type="int"&gt;
+ *              &lt;param name="min"&gt;20&lt;/param&gt;
+ *              &lt;param name="max"&gt;50&lt;/param&gt;
+ *              &lt;message&gt;Age needs to be between ${min} and ${max}&lt;/message&gt;
+ *          &lt;/field-validator&gt;
+ *      &lt;/field&gt;
+ *
+ *      &lt;!-- Field Validator Syntax with expression --&gt;
+ *      &lt;field name="age"&gt;
+ *          &lt;field-validator type="int"&gt;
+ *              &lt;param name="minExpression"&gt;${minValue}&lt;/param&gt; &lt;!-- will be evaluated as: Integer getMinValue() --&gt;
+ *              &lt;param name="maxExpression"&gt;${maxValue}&lt;/param&gt; &lt;!-- will be evaluated as: Integer getMaxValue() --&gt;
+ *              &lt;message&gt;Age needs to be between ${min} and ${max}&lt;/message&gt;
+ *          &lt;/field-validator&gt;
+ *      &lt;/field&gt;
+ * &lt;/validators&gt;
+ * <!-- END SNIPPET: examples -->
+ * </pre>
+ *
+ * @author Jason Carreira
+ * @version $Date$ $Id$
+ */
+public final class IntRangeFieldValidator extends RangeValidatorSupport<Integer> {
+
+    public IntRangeFieldValidator() {
+        super(Integer.class);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/validator/validators/LongRangeFieldValidator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/LongRangeFieldValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/LongRangeFieldValidator.java
new file mode 100644
index 0000000..d5503c3
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/LongRangeFieldValidator.java
@@ -0,0 +1,82 @@
+/*
+ * 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;
+
+/**
+ * <!-- START SNIPPET: javadoc -->
+ * Field Validator that checks if the long specified is within a certain range.
+ * <!-- END SNIPPET: javadoc -->
+ *
+ *
+ * <!-- START SNIPPET: parameters -->
+ * <ul>
+ * 		<li>fieldName - The field name this validator is validating. Required if using Plain-Validator Syntax otherwise not required</li>
+ *      <li>min - the minimum value (if none is specified, it will not be checked) </li>
+ *      <li>max - the maximum value (if none is specified, it will not be checked) </li>
+ *      <li>parse - if set to true, minExpression and maxExpression will be evaluated to find min/max</li>
+ *      <li>minExpression - expression to calculate the minimum value (if none is specified, it will not be checked) </li>
+ *      <li>maxExpression - expression to calculate the maximum value (if none is specified, it will not be checked) </li>
+ * </ul>
+ *
+ * You can either use the min / max value or minExpression / maxExpression (when parse is set to true) -
+ * using expression can be slightly slower, see the example below.
+ * <!-- END SNIPPET: parameters -->
+ *
+ * <!-- START SNIPPET: parameters-warning -->
+ * Do not use ${minExpression} and ${maxExpression} as an expression as this will turn into infinitive loop!
+ * <!-- END SNIPPET: parameters-warning -->
+ *
+ * <pre>
+ * <!-- START SNIPPET: examples -->
+ * 	&lt;validators>
+ *      &lt;!-- Plain Validator Syntax --&gt;
+ *      &lt;validator type="long">
+ *          &lt;param name="fieldName"&gt;age&lt;/param&gt;
+ *          &lt;param name="min"&gt;20&lt;/param&gt;
+ *          &lt;param name="max"&gt;50&lt;/param&gt;
+ *          &lt;message&gt;Age needs to be between ${min} and ${max}&lt;/message&gt;
+ *      &lt;/validator&gt;
+ *
+ *      &lt;!-- Field Validator Syntax --&gt;
+ *      &lt;field name="age"&gt;
+ *          &lt;field-validator type="long"&gt;
+ *              &lt;param name="min"&gt;20&lt;/param&gt;
+ *              &lt;param name="max"&gt;50&lt;/param&gt;
+ *              &lt;message&gt;Age needs to be between ${min} and ${max}&lt;/message&gt;
+ *          &lt;/field-validator&gt;
+ *      &lt;/field&gt;
+ *
+ *      &lt;!-- Field Validator Syntax with expression --&gt;
+ *      &lt;field name="age"&gt;
+ *          &lt;field-validator type="long"&gt;
+ *              &lt;param name="minExpression"&gt;${minValue}&lt;/param&gt; &lt;!-- will be evaluated as: Long getMinValue() --&gt;
+ *              &lt;param name="maxExpression"&gt;${maxValue}&lt;/param&gt; &lt;!-- will be evaluated as: Long getMaxValue() --&gt;
+ *              &lt;message&gt;Age needs to be between ${min} and ${max}&lt;/message&gt;
+ *          &lt;/field-validator&gt;
+ *      &lt;/field&gt;
+ * &lt;/validators&gt;
+ * <!-- END SNIPPET: examples -->
+ * </pre>
+ *
+ * @version $Date$
+ */
+public final class LongRangeFieldValidator extends RangeValidatorSupport<Long> {
+
+    public LongRangeFieldValidator() {
+        super(Long.class);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/validator/validators/RangeValidatorSupport.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/RangeValidatorSupport.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/RangeValidatorSupport.java
new file mode 100644
index 0000000..39c0e86
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/RangeValidatorSupport.java
@@ -0,0 +1,102 @@
+/*
+ * 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 org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.LogManager;
+import com.opensymphony.xwork2.validator.ValidationException;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * Base class for range based validators. Use this class to develop any other custom range validators.
+ */
+public abstract class RangeValidatorSupport<T extends Comparable> extends FieldValidatorSupport {
+
+    private static final Logger LOG = LogManager.getLogger(RangeValidatorSupport.class);
+
+    private final Class<T> type;
+
+    private T min;
+    private String minExpression;
+    private T max;
+    private String maxExpression;
+
+    protected RangeValidatorSupport(Class<T> type) {
+        this.type = type;
+    }
+
+    public void validate(Object object) throws ValidationException {
+        Object obj = getFieldValue(getFieldName(), object);
+        Comparable<T> value = (Comparable<T>) obj;
+
+        // if there is no value - don't do comparison
+        // if a value is required, a required validator should be added to the field
+        if (value == null) {
+            return;
+        }
+
+        // only check for a minimum value if the min parameter is set
+        T minComparatorValue = getMin();
+        if ((minComparatorValue != null) && (value.compareTo(minComparatorValue) < 0)) {
+            addFieldError(getFieldName(), object);
+        }
+
+        // only check for a maximum value if the max parameter is set
+        T maxComparatorValue = getMax();
+        if ((maxComparatorValue != null) && (value.compareTo(maxComparatorValue) > 0)) {
+            addFieldError(getFieldName(), object);
+        }
+    }
+
+    public void setMin(T min) {
+        this.min = min;
+    }
+
+    public T getMin() {
+        if (min != null) {
+            return min;
+        } else if (StringUtils.isNotEmpty(minExpression)) {
+            return (T) parse(minExpression, type);
+        } else {
+            return null;
+        }
+    }
+
+    public void setMinExpression(String minExpression) {
+        LOG.debug("${minExpression} was defined as [{}]", minExpression);
+        this.minExpression = minExpression;
+    }
+
+    public void setMax(T max) {
+        this.max = max;
+    }
+
+    public T getMax() {
+        if (max != null) {
+            return max;
+        } else if (StringUtils.isNotEmpty(maxExpression)) {
+            return (T) parse(maxExpression, type);
+        } else {
+            return null;
+        }
+    }
+
+    public void setMaxExpression(String maxExpression) {
+        LOG.debug("${maxExpression} was defined as [{}]", maxExpression);
+        this.maxExpression = maxExpression;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/validator/validators/RegexFieldValidator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/RegexFieldValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/RegexFieldValidator.java
new file mode 100644
index 0000000..a107387
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/RegexFieldValidator.java
@@ -0,0 +1,213 @@
+/*
+ * 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 org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.LogManager;
+import com.opensymphony.xwork2.validator.ValidationException;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * <!-- START SNIPPET: javadoc -->
+ * Validates a string field using a regular expression.
+ * <!-- END SNIPPET: javadoc -->
+ *
+ * 
+ * <!-- START SNIPPET: parameters -->
+ * <ul>
+ * 	  <li>fieldName - The field name this validator is validating. Required if using Plain-Validator Syntax otherwise not required</li>
+ *    <li>regexp - The RegExp expression</li>
+ *    <li>caseSensitive - Boolean (Optional). Sets whether the expression should be matched against in a case-sensitive way. Default is <code>true</code>.</li>
+ *    <li>trim - Boolean (Optional). Sets whether the expression should be trimmed before matching. Default is <code>true</code>.</li>
+ *    <li>regexExpression - String (Optional). Defines regExp expression as an OGNL expression - will be evaluated to String</li>
+ *    <li>caseSensitiveExpression - String (Optional). Defines caseSensitive param as an OGNL expression - will be evaluated to Boolean.</li>
+ *    <li>trimExpression - String (Optional). Defines trim param as an OGNL expression - will be evaluated to Boolean</li>
+ * </ul>
+ * You can mix normal params with expression aware params but thus was not tested
+ * <!-- END SNIPPET: parameters -->
+ *
+ * <!-- START SNIPPET: parameters-warning -->
+ * Do not use ${regexExpression}, ${caseSensitiveExpression} and ${trimExpression} as an expression as this will turn into infinitive loop!
+ * <!-- END SNIPPET: parameters-warning -->
+ *
+ * <pre>
+ * <!-- START SNIPPET: example -->
+ * &lt;validators&gt;
+ *     &lt;!-- Plain Validator Syntax --&gt;
+ *     &lt;validator type="regex"&gt;
+ *         &lt;param name="fieldName"&gt;myStrangePostcode&lt;/param&gt;
+ *         &lt;param name="regex"&gt;&lt;![CDATA[([aAbBcCdD][123][eEfFgG][456])]]&gt;&lt;/param&gt;
+ *     &lt;/validator&gt;
+ *
+ *     &lt;!-- Field Validator Syntax --&gt;
+ *     &lt;field name="myStrangePostcode"&gt;
+ *         &lt;field-validator type="regex"&gt;
+ *             &lt;param name="regex"&gt;&lt;![CDATA[([aAbBcCdD][123][eEfFgG][456])]]&gt;&lt;/param&gt;
+ *         &lt;/field-validator&gt;
+ *     &lt;/field&gt;
+ *
+ *     &lt;!-- Field Validator Syntax with expressions --&gt;
+ *     &lt;field name="myStrangePostcode"&gt;
+ *         &lt;field-validator type="regex"&gt;
+ *             &lt;param name="regexExpression"&gt;${regexValue}&lt;/param&gt; &lt;!-- will be evaluated as: String getRegexValue() --&gt;
+ *             &lt;param name="caseSensitiveExpression"&gt;${caseSensitiveValue}&lt;/param&gt; &lt;!-- will be evaluated as: boolean getCaseSensitiveValue() --&gt;
+ *             &lt;param name="trimExpression"&gt;${trimValue}&lt;/param&gt; &lt;!-- will be evaluated as: boolean getTrimValue() --&gt;
+ *         &lt;/field-validator&gt;
+ *     &lt;/field&gt;
+ * &lt;/validators&gt;
+ * <!-- END SNIPPET: example -->
+ * </pre>
+ *
+ * @author Quake Wang
+ * @version $Date$ $Revision$
+ */
+public class RegexFieldValidator extends FieldValidatorSupport {
+
+    private static final Logger LOG = LogManager.getLogger(RegexFieldValidator.class);
+
+    private String regex;
+    private String regexExpression;
+    private Boolean caseSensitive = true;
+    private String caseSensitiveExpression = "";
+    private Boolean trim = true;
+    private String trimExpression = "";
+
+    public void validate(Object object) throws ValidationException {
+        String fieldName = getFieldName();
+        Object value = this.getFieldValue(fieldName, object);
+        // if there is no value - don't do comparison
+        // if a value is required, a required validator should be added to the field
+        String regexToUse = getRegex();
+        LOG.debug("Defined regexp as [{}]", regexToUse);
+
+        if (value == null || regexToUse == null) {
+            return;
+        }
+
+        // XW-375 - must be a string
+        if (!(value instanceof String)) {
+            return;
+        }
+
+        // string must not be empty
+        String str = ((String) value).trim();
+        if (str.length() == 0) {
+            return;
+        }
+
+        // match against expression
+        Pattern pattern;
+        if (isCaseSensitive()) {
+            pattern = Pattern.compile(regexToUse);
+        } else {
+            pattern = Pattern.compile(regexToUse, Pattern.CASE_INSENSITIVE);
+        }
+
+        String compare = (String) value;
+        if ( isTrimed() ) {
+            compare = compare.trim();
+        }
+        Matcher matcher = pattern.matcher( compare );
+
+        if (!matcher.matches()) {
+            addFieldError(fieldName, object);
+        }
+    }
+
+    /**
+     * @return Returns the regular expression to be matched.
+     */
+    public String getRegex() {
+        if (StringUtils.isNotEmpty(regex)) {
+            return regex;
+        } else if (StringUtils.isNotEmpty(regexExpression)) {
+            return (String) parse(regexExpression, String.class);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Sets the regular expression to be matched
+     */
+    public void setRegex(String regex) {
+        this.regex = regex;
+    }
+
+    /**
+     * Sets the regular expression as an OGNL expression to be matched
+     */
+    public void setRegexExpression(String regexExpression) {
+        this.regexExpression = regexExpression;
+    }
+
+    /**
+     * @return Returns whether the expression should be matched against in
+     *         a case-sensitive way.  Default is <code>true</code>.
+     */
+    public boolean isCaseSensitive() {
+        if (StringUtils.isNotEmpty(caseSensitiveExpression)) {
+            return (Boolean) parse(caseSensitiveExpression, Boolean.class);
+        }
+        return caseSensitive;
+    }
+
+    /**
+     * Sets whether the expression should be matched against in
+     * a case-sensitive way.  Default is <code>true</code>.
+     */
+    public void setCaseSensitive(Boolean caseSensitive) {
+        this.caseSensitive = caseSensitive;
+    }
+
+    /**
+     * Allows specify caseSensitive param as an OGNL expression
+     */
+    public void setCaseSensitiveExpression(String caseSensitiveExpression) {
+        this.caseSensitiveExpression = caseSensitiveExpression;
+    }
+
+    /**
+     * @return Returns whether the expression should be trimed before matching.
+     * Default is <code>true</code>.
+     */
+    public boolean isTrimed() {
+        if (StringUtils.isNotEmpty(trimExpression)) {
+            return (Boolean) parse(trimExpression, Boolean.class);
+        }
+        return trim;
+    }
+
+    /**
+     * Sets whether the expression should be trimed before matching.
+     * Default is <code>true</code>.
+     */
+    public void setTrim(Boolean trim) {
+        this.trim = trim;
+    }
+
+    /**
+     * Allows specify trim param as an OGNL expression
+     */
+    public void setTrimExpression(String trimExpression) {
+        this.trimExpression = trimExpression;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/validator/validators/RepopulateConversionErrorFieldValidatorSupport.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/RepopulateConversionErrorFieldValidatorSupport.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/RepopulateConversionErrorFieldValidatorSupport.java
new file mode 100644
index 0000000..6dcb60f
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/RepopulateConversionErrorFieldValidatorSupport.java
@@ -0,0 +1,203 @@
+/*
+ * 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.ActionInvocation;
+import com.opensymphony.xwork2.interceptor.PreResultListener;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.validator.ValidationException;
+import org.apache.commons.lang3.StringEscapeUtils;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ *
+ *
+ * An abstract base class that adds in the capability to populate the stack with
+ * a fake parameter map when a conversion error has occurred and the 'repopulateField'
+ * property is set to "true".
+ *
+ * <p/>
+ *
+ *
+ * <!-- START SNIPPET: javadoc -->
+ *
+ * The capability of auto-repopulating the stack with a fake parameter map when
+ * a conversion error has occurred can be done with 'repopulateField' property
+ * set to "true".
+ *
+ * <p/>
+ *
+ * This is typically usefull when one wants to repopulate the field with the original value
+ * when a conversion error occurred. Eg. with a textfield that only allows an Integer
+ * (the action class have an Integer field declared), upon conversion error, the incorrectly
+ * entered integer (maybe a text 'one') will not appear when dispatched back. With 'repopulateField'
+ * porperty set to true, it will, meaning the textfield will have 'one' as its value
+ * upon conversion error.
+ *
+ * <!-- END SNIPPET: javadoc -->
+ *
+ * <p/>
+ *
+ * <pre>
+ * <!-- START SNIPPET: exampleJspPage -->
+ *
+ * &lt;!-- myJspPage.jsp --&gt;
+ * &lt;ww:form action="someAction" method="POST"&gt;
+ *   ....
+ *   &lt;ww:textfield
+ *       label="My Integer Field"
+ *       name="myIntegerField" /&gt;
+ *   ....
+ *   &lt;ww:submit /&gt;
+ * &lt;/ww:form&gt;
+ *
+ * <!-- END SNIPPET: exampleJspPage -->
+ * </pre>
+ *
+ * <pre>
+ * <!-- START SNIPPET: exampleXwork -->
+ *
+ * &lt;!-- xwork.xml --&gt;
+ * &lt;xwork&gt;
+ * &lt;include file="xwork-default.xml" /&gt;
+ * ....
+ * &lt;package name="myPackage" extends="xwork-default"&gt;
+ *   ....
+ *   &lt;action name="someAction" class="example.MyActionSupport.java"&gt;
+ *      &lt;result name="input"&gt;myJspPage.jsp&lt;/result&gt;
+ *      &lt;result&gt;success.jsp&lt;/result&gt;
+ *   &lt;/action&gt;
+ *   ....
+ * &lt;/package&gt;
+ * ....
+ * &lt;/xwork&gt;
+ *
+ * <!-- END SNIPPET:exampleXwork -->
+ * </pre>
+ *
+ *
+ * <pre>
+ * <!-- START SNIPPET: exampleJava -->
+ *
+ * &lt;!-- MyActionSupport.java --&gt;
+ * public class MyActionSupport extends ActionSupport {
+ *    private Integer myIntegerField;
+ *
+ *    public Integer getMyIntegerField() { return this.myIntegerField; }
+ *    public void setMyIntegerField(Integer myIntegerField) {
+ *       this.myIntegerField = myIntegerField;
+ *    }
+ * }
+ *
+ * <!-- END SNIPPET: exampleJava -->
+ * </pre>
+ *
+ *
+ * <pre>
+ * <!-- START SNIPPET: exampleValidation -->
+ *
+ * &lt;!-- MyActionSupport-someAction-validation.xml --&gt;
+ * &lt;validators&gt;
+ *   ...
+ *   &lt;field name="myIntegerField"&gt;
+ *      &lt;field-validator type="conversion"&gt;
+ *         &lt;param name="repopulateField"&gt;true&lt;/param&gt;
+ *         &lt;message&gt;Conversion Error (Integer Wanted)&lt;/message&gt;
+ *      &lt;/field-validator&gt;
+ *   &lt;/field&gt;
+ *   ...
+ * &lt;/validators&gt;
+ *
+ * <!-- END SNIPPET: exampleValidation -->
+ * </pre>
+ *
+ * @author tm_jee
+ * @version $Date$ $Id$
+ */
+public abstract class RepopulateConversionErrorFieldValidatorSupport extends FieldValidatorSupport {
+
+    private static final Logger LOG = LogManager.getLogger(RepopulateConversionErrorFieldValidatorSupport.class);
+
+    private boolean repopulateField = false;
+
+    public boolean isRepopulateField() {
+        return repopulateField;
+    }
+
+    public void setRepopulateField(boolean repopulateField) {
+        this.repopulateField = repopulateField;
+    }
+
+    public void validate(Object object) throws ValidationException {
+        doValidate(object);
+        if (repopulateField) {
+            repopulateField(object);
+        }
+    }
+
+    public void repopulateField(Object object) throws ValidationException {
+
+        ActionInvocation invocation = ActionContext.getContext().getActionInvocation();
+        Map<String, Object> conversionErrors = ActionContext.getContext().getConversionErrors();
+
+        String fieldName = getFieldName();
+        String fullFieldName = getValidatorContext().getFullFieldName(fieldName);
+        if (conversionErrors.containsKey(fullFieldName)) {
+            Object value = conversionErrors.get(fullFieldName);
+
+            final Map<Object, Object> fakeParams = new LinkedHashMap<Object, Object>();
+            boolean doExprOverride = false;
+
+            if (value instanceof String[]) {
+                // take the first element, if possible
+                String[] tmpValue = (String[]) value;
+                if ((tmpValue.length > 0)) {
+                    doExprOverride = true;
+                    fakeParams.put(fullFieldName, escape(tmpValue[0]));
+                } else {
+                    LOG.warn("value is an empty array of String or with first element in it as null [{}], will not repopulate conversion error", value);
+                }
+            } else if (value instanceof String) {
+                String tmpValue = (String) value;
+                doExprOverride = true;
+                fakeParams.put(fullFieldName, escape(tmpValue));
+            } else {
+                // opps... it should be 
+                LOG.warn("conversion error value is not a String or array of String but instead is [{}], will not repopulate conversion error", value);
+            }
+
+            if (doExprOverride) {
+                invocation.addPreResultListener(new PreResultListener() {
+                    public void beforeResult(ActionInvocation invocation, String resultCode) {
+                        ValueStack stack = ActionContext.getContext().getValueStack();
+                        stack.setExprOverrides(fakeParams);
+                    }
+                });
+            }
+        }
+    }
+
+    protected String escape(String value) {
+        return "\"" + StringEscapeUtils.escapeJava(value) + "\"";
+    }
+
+    protected abstract void doValidate(Object object) throws ValidationException;
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/validator/validators/RequiredFieldValidator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/RequiredFieldValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/RequiredFieldValidator.java
new file mode 100644
index 0000000..6b103f2
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/RequiredFieldValidator.java
@@ -0,0 +1,72 @@
+/*
+ * 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.validator.ValidationException;
+
+
+/**
+ * <!-- START SNIPPET: javadoc -->
+ * RequiredFieldValidator checks if the specified field is not null.
+ * <!-- 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>
+ * </ul>
+ * <!-- END SNIPPET: parameters -->
+ * 
+ * 
+ * <pre>
+ * <!-- START SNIPPET: example -->
+ * 	   &lt;validators&gt;
+ * 
+ *         &lt;!-- Plain Validator Syntax --&gt;
+ *         &lt;validator type="required"&gt;
+ *             &lt;param name="fieldName"&gt;username&lt;/param&gt;
+ *             &lt;message&gt;username must not be null&lt;/message&gt;
+ *         &lt;/validator&gt;
+ * 
+ * 
+ *         &lt;!-- Field Validator Syntax --&gt;
+ *         &lt;field name="username"&gt;
+ *             &lt;field-validator type="required"&gt;
+ *             	   &lt;message&gt;username must not be null&lt;/message&gt;
+ *             &lt;/field-validator&gt;
+ *         &lt;/field&gt;
+ * 
+ *     &lt;/validators&gt;
+ * <!-- END SNIPPET: example -->
+ * </pre>
+ * 
+ * 
+ *
+ * @author rainerh
+ * @version $Revision$
+ */
+public class RequiredFieldValidator extends FieldValidatorSupport {
+
+    public void validate(Object object) throws ValidationException {
+        String fieldName = getFieldName();
+        Object value = this.getFieldValue(fieldName, object);
+
+        if (value == null) {
+            addFieldError(fieldName, object);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/validator/validators/RequiredStringValidator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/RequiredStringValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/RequiredStringValidator.java
new file mode 100644
index 0000000..7b2cbfd
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/RequiredStringValidator.java
@@ -0,0 +1,108 @@
+/*
+ * 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.validator.ValidationException;
+
+
+/**
+ * <!-- START SNIPPET: javadoc -->
+ * RequiredStringValidator checks that a String field is non-null and has a length > 0.
+ * (i.e. it isn't "").  The "trim" parameter determines whether it will {@link String#trim() trim}
+ * the String before performing the length check.  If unspecified, the String will be trimmed.
+ * <!-- END SNIPPET: javadoc -->
+ * <p/>
+ *
+ * <!-- START SNIPPET: parameters -->
+ * <ul>
+ * 		<li>fieldName - The field name this validator is validating. Required if using Plain-Validator Syntax otherwise not required</li>
+ *      <li>trim - (Optional) Boolean, default true. Trims the field name value before validating.</li>
+ *      <li>trimExpression - (Optional) String. Specifies the trim param as an OGNL expression.</li>
+ * </ul>
+ * <!-- END SNIPPET: parameters -->
+ * 
+ * <!-- START SNIPPET: parameters-warning -->
+ * Do not use ${trimExpression} as an expression as this will turn into infinitive loop!
+ * <!-- END SNIPPET: parameters-warning -->
+ *
+ * <pre>
+ * <!-- START SNIPPET: examples -->
+ *     &lt;validators&gt;
+ *         &lt;!-- Plain-Validator Syntax --&gt;
+ *         &lt;validator type="requiredstring"&gt;
+ *             &lt;param name="fieldName"&gt;username&lt;/param&gt;
+ *             &lt;param name="trim"&gt;true&lt;/param&gt;
+ *             &lt;message&gt;username is required&lt;/message&gt;
+ *         &lt;/validator&gt;
+ *         
+ *         &lt;!-- Field-Validator Syntax --&gt;
+ *         &lt;field name="username"&gt;
+ *         	  &lt;field-validator type="requiredstring"&gt;
+ *                 &lt;param name="trim"&gt;true&lt;/param&gt;
+ *                 &lt;message&gt;username is required&lt;/message&gt;
+ *            &lt;/field-validator&gt;
+ *         &lt;/field&gt;
+ *
+ *         &lt;!-- Field-Validator Syntax with expression --&gt;
+ *         &lt;field name="username"&gt;
+ *         	  &lt;field-validator type="requiredstring"&gt;
+ *                 &lt;param name="trimExpression"&gt;${trimValue}&lt;/param&gt; &lt;!-- will be evaluated as: boolean getTrimValue() --&gt;
+ *                 &lt;message&gt;username is required&lt;/message&gt;
+ *            &lt;/field-validator&gt;
+ *         &lt;/field&gt;
+ *     &lt;/validators&gt;
+ * <!-- END SNIPPET: examples -->
+ * </pre>
+ * 
+ * @author rainerh
+ * @version $Date$ $Id$
+ */
+public class RequiredStringValidator extends FieldValidatorSupport {
+
+    private boolean trim = true;
+
+    public void setTrim(boolean trim) {
+        this.trim = trim;
+    }
+
+    public void setTrimExpression(String trimExpression) {
+        trim = (Boolean) parse(trimExpression, Boolean.class);
+    }
+
+    public boolean isTrim() {
+        return trim;
+    }
+
+    public void validate(Object object) throws ValidationException {
+        String fieldName = getFieldName();
+        Object value = this.getFieldValue(fieldName, object);
+
+        if (!(value instanceof String)) {
+            addFieldError(fieldName, object);
+        } else {
+            String s = (String) value;
+
+            if (trim) {
+                s = s.trim();
+            }
+
+            if (s.length() == 0) {
+                addFieldError(fieldName, object);
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/validator/validators/ShortRangeFieldValidator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/ShortRangeFieldValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/ShortRangeFieldValidator.java
new file mode 100644
index 0000000..24a20e2
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/ShortRangeFieldValidator.java
@@ -0,0 +1,82 @@
+/*
+ * 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;
+
+/**
+ * <!-- START SNIPPET: javadoc -->
+ * Field Validator that checks if the short specified is within a certain range.
+ * <!-- END SNIPPET: javadoc -->
+ *
+ *
+ * <!-- START SNIPPET: parameters -->
+ * <ul>
+ *      <li>fieldName - The field name this validator is validating. Required if using Plain-Validator Syntax otherwise not required</li>
+ *      <li>min - the minimum value (if none is specified, it will not be checked) </li>
+ *      <li>max - the maximum value (if none is specified, it will not be checked) </li>
+ *      <li>parse - if set to true, minExpression and maxExpression will be evaluated to find min/max</li>
+ *      <li>minExpression - expression to calculate the minimum value (if none is specified, it will not be checked) </li>
+ *      <li>maxExpression - expression to calculate the maximum value (if none is specified, it will not be checked) </li>
+ * </ul>
+ *
+ * You can either use the min / max value or minExpression / maxExpression (when parse is set to true) -
+ * using expression can be slightly slower, see the example below.
+ * <!-- END SNIPPET: parameters -->
+ *
+ * <!-- START SNIPPET: parameters-warning -->
+ * Do not use ${minExpression} and ${maxExpression} as an expression as this will turn into infinitive loop!
+ * <!-- END SNIPPET: parameters-warning -->
+ *
+ * <pre>
+ * <!-- START SNIPPET: examples -->
+ *  &lt;validators>
+ *      &lt;!-- Plain Validator Syntax --&gt;
+ *      &lt;validator type="short">
+ *          &lt;param name="fieldName"&gt;age&lt;/param&gt;
+ *          &lt;param name="min"&gt;20&lt;/param&gt;
+ *          &lt;param name="max"&gt;50&lt;/param&gt;
+ *          &lt;message&gt;Age needs to be between ${min} and ${max}&lt;/message&gt;
+ *      &lt;/validator&gt;
+ *
+ *      &lt;!-- Field Validator Syntax --&gt;
+ *      &lt;field name="age"&gt;
+ *          &lt;field-validator type="short"&gt;
+ *              &lt;param name="min"&gt;20&lt;/param&gt;
+ *              &lt;param name="max"&gt;50&lt;/param&gt;
+ *              &lt;message&gt;Age needs to be between ${min} and ${max}&lt;/message&gt;
+ *          &lt;/field-validator&gt;
+ *      &lt;/field&gt;
+ *
+ *      &lt;!-- Field Validator Syntax with expression --&gt;
+ *      &lt;field name="age"&gt;
+ *          &lt;field-validator type="short"&gt;
+ *              &lt;param name="minExpression"&gt;${minValue}&lt;/param&gt; &lt;!-- will be evaluated as: Short getMinValue() --&gt;
+ *              &lt;param name="maxExpression"&gt;${maxValue}&lt;/param&gt; &lt;!-- will be evaluated as: Short getMaxValue() --&gt;
+ *              &lt;message&gt;Age needs to be between ${min} and ${max}&lt;/message&gt;
+ *          &lt;/field-validator&gt;
+ *      &lt;/field&gt;
+ *  &lt;/validators&gt;
+ * <!-- END SNIPPET: examples -->
+ * </pre>
+ *
+ * @version $Date$
+ */
+public final class ShortRangeFieldValidator extends RangeValidatorSupport<Short> {
+
+    public ShortRangeFieldValidator() {
+        super(Short.class);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/validator/validators/StringLengthFieldValidator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/StringLengthFieldValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/StringLengthFieldValidator.java
new file mode 100644
index 0000000..47916d0
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/StringLengthFieldValidator.java
@@ -0,0 +1,169 @@
+/*
+ * 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.validator.ValidationException;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * <!-- START SNIPPET: javadoc -->
+ * StringLengthFieldValidator checks that a String field is of a certain length.  If the "minLength"
+ * parameter is specified, it will make sure that the String has at least that many characters.  If
+ * the "maxLength" parameter is specified, it will make sure that the String has at most that many
+ * characters.  The "trim" parameter determines whether it will {@link String#trim() trim} the
+ * String before performing the length check.  If unspecified, the String will be trimmed.
+ * <!-- END SNIPPET: javadoc -->
+ * <p/>
+ * <p/>
+ * <p/>
+ * <!-- START SNIPPET: parameters -->
+ * <ul>
+ * <li>fieldName - The field name this validator is validating. Required if using Plain-Validator Syntax otherwise not required</li>
+ * <li>maxLength - Integer. The max length of the field value. Default ignore.</li>
+ * <li>minLength - Integer. The min length of the field value. Default ignore.</li>
+ * <li>trim - (Optional) Boolean, default true. Trim the field value before evaluating its min/max length. Default true.</li>
+ * <li>maxLengthExpression - (Optional) String. Defines the max length param as an OGNL expression</li>
+ * <li>minLengthExpression - (Optional) String. Defines the min length param as an OGNL expression</li>
+ * <li>trimExpression - (Optional) String. Defines th trim param as an OGNL expression</li>
+ * </ul>
+ * <!-- END SNIPPET: parameters -->
+ * <p/>
+ * <!-- START SNIPPET: parameters-warning -->
+ * Do not use ${minLengthExpression}, ${maxLengthExpression} and ${trimExpression} as an expression as this will turn into infinitive loop!
+ * <!-- END SNIPPET: parameters-warning -->
+ * <p/>
+ * <pre>
+ * <!--START SNIPPET: example -->
+ * &lt;validators&gt;
+ *     &lt;!-- Plain Validator Syntax --&gt;
+ *     &lt;validator type="stringlength"&gt;
+ *         &lt;param name="fieldName"&gt;myPurchaseCode&lt;/param&gt;
+ *         &lt;param name="minLength"&gt;10&lt;/param&gt;
+ *         &lt;param name="maxLength"&gt;10&lt;/param&gt;
+ *         &lt;param name="trim"&gt;true&lt;/param&gt;
+ *         &lt;message&gt;Your purchase code needs to be 10 characters long&lt;/message&gt;
+ *     &lt;/validator&gt;
+ *
+ *     &lt;!-- Field Validator Syntax --&gt;
+ *     &lt;field name="myPurchaseCode"&gt;
+ *         &lt;field-validator type="stringlength"&gt;
+ *              &lt;param name="minLength"&gt;10&lt;/param&gt;
+ *              &lt;param name="maxLength"&gt;10&lt;/param&gt;
+ *              &lt;param name="trim"&gt;true&lt;/param&gt;
+ *              &lt;message&gt;Your purchase code needs to be 10 characters long&lt;/message&gt;
+ *         &lt;/field-validator&gt;
+ *     &lt;/field&gt;
+ *
+ *     &lt;!-- Field Validator Syntax with expression --&gt;
+ *     &lt;field name="myPurchaseCode"&gt;
+ *         &lt;field-validator type="stringlength"&gt;
+ *              &lt;param name="minLengthExpression"&gt;${minLengthValue}&lt;/param&gt; &lt;!-- will be evaluated as: Integer getMinLengthValue() --&gt;
+ *              &lt;param name="maxLengthExpression"&gt;${maxLengthValue}&lt;/param&gt; &lt;!-- will be evaluated as: Integer getMaxLengthValue() --&gt;
+ *              &lt;param name="trimExpression"&gt;${trimValue}&lt;/param&gt; &lt;!-- will be evaluated as: boolean getTrimValue() --&gt;
+ *              &lt;message&gt;Your purchase code needs to be 10 characters long&lt;/message&gt;
+ *         &lt;/field-validator&gt;
+ *     &lt;/field&gt;
+ * &lt;/validators&gt;
+ * <!-- END SNIPPET: example -->
+ * </pre>
+ *
+ * @author Jason Carreira
+ * @author Mark Woon
+ * @author tmjee
+ * @version $Date$ $Id$
+ */
+public class StringLengthFieldValidator extends FieldValidatorSupport {
+
+    private boolean trim = true;
+    private int maxLength = -1;
+    private int minLength = -1;
+
+    private String maxLengthExpression;
+    private String minLengthExpression;
+    private String trimExpression;
+
+    public void setMaxLength(int maxLength) {
+        this.maxLength = maxLength;
+    }
+
+    public void setMaxLengthExpression(String maxLengthExpression) {
+        this.maxLengthExpression = maxLengthExpression;
+    }
+
+    public int getMaxLength() {
+        if (StringUtils.isNotEmpty(maxLengthExpression)) {
+            return (Integer) parse(maxLengthExpression, Integer.class);
+        }
+        return maxLength;
+    }
+
+    public void setMinLength(int minLength) {
+        this.minLength = minLength;
+    }
+
+    public void setMinLengthExpression(String minLengthExpression) {
+        this.minLengthExpression = minLengthExpression;
+    }
+
+    public int getMinLength() {
+        if (StringUtils.isNotEmpty(minLengthExpression)) {
+            return (Integer) parse(minLengthExpression, Integer.class);
+        }
+        return minLength;
+    }
+
+    public void setTrim(boolean trim) {
+        this.trim = trim;
+    }
+
+    public void setTrimExpression(String trimExpression) {
+        this.trimExpression = trimExpression;
+    }
+
+    public boolean isTrim() {
+        if (StringUtils.isNotEmpty(trimExpression)) {
+            return (Boolean) parse(trimExpression, Boolean.class);
+        }
+        return trim;
+    }
+
+    public void validate(Object object) throws ValidationException {
+        String fieldName = getFieldName();
+        String val = (String) getFieldValue(fieldName, object);
+
+        if (StringUtils.isEmpty(val)) {
+            // use a required validator for these
+            return;
+        }
+        if (isTrim()) {
+            val = val.trim();
+            if (val.length() <= 0) {
+                // use a required validator
+                return;
+            }
+        }
+
+        int minLengthToUse = getMinLength();
+        int maxLengthToUse = getMaxLength();
+
+        if ((minLengthToUse > -1) && (val.length() < minLengthToUse)) {
+            addFieldError(fieldName, object);
+        } else if ((maxLengthToUse > -1) && (val.length() > maxLengthToUse)) {
+            addFieldError(fieldName, object);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/validator/validators/URLValidator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/URLValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/URLValidator.java
new file mode 100644
index 0000000..767416d
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/URLValidator.java
@@ -0,0 +1,101 @@
+/*
+ * 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.validator.ValidationException;
+import com.opensymphony.xwork2.util.URLUtil;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * URLValidator checks that a given field is a String and a valid URL
+ *
+ * <pre>
+ * &lt;validators&gt;
+ *      &lt;!-- Plain Validator Syntax --&gt;
+ *      &lt;validator type="url"&gt;
+ *          &lt;param name="fieldName"&gt;myHomePage&lt;/param&gt;
+ *          &lt;message&gt;Invalid homepage url&lt;/message&gt;
+ *      &lt;/validator&gt;
+ *
+ *      &lt;!-- Field Validator Syntax --&gt;
+ *      &lt;field name="myHomepage"&gt;
+ *          &lt;field-validator type="url"&gt;
+ *              &lt;message&gt;Invalid homepage url&lt;/message&gt;
+ *          &lt;/field-validator&gt;
+ *      &lt;/field&gt;
+ * &lt;/validators&gt;
+ * </pre>
+ */
+public class URLValidator extends FieldValidatorSupport {
+
+    private String urlRegex;
+    private String urlRegexExpression;
+
+    public void validate(Object object) throws ValidationException {
+        String fieldName = getFieldName();
+        Object value = this.getFieldValue(fieldName, object);
+
+        // if there is no value - don't do comparison
+        // if a value is required, a required validator should be added to the field
+        if (value == null || value.toString().length() == 0) {
+            return;
+        }
+
+        // FIXME deprecated! the same regex below should be used instead
+        // replace logic with next major release
+        if (!(value.getClass().equals(String.class)) || !URLUtil.verifyUrl((String) value)) {
+            addFieldError(fieldName, object);
+        }
+    }
+
+    /**
+     * This is used to support client-side validation, it's based on
+     * http://stackoverflow.com/questions/161738/what-is-the-best-regular-expression-to-check-if-a-string-is-a-valid-url
+     *
+     * @return regex to validate URLs
+     */
+    public String getUrlRegex() {
+        if (StringUtils.isNotEmpty(urlRegexExpression)) {
+            return (String) parse(urlRegexExpression, String.class);
+        } else if (StringUtils.isNotEmpty(urlRegex)) {
+            return urlRegex;
+        } else {
+            return "^(https?|ftp):\\/\\/" +
+                    "(([a-z0-9$_\\.\\+!\\*\\'\\(\\),;\\?&=-]|%[0-9a-f]{2})+" +
+                    "(:([a-z0-9$_\\.\\+!\\*\\'\\(\\),;\\?&=-]|%[0-9a-f]{2})+)?" +
+                    "@)?(#?" +
+                    ")((([a-z0-9]\\.|[a-z0-9][a-z0-9-]*[a-z0-9]\\.)*" +
+                    "[a-z][a-z0-9-]*[a-z0-9]" +
+                    "|((\\d|[1-9]\\d|1\\d{2}|2[0-4][0-9]|25[0-5])\\.){3}" +
+                    "(\\d|[1-9]\\d|1\\d{2}|2[0-4][0-9]|25[0-5])" +
+                    ")(:\\d+)?" +
+                    ")(((\\/+([a-z0-9$_\\.\\+!\\*\\'\\(\\),;:@&=-]|%[0-9a-f]{2})*)*" +
+                    "(\\?([a-z0-9$_\\.\\+!\\*\\'\\(\\),;:@&=-]|%[0-9a-f]{2})*)" +
+                    "?)?)?" +
+                    "(#([a-z0-9$_\\.\\+!\\*\\'\\(\\),;:@&=-]|%[0-9a-f]{2})*)?" +
+                    "$";
+        }
+    }
+
+    public void setUrlRegex(String urlRegex) {
+        this.urlRegex = urlRegex;
+    }
+
+    public void setUrlRegexExpression(String urlRegexExpression) {
+        this.urlRegexExpression = urlRegexExpression;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/main/java/com/opensymphony/xwork2/validator/validators/ValidatorSupport.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/ValidatorSupport.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/ValidatorSupport.java
new file mode 100644
index 0000000..1ca43b0
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/ValidatorSupport.java
@@ -0,0 +1,205 @@
+/*
+ * 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.util.TextParseUtil;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.validator.*;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * Abstract implementation of the Validator interface suitable for subclassing.
+ *
+ * @author Jason Carreira
+ * @author tm_jee
+ * @author Martin Gilday
+ */
+public abstract class ValidatorSupport implements Validator, ShortCircuitableValidator {
+
+    protected final Logger log = LogManager.getLogger(this.getClass());
+
+    protected String defaultMessage = "";
+    protected String messageKey;
+    private ValidatorContext validatorContext;
+    private boolean shortCircuit;
+    private String type;
+    private String[] messageParameters;
+    protected ValueStack stack;
+
+
+    public void setValueStack(ValueStack stack) {
+        this.stack = stack;
+    }
+
+    public void setDefaultMessage(String message) {
+        if (StringUtils.isNotEmpty(message)) {
+            this.defaultMessage = message;
+        }
+    }
+
+    public String getDefaultMessage() {
+        return defaultMessage;
+    }
+
+    public String getMessage(Object object) {
+        String message;
+        boolean pop = false;
+
+        if (!stack.getRoot().contains(object)) {
+            stack.push(object);
+            pop = true;
+        }
+
+        stack.push(this);
+
+        if (messageKey != null) {
+            if ((defaultMessage == null) || ("".equals(defaultMessage.trim()))) {
+                defaultMessage = messageKey;
+            }
+            if (validatorContext == null) {
+                validatorContext = new DelegatingValidatorContext(object);
+            }
+            List<Object> parsedMessageParameters = null;
+            if (messageParameters != null) {
+                parsedMessageParameters = new ArrayList<>();
+                for (String messageParameter : messageParameters) {
+                    if (messageParameter != null) {
+                        try {
+                            Object val = stack.findValue(messageParameter);
+                            parsedMessageParameters.add(val);
+                        } catch (Exception e) {
+                            // if there's an exception in parsing, we'll just treat the expression itself as the
+                            // parameter
+                            log.warn("exception while parsing message parameter [{}]", messageParameter, e);
+                            parsedMessageParameters.add(messageParameter);
+                        }
+                    }
+                }
+            }
+
+            message = validatorContext.getText(messageKey, defaultMessage, parsedMessageParameters);
+        } else {
+            message = defaultMessage;
+        }
+
+        if (StringUtils.isNotBlank(message))
+            message = TextParseUtil.translateVariables(message, stack);
+
+        stack.pop();
+
+        if (pop) {
+            stack.pop();
+        }
+
+        return message;
+    }
+
+    public void setMessageKey(String key) {
+        messageKey = key;
+    }
+
+    public String getMessageKey() {
+        return messageKey;
+    }
+
+    public String[] getMessageParameters() {
+        return this.messageParameters;
+    }
+
+    public void setMessageParameters(String[] messageParameters) {
+        this.messageParameters = messageParameters;
+    }
+
+    public void setShortCircuit(boolean shortcircuit) {
+        shortCircuit = shortcircuit;
+    }
+
+    public boolean isShortCircuit() {
+        return shortCircuit;
+    }
+
+    public void setValidatorContext(ValidatorContext validatorContext) {
+        this.validatorContext = validatorContext;
+    }
+
+    public ValidatorContext getValidatorContext() {
+        return validatorContext;
+    }
+
+    public void setValidatorType(String type) {
+        this.type = type;
+    }
+
+    public String getValidatorType() {
+        return type;
+    }
+
+    /**
+     * Parse <code>expression</code> passed in against value stack.
+     *
+     * @param expression an OGNL expression
+     * @param type type to return
+     * @return Object
+     */
+    protected Object parse(String expression, Class type) {
+        if (expression == null) {
+            return null;
+        }
+        return TextParseUtil.translateVariables('$', expression, stack, type);
+    }
+
+    /**
+     * Return the field value named <code>name</code> from <code>object</code>,
+     * <code>object</code> should have the appropriate getter/setter.
+     *
+     * @param name name of the field
+     * @param object to search field name on
+     * @return Object as field value
+     * @throws ValidationException
+     */
+    protected Object getFieldValue(String name, Object object) throws ValidationException {
+
+        boolean pop = false;
+
+        if (!stack.getRoot().contains(object)) {
+            stack.push(object);
+            pop = true;
+        }
+
+        Object retVal = stack.findValue(name);
+
+        if (pop) {
+            stack.pop();
+        }
+
+        return retVal;
+    }
+
+    protected void addActionError(Object object) {
+        validatorContext.addActionError(getMessage(object));
+    }
+
+    protected void addFieldError(String propertyName, Object object) {
+        validatorContext.addFieldError(propertyName, getMessage(object));
+    }
+
+}


Mime
View raw message