WW-3890 adds support for expression in specifying min and max constraints

git-svn-id: https://svn.apache.org/repos/asf/struts/struts2/trunk@1424652 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Lukasz Lenart
2012-12-20 19:47:02 +00:00
parent 40b7bfbe25
commit bd01d1525a
4 changed files with 162 additions and 41 deletions
@@ -68,8 +68,6 @@ package com.opensymphony.xwork2.validator.validators;
* <!-- END SNIPPET: examples -->
* </pre>
*
*
*
* @author Jason Carreira
* @version $Date$ $Id$
*/
@@ -15,7 +15,6 @@
*/
package com.opensymphony.xwork2.validator.validators;
/**
* <!-- START SNIPPET: javadoc -->
* Field Validator that checks if the long specified is within a certain range.
@@ -24,69 +23,90 @@ package com.opensymphony.xwork2.validator.validators;
*
* <!-- 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>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>
* </ul>
*
* The min / max value can be specified as an expression, but then you must also enable parsing it by specifying <strong>parse</strong> param
* as in the example below.
* WARNING! Do not use ${min} and ${max} as an expression as this will turn into infinitive loop!
*
* <!-- END SNIPPET: parameters -->
*
*
* <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;/validators&gt;
* &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="parse"&gt;true&lt;/param&gt;
* &lt;param name="${minValue}"&gt;20&lt;/param&gt; &lt;!-- will be evaluated as: Long getMinValue() --&gt;
* &lt;param name="${maxValue}"&gt;50&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 class LongRangeFieldValidator extends AbstractRangeValidator {
public class LongRangeFieldValidator extends AbstractRangeValidator<Long> {
Long max = null;
Long min = null;
String max = null;
String min = null;
public void setMax(Long max) {
public void setMax(String max) {
this.max = max;
}
public Long getMax() {
return max;
public String getMax() {
return safeConditionalParse(max);
}
@Override
public Comparable getMaxComparatorValue() {
return max;
public Long getMaxComparatorValue() {
return parseLong(getMax());
}
public void setMin(Long min) {
public void setMin(String min) {
this.min = min;
}
public Long getMin() {
return min;
public String getMin() {
return safeConditionalParse(min);
}
@Override
public Comparable getMinComparatorValue() {
return min;
public Long getMinComparatorValue() {
return parseLong(getMin());
}
private Long parseLong(String value) {
if (value != null) {
return Long.parseLong(value);
} else {
return null;
}
}
}
@@ -0,0 +1,74 @@
package com.opensymphony.xwork2.validator.validators;
import com.opensymphony.xwork2.XWorkTestCase;
import com.opensymphony.xwork2.util.ValueStack;
import com.opensymphony.xwork2.util.ValueStackFactory;
import com.opensymphony.xwork2.validator.GenericValidatorContext;
import com.opensymphony.xwork2.validator.ValidatorContext;
public class LongRangeFieldValidatorTest extends XWorkTestCase {
public void testPassValidation() throws Exception {
// given
ValidationAction action = prepareAction(100);
ValidatorContext context = new GenericValidatorContext(action);
LongRangeFieldValidator validator = prepareValidator(action, context);
// when
validator.validate(action);
// then
assertTrue(context.getFieldErrors().size() == 0);
}
public void testMinValidation() throws Exception {
// given
ValidationAction action = prepareAction(98);
ValidatorContext context = new GenericValidatorContext(action);
LongRangeFieldValidator validator = prepareValidator(action, context);
// when
validator.validate(action);
// then
assertTrue(context.getFieldErrors().size() == 1);
assertEquals("Max is 101, min is 99 but value is 98", context.getFieldErrors().get("longRange").get(0));
}
public void testMaxValidation() throws Exception {
// given
ValidationAction action = prepareAction(102);
ValidatorContext context = new GenericValidatorContext(action);
LongRangeFieldValidator validator = prepareValidator(action, context);
// when
validator.validate(action);
// then
assertTrue(context.getFieldErrors().size() == 1);
assertEquals("Max is 101, min is 99 but value is 102", context.getFieldErrors().get("longRange").get(0));
}
private ValidationAction prepareAction(long longRange) {
ValidationAction action = new ValidationAction();
action.setLongMaxValue(101L);
action.setLongMinValue(99L);
action.setLongRange(longRange);
return action;
}
private LongRangeFieldValidator prepareValidator(ValidationAction action, ValidatorContext context) {
LongRangeFieldValidator validator = new LongRangeFieldValidator();
validator.setMax("${longMaxValue}");
validator.setMin("${longMinValue}");
ValueStack valueStack = container.getInstance(ValueStackFactory.class).createValueStack();
valueStack.push(action);
validator.setValueStack(valueStack);
validator.setValidatorContext(context);
validator.setFieldName("longRange");
validator.setParse(true);
validator.setDefaultMessage("Max is ${longMaxValue}, min is ${longMinValue} but value is ${longRange}");
return validator;
}
}
@@ -10,6 +10,10 @@ public class ValidationAction {
private Short shortMinValue;
private Short shortMaxValue;
private Long longRange;
private Long longMinValue;
private Long longMaxValue;
public Integer getIntRange() {
return intRange;
}
@@ -57,4 +61,29 @@ public class ValidationAction {
public void setShortMaxValue(Short shortMaxValue) {
this.shortMaxValue = shortMaxValue;
}
public Long getLongRange() {
return longRange;
}
public void setLongRange(Long longRange) {
this.longRange = longRange;
}
public Long getLongMinValue() {
return longMinValue;
}
public void setLongMinValue(Long longMinValue) {
this.longMinValue = longMinValue;
}
public Long getLongMaxValue() {
return longMaxValue;
}
public void setLongMaxValue(Long longMaxValue) {
this.longMaxValue = longMaxValue;
}
}