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

git-svn-id: https://svn.apache.org/repos/asf/struts/struts2/trunk@1399395 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Lukasz Lenart
2012-10-17 19:09:07 +00:00
parent a25315b3d3
commit e6ca077e00
4 changed files with 176 additions and 53 deletions
@@ -15,7 +15,6 @@
*/
package com.opensymphony.xwork2.validator.validators;
/**
* <!-- START SNIPPET: javadoc -->
* Field Validator that checks if the short specified is within a certain range.
@@ -24,33 +23,47 @@ 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="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;/validators&gt;
* &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="parse"&gt;true&lt;/param&gt;
* &lt;param name="${minValue}"&gt;20&lt;/param&gt; &lt;!-- will be evaluated as: Short getMinValue() --&gt;
* &lt;param name="${maxValue}"&gt;50&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>
*
@@ -58,35 +71,43 @@ package com.opensymphony.xwork2.validator.validators;
*
* @version $Date$
*/
public class ShortRangeFieldValidator extends AbstractRangeValidator {
public class ShortRangeFieldValidator extends AbstractRangeValidator<Short> {
Short max = null;
Short min = null;
String max = null;
String min = null;
public void setMax(Short max) {
public void setMax(String max) {
this.max = max;
}
public Short getMax() {
return max;
public String getMax() {
return safeConditionalParse(max);
}
@Override
public Comparable getMaxComparatorValue() {
return max;
public Short getMaxComparatorValue() {
return parseShort(getMax());
}
public void setMin(Short min) {
public void setMin(String min) {
this.min = min;
}
public Short getMin() {
return min;
public String getMin() {
return safeConditionalParse(min);
}
@Override
public Comparable getMinComparatorValue() {
return min;
public Short getMinComparatorValue() {
return parseShort(getMin());
}
private Short parseShort(String value) {
if (value != null) {
return Short.parseShort(value);
} else {
return null;
}
}
}
@@ -51,23 +51,23 @@ public class IntRangeFieldValidatorTest extends XWorkTestCase {
private ValidationAction prepareAction(int intRange) {
ValidationAction action = new ValidationAction();
action.setMaxValue(101);
action.setMinValue(99);
action.setIntMaxValue(101);
action.setIntMinValue(99);
action.setIntRange(intRange);
return action;
}
private IntRangeFieldValidator prepareValidator(ValidationAction action, ValidatorContext context) {
IntRangeFieldValidator validator = new IntRangeFieldValidator();
validator.setMax("${maxValue}");
validator.setMin("${minValue}");
validator.setMax("${intMaxValue}");
validator.setMin("${intMinValue}");
ValueStack valueStack = container.getInstance(ValueStackFactory.class).createValueStack();
valueStack.push(action);
validator.setValueStack(valueStack);
validator.setValidatorContext(context);
validator.setFieldName("intRange");
validator.setParse(true);
validator.setDefaultMessage("Max is ${maxValue}, min is ${minValue} but value is ${intRange}");
validator.setDefaultMessage("Max is ${intMaxValue}, min is ${intMinValue} but value is ${intRange}");
return validator;
}
@@ -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 ShortRangeFieldValidatorTest extends XWorkTestCase {
public void testPassValidation() throws Exception {
// given
ValidationAction action = prepareAction((short) 5);
ValidatorContext context = new GenericValidatorContext(action);
ShortRangeFieldValidator validator = prepareValidator(action, context);
// when
validator.validate(action);
// then
assertTrue(context.getFieldErrors().size() == 0);
}
public void testMinValidation() throws Exception {
// given
ValidationAction action = prepareAction((short) 1);
ValidatorContext context = new GenericValidatorContext(action);
ShortRangeFieldValidator validator = prepareValidator(action, context);
// when
validator.validate(action);
// then
assertTrue(context.getFieldErrors().size() == 1);
assertEquals("Max is 10, min is 2 but value is 1", context.getFieldErrors().get("shortRange").get(0));
}
public void testMaxValidation() throws Exception {
// given
ValidationAction action = prepareAction((short) 11);
ValidatorContext context = new GenericValidatorContext(action);
ShortRangeFieldValidator validator = prepareValidator(action, context);
// when
validator.validate(action);
// then
assertTrue(context.getFieldErrors().size() == 1);
assertEquals("Max is 10, min is 2 but value is 11", context.getFieldErrors().get("shortRange").get(0));
}
private ValidationAction prepareAction(short range) {
ValidationAction action = new ValidationAction();
action.setShortMaxValue((short) 10);
action.setShortMinValue((short) 2);
action.setShortRange(range);
return action;
}
private ShortRangeFieldValidator prepareValidator(ValidationAction action, ValidatorContext context) {
ShortRangeFieldValidator validator = new ShortRangeFieldValidator();
validator.setMax("${shortMaxValue}");
validator.setMin("${shortMinValue}");
ValueStack valueStack = container.getInstance(ValueStackFactory.class).createValueStack();
valueStack.push(action);
validator.setValueStack(valueStack);
validator.setValidatorContext(context);
validator.setFieldName("shortRange");
validator.setParse(true);
validator.setDefaultMessage("Max is ${shortMaxValue}, min is ${shortMinValue} but value is ${shortRange}");
return validator;
}
}
@@ -3,8 +3,12 @@ package com.opensymphony.xwork2.validator.validators;
public class ValidationAction {
private Integer intRange;
private Integer minValue;
private Integer maxValue;
private Integer intMinValue;
private Integer intMaxValue;
private Short shortRange;
private Short shortMinValue;
private Short shortMaxValue;
public Integer getIntRange() {
return intRange;
@@ -14,19 +18,43 @@ public class ValidationAction {
this.intRange = intRange;
}
public Integer getMinValue() {
return minValue;
public Integer getIntMinValue() {
return intMinValue;
}
public void setMinValue(Integer minValue) {
this.minValue = minValue;
public void setIntMinValue(Integer intMinValue) {
this.intMinValue = intMinValue;
}
public Integer getMaxValue() {
return maxValue;
public Integer getIntMaxValue() {
return intMaxValue;
}
public void setMaxValue(Integer maxValue) {
this.maxValue = maxValue;
public void setIntMaxValue(Integer intMaxValue) {
this.intMaxValue = intMaxValue;
}
public Short getShortRange() {
return shortRange;
}
public void setShortRange(Short shortRange) {
this.shortRange = shortRange;
}
public Short getShortMinValue() {
return shortMinValue;
}
public void setShortMinValue(Short shortMinValue) {
this.shortMinValue = shortMinValue;
}
public Short getShortMaxValue() {
return shortMaxValue;
}
public void setShortMaxValue(Short shortMaxValue) {
this.shortMaxValue = shortMaxValue;
}
}