Author: lukaszlenart Date: Wed Jan 2 21:44:41 2013 New Revision: 1428077 URL: http://svn.apache.org/viewvc?rev=1428077&view=rev Log: WW-3889 adds support to specify min and max constraints as expressions
Added: struts/struts2/trunk/xwork-core/src/test/java/com/opensymphony/xwork2/validator/validators/DateRangeFieldValidatorTest.java Modified: struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/validator/validators/DateRangeFieldValidator.java struts/struts2/trunk/xwork-core/src/test/java/com/opensymphony/xwork2/validator/DateRangeValidatorTest.java Modified: struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/validator/validators/DateRangeFieldValidator.java URL: http://svn.apache.org/viewvc/struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/validator/validators/DateRangeFieldValidator.java?rev=1428077&r1=1428076&r2=1428077&view=diff ============================================================================== --- struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/validator/validators/DateRangeFieldValidator.java (original) +++ struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/validator/validators/DateRangeFieldValidator.java Wed Jan 2 21:44:41 2013 @@ -17,20 +17,19 @@ package com.opensymphony.xwork2.validato 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 ext return min; } + public String getMinExpression() { + return minExpression; + } + + public void setMinExpression(String minExpression) { + this.minExpression = minExpression; + } + @Override - protected Comparable getMaxComparatorValue() { + 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 - protected Comparable getMinComparatorValue() { - return min; + public Date getMaxComparatorValue() { + if (parse) { + return parse(getMaxExpression()); + } + return getMax(); } + } Modified: struts/struts2/trunk/xwork-core/src/test/java/com/opensymphony/xwork2/validator/DateRangeValidatorTest.java URL: http://svn.apache.org/viewvc/struts/struts2/trunk/xwork-core/src/test/java/com/opensymphony/xwork2/validator/DateRangeValidatorTest.java?rev=1428077&r1=1428076&r2=1428077&view=diff ============================================================================== --- struts/struts2/trunk/xwork-core/src/test/java/com/opensymphony/xwork2/validator/DateRangeValidatorTest.java (original) +++ struts/struts2/trunk/xwork-core/src/test/java/com/opensymphony/xwork2/validator/DateRangeValidatorTest.java Wed Jan 2 21:44:41 2013 @@ -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 exte * 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 { Added: struts/struts2/trunk/xwork-core/src/test/java/com/opensymphony/xwork2/validator/validators/DateRangeFieldValidatorTest.java URL: http://svn.apache.org/viewvc/struts/struts2/trunk/xwork-core/src/test/java/com/opensymphony/xwork2/validator/validators/DateRangeFieldValidatorTest.java?rev=1428077&view=auto ============================================================================== --- struts/struts2/trunk/xwork-core/src/test/java/com/opensymphony/xwork2/validator/validators/DateRangeFieldValidatorTest.java (added) +++ struts/struts2/trunk/xwork-core/src/test/java/com/opensymphony/xwork2/validator/validators/DateRangeFieldValidatorTest.java Wed Jan 2 21:44:41 2013 @@ -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; + } + +}