001 package org.apache.fulcrum.intake.validator;
002
003 /*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements. See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership. The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License. You may obtain a copy of the License at
011 *
012 * http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied. See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022 import java.text.ParseException;
023 import java.util.ArrayList;
024 import java.util.Date;
025 import java.util.Iterator;
026 import java.util.List;
027 import java.util.Map;
028
029 import org.apache.commons.lang.StringUtils;
030 import org.apache.fulcrum.intake.IntakeException;
031 import org.apache.fulcrum.intake.model.Field;
032 import org.apache.fulcrum.intake.model.Group;
033
034 /**
035 * Validates a DateString field in dependency on another DateString field.
036 *
037 * <table>
038 * <tr>
039 * <th>Name</th><th>Valid Values</th><th>Default Value</th>
040 * </tr>
041 * <tr>
042 * <td>less-than</td>
043 * <td><name of other field></td>
044 * <td> </td>
045 * </tr>
046 * <tr>
047 * <td>greater-than</td>
048 * <td><name of other field></td>
049 * <td> </td>
050 * </tr>
051 * <tr>
052 * <td>less-than-or-equal</td>
053 * <td><name of other field></td>
054 * <td> </td>
055 * </tr>
056 * <tr>
057 * <td>greater-than-or-equal</td>
058 * <td><name of other field></td>
059 * <td> </td>
060 * </tr>
061 * </table>
062 *
063 * @author <a href="mailto:tv@apache.org">Thomas Vandahl</a>
064 * @version $Id: DateStringValidator.java 534527 2007-05-02 16:10:59Z tv $
065 */
066 public class DateRangeValidator
067 extends DateStringValidator
068 {
069 /** List of FieldReferences for multiple comparisons */
070 List fieldReferences;
071
072 /** Callback for the actual compare operation */
073 CompareCallback compareCallback;
074
075 public DateRangeValidator(final Map paramMap)
076 throws IntakeException
077 {
078 init(paramMap);
079 }
080
081 /**
082 * Default constructor
083 */
084 public DateRangeValidator()
085 {
086 super();
087 }
088
089 /**
090 * Constructor to use when initialising Object
091 *
092 * @param paramMap
093 * @throws InvalidMaskException
094 */
095 public void init(final Map paramMap)
096 throws InvalidMaskException
097 {
098 super.init(paramMap);
099
100 compareCallback = new CompareCallback()
101 {
102 /**
103 * Compare the given values using the compare operation provided
104 *
105 * @param compare type of compare operation
106 * @param thisValue value of this field
107 * @param refValue value of the reference field
108 *
109 * @return the result of the comparison
110 */
111 public boolean compareValues(int compare, Object thisValue, Object refValue)
112 throws ClassCastException
113 {
114 boolean result = true;
115
116 Date thisDate = (Date)thisValue;
117 Date otherDate = (Date)refValue;
118
119 switch (compare)
120 {
121 case FieldReference.COMPARE_LT:
122 result = thisDate.before(otherDate);
123 break;
124
125 case FieldReference.COMPARE_LTE:
126 result = !thisDate.after(otherDate);
127 break;
128
129 case FieldReference.COMPARE_GT:
130 result = thisDate.after(otherDate);
131 break;
132
133 case FieldReference.COMPARE_GTE:
134 result = !thisDate.before(otherDate);
135 break;
136 }
137
138 return result;
139 }
140 };
141
142 fieldReferences = new ArrayList(10);
143
144 for (Iterator i = paramMap.entrySet().iterator(); i.hasNext();)
145 {
146 Map.Entry entry = (Map.Entry)i.next();
147 String key = (String)entry.getKey();
148 Constraint constraint = (Constraint)entry.getValue();
149
150 int compare = FieldReference.getCompareType(key);
151
152 if (compare != 0)
153 {
154 // found matching constraint
155 FieldReference fieldref = new FieldReference();
156 fieldref.setCompare(compare);
157 fieldref.setFieldName(constraint.getValue());
158 fieldref.setMessage(constraint.getMessage());
159
160 fieldReferences.add(fieldref);
161 }
162 }
163
164 if (fieldReferences.isEmpty())
165 {
166 log.warn("No reference field rules have been found.");
167 }
168 }
169
170 /**
171 * Determine whether a testValue meets the criteria specified
172 * in the constraints defined for this validator
173 *
174 * @param testField a <code>Field</code> to be tested
175 * @exception ValidationException containing an error message if the
176 * testValue did not pass the validation tests.
177 */
178 public void assertValidity(final Field testField)
179 throws ValidationException
180 {
181 super.assertValidity(testField);
182
183 Group thisGroup = testField.getGroup();
184
185 if (testField.isMultiValued())
186 {
187 String[] stringValues = (String[])testField.getTestValue();
188
189 for (int i = 0; i < stringValues.length; i++)
190 {
191 assertValidity(stringValues[i], thisGroup);
192 }
193 }
194 else
195 {
196 String testValue = (String)testField.getTestValue();
197
198 assertValidity(testValue, thisGroup);
199 }
200 }
201
202 /**
203 * Determine whether a testValue meets the criteria specified
204 * in the constraints defined for this validator
205 *
206 * @param testValue a <code>String</code> to be tested
207 * @param group the group this field belongs to
208 *
209 * @exception ValidationException containing an error message if the
210 * testValue did not pass the validation tests.
211 */
212 public void assertValidity(final String testValue, final Group group)
213 throws ValidationException
214 {
215 if (required || StringUtils.isNotEmpty(testValue))
216 {
217 Date testDate = null;
218
219 try
220 {
221 testDate = parse(testValue);
222 }
223 catch (ParseException e)
224 {
225 // This should not happen because we succeded with this before,
226 // but we need to catch the exception anyway
227 errorMessage = getDateFormatMessage();
228 throw new ValidationException(errorMessage);
229 }
230
231 try
232 {
233 FieldReference.checkReferences(fieldReferences, compareCallback,
234 testDate, group);
235 }
236 catch (ValidationException e)
237 {
238 errorMessage = e.getMessage();
239 throw e;
240 }
241 }
242 }
243 }