diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/validator/AnnotationValidationConfigurationBuilder.java b/xwork-core/src/main/java/com/opensymphony/xwork2/validator/AnnotationValidationConfigurationBuilder.java
index d26e5b410..fde9f8172 100644
--- a/xwork-core/src/main/java/com/opensymphony/xwork2/validator/AnnotationValidationConfigurationBuilder.java
+++ b/xwork-core/src/main/java/com/opensymphony/xwork2/validator/AnnotationValidationConfigurationBuilder.java
@@ -16,6 +16,7 @@
package com.opensymphony.xwork2.validator;
import com.opensymphony.xwork2.validator.annotations.*;
+import org.apache.commons.lang3.StringUtils;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
@@ -559,12 +560,16 @@ public class AnnotationValidationConfigurationBuilder {
.build();
}
- private Date parseDateString(String value) {
+ private Date parseDateString(String value, String format) {
+ SimpleDateFormat d0 = null;
+ if (StringUtils.isNotEmpty(format)) {
+ d0 = new SimpleDateFormat(format);
+ }
SimpleDateFormat d1 = (SimpleDateFormat) DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.LONG, Locale.getDefault());
SimpleDateFormat d2 = (SimpleDateFormat)DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM, Locale.getDefault());
SimpleDateFormat d3 = (SimpleDateFormat)DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, Locale.getDefault());
- SimpleDateFormat[] dfs = {d1, d2, d3};
+ SimpleDateFormat[] dfs = (d0 != null ? new SimpleDateFormat[]{d0, d1, d2, d3} : new SimpleDateFormat[]{d1, d2, d3});
for (SimpleDateFormat df : dfs)
try {
Date check = df.parse(value);
@@ -574,7 +579,6 @@ public class AnnotationValidationConfigurationBuilder {
} catch (ParseException ignore) {
}
return null;
-
}
private ValidatorConfig processRequiredStringValidatorAnnotation(RequiredStringValidator v, String fieldName, String methodName) {
@@ -767,12 +771,19 @@ public class AnnotationValidationConfigurationBuilder {
params.put("fieldName", v.fieldName());
}
if ( v.min() != null && v.min().length() > 0) {
- final Date minDate = parseDateString(v.min());
- params.put("min", String.valueOf(minDate == null ? v.min() : minDate));
+ final Date minDate = parseDateString(v.min(), v.dateFormat());
+ params.put("min", minDate == null ? v.min() : minDate);
}
if ( v.max() != null && v.max().length() > 0) {
- final Date maxDate = parseDateString(v.max());
- params.put("max", String.valueOf(maxDate == null ? v.max() : maxDate));
+ final Date maxDate = parseDateString(v.max(), v.dateFormat());
+ params.put("max", maxDate == null ? v.max() : maxDate);
+ }
+
+ if (StringUtils.isNotEmpty(v.minExpression())) {
+ params.put("minExpression", v.minExpression());
+ }
+ if (StringUtils.isNotEmpty(v.maxExpression())) {
+ params.put("maxExpression", v.maxExpression());
}
validatorFactory.lookupRegisteredValidatorType(validatorType);
@@ -782,6 +793,7 @@ public class AnnotationValidationConfigurationBuilder {
.shortCircuit(v.shortCircuit())
.defaultMessage(v.message())
.messageKey(v.key())
+ .messageParams(v.messageParams())
.build();
}
diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/validator/annotations/DateRangeFieldValidator.java b/xwork-core/src/main/java/com/opensymphony/xwork2/validator/annotations/DateRangeFieldValidator.java
index fd47fce8d..c6b81b70f 100644
--- a/xwork-core/src/main/java/com/opensymphony/xwork2/validator/annotations/DateRangeFieldValidator.java
+++ b/xwork-core/src/main/java/com/opensymphony/xwork2/validator/annotations/DateRangeFieldValidator.java
@@ -55,6 +55,12 @@ import java.lang.annotation.Target;
*
i18n key from language specific properties file. |
*
*
+ * | messageParams |
+ * no |
+ * |
+ * Additional params to be used to customize message - will be evaluated against the Value Stack |
+ *
+ *
* | fieldName |
* no |
* |
@@ -109,11 +115,26 @@ public @interface DateRangeFieldValidator {
*/
String min() default "";
+ /**
+ * An expression which will be evaluated against the Value Stack to get the min value
+ */
+ String minExpression() default "";
+
/**
* Date property. The maximum date can be.
*/
String max() default "";
+ /**
+ * An expression which will be evaluated against the Value Stack to get the max value
+ */
+ String maxExpression() default "";
+
+ /**
+ * Date format used to parse min and mac value
+ */
+ String dateFormat() default "";
+
/**
* The default error message for this validator.
* NOTE: It is required to set a message, if you are not using the message key for 18n lookup!
@@ -125,6 +146,11 @@ public @interface DateRangeFieldValidator {
*/
String key() default "";
+ /**
+ * Additional params to be used to customize message - will be evaluated against the Value Stack
+ */
+ String[] messageParams() default {};
+
/**
* The optional fieldName for SIMPLE validator types.
*/
diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/validator/validators/AbstractRangeValidator.java b/xwork-core/src/main/java/com/opensymphony/xwork2/validator/validators/AbstractRangeValidator.java
index 2ffaaba2d..aa17a0e8b 100644
--- a/xwork-core/src/main/java/com/opensymphony/xwork2/validator/validators/AbstractRangeValidator.java
+++ b/xwork-core/src/main/java/com/opensymphony/xwork2/validator/validators/AbstractRangeValidator.java
@@ -18,6 +18,7 @@ package com.opensymphony.xwork2.validator.validators;
import com.opensymphony.xwork2.util.logging.Logger;
import com.opensymphony.xwork2.util.logging.LoggerFactory;
import com.opensymphony.xwork2.validator.ValidationException;
+import org.apache.commons.lang3.StringUtils;
/**
@@ -33,7 +34,9 @@ public abstract class AbstractRangeValidator extends Field
private final Class type;
private T min;
+ private String minExpression;
private T max;
+ private String maxExpression;
protected AbstractRangeValidator(Class type) {
this.type = type;
@@ -67,14 +70,20 @@ public abstract class AbstractRangeValidator extends Field
}
public T getMin() {
- return min;
+ if (min != null) {
+ return min;
+ } else if (StringUtils.isNotEmpty(minExpression)) {
+ return (T) parse(minExpression, type);
+ } else {
+ return null;
+ }
}
public void setMinExpression(String minExpression) {
if (LOG.isDebugEnabled()) {
LOG.debug("${minExpression} was defined as [#0]", minExpression);
}
- this.min = (T) parse(minExpression, type);
+ this.minExpression = minExpression;
}
public void setMax(T max) {
@@ -82,14 +91,20 @@ public abstract class AbstractRangeValidator extends Field
}
public T getMax() {
- return max;
+ if (max != null) {
+ return max;
+ } else if (StringUtils.isNotEmpty(maxExpression)) {
+ return (T) parse(maxExpression, type);
+ } else {
+ return null;
+ }
}
public void setMaxExpression(String maxExpression) {
if (LOG.isDebugEnabled()) {
LOG.debug("${maxExpression} was defined as [#0]", maxExpression);
}
- this.max = (T) parse(maxExpression, type);
+ this.maxExpression = maxExpression;
}
}
diff --git a/xwork-core/src/test/java/com/opensymphony/xwork2/validator/AnnotationValidationAction.java b/xwork-core/src/test/java/com/opensymphony/xwork2/validator/AnnotationValidationAction.java
index 62608fe63..da9ee67c3 100644
--- a/xwork-core/src/test/java/com/opensymphony/xwork2/validator/AnnotationValidationAction.java
+++ b/xwork-core/src/test/java/com/opensymphony/xwork2/validator/AnnotationValidationAction.java
@@ -4,6 +4,7 @@ import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.validator.annotations.ConditionalVisitorFieldValidator;
import com.opensymphony.xwork2.validator.annotations.ConversionErrorFieldValidator;
import com.opensymphony.xwork2.validator.annotations.CustomValidator;
+import com.opensymphony.xwork2.validator.annotations.DateRangeFieldValidator;
import com.opensymphony.xwork2.validator.annotations.RegexFieldValidator;
import com.opensymphony.xwork2.validator.annotations.ValidationParameter;
@@ -26,6 +27,8 @@ public class AnnotationValidationAction extends ActionSupport {
@ValidationParameter(name = "value", value = "1")
}
)
+ @DateRangeFieldValidator(fieldName = "foo", key = "date.foo", max = "2012", min = "2011", dateFormat = "yyyy",
+ message = "Foo isn't in range!", shortCircuit = true, messageParams = {"one", "two", "three"})
public String execute() {
return SUCCESS;
}
diff --git a/xwork-core/src/test/java/com/opensymphony/xwork2/validator/AnnotationValidationConfigurationBuilderTest.java b/xwork-core/src/test/java/com/opensymphony/xwork2/validator/AnnotationValidationConfigurationBuilderTest.java
index e957d2106..920aea27c 100644
--- a/xwork-core/src/test/java/com/opensymphony/xwork2/validator/AnnotationValidationConfigurationBuilderTest.java
+++ b/xwork-core/src/test/java/com/opensymphony/xwork2/validator/AnnotationValidationConfigurationBuilderTest.java
@@ -16,8 +16,11 @@ import com.opensymphony.xwork2.util.ValueStackFactory;
import com.opensymphony.xwork2.util.location.LocatableProperties;
import com.opensymphony.xwork2.validator.validators.ConditionalVisitorFieldValidator;
import com.opensymphony.xwork2.validator.validators.ConversionErrorFieldValidator;
+import com.opensymphony.xwork2.validator.validators.DateRangeFieldValidator;
import com.opensymphony.xwork2.validator.validators.RegexFieldValidator;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
@@ -36,7 +39,7 @@ public class AnnotationValidationConfigurationBuilderTest extends XWorkTestCase
List validators = manager.getValidators(AnnotationValidationAction.class, null);
// then
- assertEquals(validators.size(), 4);
+ assertEquals(validators.size(), 5);
for (Validator validator : validators) {
validate(validator);
}
@@ -53,14 +56,14 @@ public class AnnotationValidationConfigurationBuilderTest extends XWorkTestCase
ValueStack valueStack = container.getInstance(ValueStackFactory.class).createValueStack();
valueStack.push(new AnnotationValidationExpAction());
- assertEquals(validators.size(), 4);
+ assertEquals(validators.size(), 5);
for (Validator validator : validators) {
validator.setValueStack(valueStack);
validate(validator);
}
}
- private void validate(Validator validator) {
+ private void validate(Validator validator) throws Exception {
if (validator.getValidatorType().equals("regex")) {
validateRegexValidator((RegexFieldValidator) validator);
} else if (validator.getValidatorType().equals("conditionalvisitor")) {
@@ -69,9 +72,21 @@ public class AnnotationValidationConfigurationBuilderTest extends XWorkTestCase
validateConversionFieldErrorVisitorValidator((ConversionErrorFieldValidator) validator);
} else if (validator.getValidatorType().equals("myValidator")) {
validateMyValidator((MyValidator) validator);
+ } else if (validator.getValidatorType().equals("date")) {
+ validateDateRangeFieldValidator((DateRangeFieldValidator) validator);
}
}
+ private void validateDateRangeFieldValidator(DateRangeFieldValidator validator) throws ParseException {
+ assertEquals("foo", validator.getFieldName());
+ assertEquals("Foo isn't in range!", validator.getDefaultMessage());
+ assertEquals("date.foo", validator.getMessageKey());
+ assertEquals(true, validator.isShortCircuit());
+ assertTrue(Arrays.equals(new String[]{"one", "two", "three"}, validator.getMessageParameters()));
+ assertEquals(new SimpleDateFormat("yyyy").parse("2011"), validator.getMin());
+ assertEquals(new SimpleDateFormat("yyyy").parse("2012"), validator.getMax());
+ }
+
private void validateMyValidator(MyValidator validator) {
assertEquals("Foo is invalid!", validator.getDefaultMessage());
assertEquals("foo", validator.getFieldName());
diff --git a/xwork-core/src/test/java/com/opensymphony/xwork2/validator/AnnotationValidationExpAction.java b/xwork-core/src/test/java/com/opensymphony/xwork2/validator/AnnotationValidationExpAction.java
index c18a7f91d..9a485e869 100644
--- a/xwork-core/src/test/java/com/opensymphony/xwork2/validator/AnnotationValidationExpAction.java
+++ b/xwork-core/src/test/java/com/opensymphony/xwork2/validator/AnnotationValidationExpAction.java
@@ -4,9 +4,14 @@ import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.validator.annotations.ConditionalVisitorFieldValidator;
import com.opensymphony.xwork2.validator.annotations.ConversionErrorFieldValidator;
import com.opensymphony.xwork2.validator.annotations.CustomValidator;
+import com.opensymphony.xwork2.validator.annotations.DateRangeFieldValidator;
import com.opensymphony.xwork2.validator.annotations.RegexFieldValidator;
import com.opensymphony.xwork2.validator.annotations.ValidationParameter;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
/**
* Sets up all available validation annotations with params as expressions
*/
@@ -26,6 +31,8 @@ public class AnnotationValidationExpAction extends ActionSupport {
@ValidationParameter(name = "value", value = "1")
}
)
+ @DateRangeFieldValidator(fieldName = "foo", key = "date.foo", maxExpression = "${dateMax}", minExpression = "${dateMin}", dateFormat = "yyyy",
+ message = "Foo isn't in range!", shortCircuit = true, messageParams = {"one", "two", "three"})
public String execute() {
return SUCCESS;
}
@@ -42,4 +49,12 @@ public class AnnotationValidationExpAction extends ActionSupport {
return false;
}
+ public Date getDateMin() throws ParseException {
+ return new SimpleDateFormat("yyyy").parse("2011");
+ }
+
+ public Date getDateMax() throws ParseException {
+ return new SimpleDateFormat("yyyy").parse("2012");
+ }
+
}