1 package org.apache.fulcrum.intake.validator;
2
3 /*
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 */
21
22 import java.text.ParseException;
23 import java.util.ArrayList;
24 import java.util.Date;
25 import java.util.List;
26 import java.util.Map;
27
28 import org.apache.commons.lang3.StringUtils;
29 import org.apache.fulcrum.intake.model.Field;
30 import org.apache.fulcrum.intake.model.Group;
31 import org.apache.fulcrum.intake.validator.FieldReference.Comparison;
32
33 /**
34 * Validates a DateString field in dependency on another DateString field.
35 *
36 * <table>
37 * <caption>Validation rules</caption>
38 * <tr>
39 * <th>Name</th><th>Valid Values</th><th>Default Value</th>
40 * </tr>
41 * <tr>
42 * <td>less-than</td>
43 * <td><name of other field></td>
44 * <td> </td>
45 * </tr>
46 * <tr>
47 * <td>greater-than</td>
48 * <td><name of other field></td>
49 * <td> </td>
50 * </tr>
51 * <tr>
52 * <td>less-than-or-equal</td>
53 * <td><name of other field></td>
54 * <td> </td>
55 * </tr>
56 * <tr>
57 * <td>greater-than-or-equal</td>
58 * <td><name of other field></td>
59 * <td> </td>
60 * </tr>
61 * </table>
62 *
63 * @author <a href="mailto:tv@apache.org">Thomas Vandahl</a>
64 * @version $Id$
65 */
66 public class DateRangeValidator
67 extends DateStringValidator
68 {
69 /** List of FieldReferences for multiple comparisons */
70 List<FieldReference> fieldReferences;
71
72 /** Callback for the actual compare operation */
73 CompareCallback<Date> compareCallback;
74
75 /**
76 * Default constructor
77 */
78 public DateRangeValidator()
79 {
80 super();
81 }
82
83 /**
84 * Constructor to use when initializing Object
85 *
86 * @param paramMap a map of parameters
87 * @throws InvalidMaskException one of the mask rules is invalid
88 */
89 @Override
90 public void init(Map<String, ? extends Constraint> paramMap)
91 throws InvalidMaskException
92 {
93 super.init(paramMap);
94
95 compareCallback = new CompareCallback<Date>()
96 {
97 /**
98 * Compare the given values using the compare operation provided
99 *
100 * @param compare type of compare operation
101 * @param thisValue value of this field
102 * @param refValue value of the reference field
103 *
104 * @return the result of the comparison
105 */
106 @Override
107 public boolean compareValues(Comparison compare, Date thisValue, Date refValue)
108 {
109 boolean result = true;
110
111 switch (compare)
112 {
113 case LT:
114 result = thisValue.before(refValue);
115 break;
116
117 case LTE:
118 result = !thisValue.after(refValue);
119 break;
120
121 case GT:
122 result = thisValue.after(refValue);
123 break;
124
125 case GTE:
126 result = !thisValue.before(refValue);
127 break;
128 }
129
130 return result;
131 }
132 };
133
134 fieldReferences = new ArrayList<FieldReference>(10);
135
136 for (Map.Entry<String, ? extends Constraint> entry : paramMap.entrySet())
137 {
138 String key = entry.getKey();
139 Constraint constraint = entry.getValue();
140
141 Comparison compare = FieldReference.getComparisonType(key);
142
143 if (compare != null)
144 {
145 // found matching constraint
146 FieldReference/FieldReference.html#FieldReference">FieldReference fieldref = new FieldReference();
147 fieldref.setComparison(compare);
148 fieldref.setFieldName(constraint.getValue());
149 fieldref.setMessage(constraint.getMessage());
150
151 fieldReferences.add(fieldref);
152 }
153 }
154
155 if (fieldReferences.isEmpty())
156 {
157 log.warn("No reference field rules have been found.");
158 }
159 }
160
161 /**
162 * Determine whether a testValue meets the criteria specified
163 * in the constraints defined for this validator
164 *
165 * @param testField a <code>Field</code> to be tested
166 * @throws ValidationException containing an error message if the
167 * testValue did not pass the validation tests.
168 */
169 @Override
170 public void assertValidity(Field<Date> testField)
171 throws ValidationException
172 {
173 super.assertValidity(testField);
174
175 Group thisGroup = testField.getGroup();
176
177 if (testField.isMultiValued())
178 {
179 String[] stringValues = (String[])testField.getTestValue();
180
181 for (int i = 0; i < stringValues.length; i++)
182 {
183 assertValidity(stringValues[i], thisGroup);
184 }
185 }
186 else
187 {
188 String testValue = (String)testField.getTestValue();
189
190 assertValidity(testValue, thisGroup);
191 }
192 }
193
194 /**
195 * Determine whether a testValue meets the criteria specified
196 * in the constraints defined for this validator
197 *
198 * @param testValue a <code>String</code> to be tested
199 * @param group the group this field belongs to
200 *
201 * @throws ValidationException containing an error message if the
202 * testValue did not pass the validation tests.
203 */
204 public void assertValidity(final String testValue, final Group group)
205 throws ValidationException
206 {
207 if (required || StringUtils.isNotEmpty(testValue))
208 {
209 Date testDate = null;
210
211 try
212 {
213 testDate = parse(testValue);
214 }
215 catch (ParseException e)
216 {
217 // This should not happen because we succeeded with this before,
218 // but we need to catch the exception anyway
219 errorMessage = getDateFormatMessage();
220 throw new ValidationException(errorMessage);
221 }
222
223 try
224 {
225 FieldReference.checkReferences(fieldReferences, compareCallback,
226 testDate, group);
227 }
228 catch (ValidationException e)
229 {
230 errorMessage = e.getMessage();
231 throw e;
232 }
233 }
234 }
235 }