mirror of
https://github.com/apache/struts.git
synced 2026-08-11 01:27:14 +00:00
WW-3889 adds support to specify min and max constraints as expressions
git-svn-id: https://svn.apache.org/repos/asf/struts/struts2/trunk@1428077 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
+88
-44
@@ -17,20 +17,19 @@ 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 programmatically specified locale else falling back to the system
|
||||
* 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 -->
|
||||
@@ -38,50 +37,64 @@ import java.util.Date;
|
||||
* <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.
|
||||
* WARNING! Do not use ${minExpression} and ${maxExpression} as an expression as this will turn into infinitive loop!
|
||||
*
|
||||
* <!-- END SNIPPET: parameters -->
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
* <!-- START SNIPPET: examples -->
|
||||
* <validators>
|
||||
* <!-- Plain Validator syntax -->
|
||||
* <validator type="date">
|
||||
* <param name="fieldName">birthday</param>
|
||||
* <param name="min">01/01/1990</param>
|
||||
* <param name="max">01/01/2000</param>
|
||||
* <message>Birthday must be within ${min} and ${max}</message>
|
||||
* </validator>
|
||||
*
|
||||
* <!-- Field Validator Syntax -->
|
||||
* <field name="birthday">
|
||||
* <field-validator type="date">
|
||||
* <param name="min">01/01/1990</param>
|
||||
* <param name="max">01/01/2000</param>
|
||||
* <message>Birthday must be within ${min} and ${max}</message>
|
||||
* </field>
|
||||
* </field>
|
||||
*
|
||||
* </validators>
|
||||
* <validators>
|
||||
* <!-- Plain Validator syntax -->
|
||||
* <validator type="date">
|
||||
* <param name="fieldName">birthday</param>
|
||||
* <param name="min">01/01/1990</param>
|
||||
* <param name="max">01/01/2000</param>
|
||||
* <message>Birthday must be within ${min} and ${max}</message>
|
||||
* </validator>
|
||||
*
|
||||
* <!-- Field Validator Syntax -->
|
||||
* <field name="birthday">
|
||||
* <field-validator type="date">
|
||||
* <param name="min">01/01/1990</param>
|
||||
* <param name="max">01/01/2000</param>
|
||||
* <message>Birthday must be within ${min} and ${max}</message>
|
||||
* </field>
|
||||
* </field>
|
||||
*
|
||||
* <!-- Field Validator Syntax with expression -->
|
||||
* <field name="birthday">
|
||||
* <field-validator type="date">
|
||||
* <param name="parse">true</param>
|
||||
* <param name="minExpression">${minValue}</param> <!-- will be evaluated as: Date getMinValue() -->
|
||||
* <param name="maxExpression">${maxValue}</param> <!-- will be evaluated as: Date getMaxValue() -->
|
||||
* <message>Age needs to be between ${minExpression} and ${maxExpression}</message>
|
||||
* </field-validator>
|
||||
* </field>
|
||||
* </validators>
|
||||
* <!-- END SNIPPET: examples -->
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
*
|
||||
* @author Jason Carreira
|
||||
* @version $Date$ $Id$
|
||||
*/
|
||||
public class DateRangeFieldValidator extends AbstractRangeValidator {
|
||||
public class DateRangeFieldValidator extends AbstractRangeValidator<Date> {
|
||||
|
||||
private Date max;
|
||||
private Date min;
|
||||
private Date max;
|
||||
private String minExpression;
|
||||
private String maxExpression;
|
||||
|
||||
|
||||
public void setMax(Date max) {
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
public Date getMax() {
|
||||
return max;
|
||||
public DateRangeFieldValidator() {
|
||||
super(Date.class);
|
||||
}
|
||||
|
||||
public void setMin(Date min) {
|
||||
@@ -92,13 +105,44 @@ public class DateRangeFieldValidator extends AbstractRangeValidator {
|
||||
return min;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Comparable getMaxComparatorValue() {
|
||||
return max;
|
||||
public String getMinExpression() {
|
||||
return minExpression;
|
||||
}
|
||||
|
||||
public void setMinExpression(String minExpression) {
|
||||
this.minExpression = minExpression;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Comparable getMinComparatorValue() {
|
||||
return min;
|
||||
public Date getMinComparatorValue() {
|
||||
if (parse) {
|
||||
return parse(getMinExpression());
|
||||
}
|
||||
return getMin();
|
||||
}
|
||||
|
||||
public void setMax(Date max) {
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
public Date getMax() {
|
||||
return max;
|
||||
}
|
||||
|
||||
public String getMaxExpression() {
|
||||
return maxExpression;
|
||||
}
|
||||
|
||||
public void setMaxExpression(String maxExpression) {
|
||||
this.maxExpression = maxExpression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getMaxComparatorValue() {
|
||||
if (parse) {
|
||||
return parse(getMaxExpression());
|
||||
}
|
||||
return getMax();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+19
-7
@@ -15,13 +15,19 @@
|
||||
*/
|
||||
package com.opensymphony.xwork2.validator;
|
||||
|
||||
import com.opensymphony.xwork2.ActionContext;
|
||||
import com.opensymphony.xwork2.ActionProxy;
|
||||
import com.opensymphony.xwork2.ValidationAware;
|
||||
import com.opensymphony.xwork2.XWorkTestCase;
|
||||
import com.opensymphony.xwork2.config.providers.MockConfigurationProvider;
|
||||
import com.opensymphony.xwork2.validator.validators.DateRangeFieldValidator;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
@@ -40,19 +46,25 @@ public class DateRangeValidatorTest extends XWorkTestCase {
|
||||
* because the action config sets date to 12/20/2002 while expected range is Dec 22-25.
|
||||
*/
|
||||
public void testRangeValidation() throws Exception {
|
||||
ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.VALIDATION_ACTION_NAME, null);
|
||||
Calendar date = Calendar.getInstance();
|
||||
date.set(2002, Calendar.NOVEMBER, 20);
|
||||
Map<String, Object> context = new HashMap<String, Object>();
|
||||
HashMap<String, Object> params = new HashMap<String, Object>();
|
||||
params.put("date", date.getTime());
|
||||
context.put(ActionContext.PARAMETERS, params);
|
||||
|
||||
ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.VALIDATION_ACTION_NAME, context);
|
||||
proxy.execute();
|
||||
assertTrue(((ValidationAware) proxy.getAction()).hasFieldErrors());
|
||||
|
||||
Map errors = ((ValidationAware) proxy.getAction()).getFieldErrors();
|
||||
Iterator it = errors.entrySet().iterator();
|
||||
Map<String, List<String>> errors = ((ValidationAware) proxy.getAction()).getFieldErrors();
|
||||
|
||||
List errorMessages = (List) errors.get("date");
|
||||
List<String> errorMessages = errors.get("date");
|
||||
assertNotNull("Expected date range validation error message.", errorMessages);
|
||||
assertEquals(1, errorMessages.size());
|
||||
|
||||
String errorMessage = (String) errorMessages.get(0);
|
||||
assertNotNull(errorMessage);
|
||||
String errorMessage = errorMessages.get(0);
|
||||
assertEquals("The date must be between 12-22-2002 and 12-25-2002.", errorMessage);
|
||||
}
|
||||
|
||||
public void testGetSetMinMax() throws Exception {
|
||||
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
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;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
public class DateRangeFieldValidatorTest extends XWorkTestCase {
|
||||
|
||||
public void testPassValidation() throws Exception {
|
||||
// given
|
||||
ValidationAction action = prepareAction(createDate(2013, 6, 6));
|
||||
ValidatorContext context = new GenericValidatorContext(action);
|
||||
DateRangeFieldValidator validator = prepareValidator(action, context);
|
||||
|
||||
// when
|
||||
validator.validate(action);
|
||||
|
||||
// then
|
||||
assertTrue(context.getFieldErrors().size() == 0);
|
||||
}
|
||||
|
||||
public void testMinValidation() throws Exception {
|
||||
// given
|
||||
ValidationAction action = prepareAction(createDate(2012, Calendar.MARCH, 3));
|
||||
ValidatorContext context = new GenericValidatorContext(action);
|
||||
DateRangeFieldValidator validator = prepareValidator(action, context);
|
||||
|
||||
// when
|
||||
validator.validate(action);
|
||||
|
||||
// then
|
||||
assertTrue(context.getFieldErrors().size() == 1);
|
||||
assertEquals("Max is 12/12/13, min is 1/1/13 but value is 3/3/12", context.getFieldErrors().get("dateRange").get(0));
|
||||
}
|
||||
|
||||
public void testMaxValidation() throws Exception {
|
||||
// given
|
||||
ValidationAction action = prepareAction(createDate(2014, Calendar.APRIL, 4));
|
||||
ValidatorContext context = new GenericValidatorContext(action);
|
||||
DateRangeFieldValidator validator = prepareValidator(action, context);
|
||||
|
||||
// when
|
||||
validator.validate(action);
|
||||
|
||||
// then
|
||||
assertTrue(context.getFieldErrors().size() == 1);
|
||||
assertEquals("Max is 12/12/13, min is 1/1/13 but value is 4/4/14", context.getFieldErrors().get("dateRange").get(0));
|
||||
}
|
||||
|
||||
private ValidationAction prepareAction(Date range) {
|
||||
ValidationAction action = new ValidationAction();
|
||||
action.setDateMinValue(createDate(2013, Calendar.JANUARY, 1));
|
||||
action.setDateMaxValue(createDate(2013, Calendar.DECEMBER, 12));
|
||||
action.setDateRange(range);
|
||||
return action;
|
||||
}
|
||||
|
||||
private Date createDate(int year, int month, int day) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.set(year, month, day);
|
||||
return cal.getTime();
|
||||
}
|
||||
|
||||
private DateRangeFieldValidator prepareValidator(ValidationAction action, ValidatorContext context) {
|
||||
DateRangeFieldValidator validator = new DateRangeFieldValidator();
|
||||
validator.setMaxExpression("${dateMaxValue}");
|
||||
validator.setMinExpression("${dateMinValue}");
|
||||
ValueStack valueStack = container.getInstance(ValueStackFactory.class).createValueStack();
|
||||
valueStack.push(action);
|
||||
validator.setValueStack(valueStack);
|
||||
validator.setValidatorContext(context);
|
||||
validator.setFieldName("dateRange");
|
||||
validator.setParse(true);
|
||||
validator.setDefaultMessage("Max is ${dateMaxValue}, min is ${dateMinValue} but value is ${dateRange}");
|
||||
return validator;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user