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.util.ArrayList;
023 import java.util.Iterator;
024 import java.util.List;
025 import java.util.Map;
026
027 import org.apache.commons.lang.StringUtils;
028 import org.apache.fulcrum.intake.IntakeException;
029 import org.apache.fulcrum.intake.model.Field;
030 import org.apache.fulcrum.intake.model.Group;
031
032 /**
033 * Validates an int field in dependency on another int field.
034 *
035 * <table>
036 * <tr>
037 * <th>Name</th><th>Valid Values</th><th>Default Value</th>
038 * </tr>
039 * <tr>
040 * <td>less-than</td>
041 * <td><name of other field></td>
042 * <td> </td>
043 * </tr>
044 * <tr>
045 * <td>greater-than</td>
046 * <td><name of other field></td>
047 * <td> </td>
048 * </tr>
049 * <tr>
050 * <td>less-than-or-equal</td>
051 * <td><name of other field></td>
052 * <td> </td>
053 * </tr>
054 * <tr>
055 * <td>greater-than-or-equal</td>
056 * <td><name of other field></td>
057 * <td> </td>
058 * </tr>
059 * </table>
060 *
061 * @author <a href="mailto:tv@apache.org">Thomas Vandahl</a>
062 * @version $Id: DateStringValidator.java 534527 2007-05-02 16:10:59Z tv $
063 */
064 public class IntegerRangeValidator
065 extends IntegerValidator
066 {
067 /** List of FieldReferences for multiple comparisons */
068 List fieldReferences;
069
070 /** Callback for the actual compare operation */
071 CompareCallback compareCallback;
072
073 public IntegerRangeValidator(final Map paramMap)
074 throws IntakeException
075 {
076 this();
077 init(paramMap);
078 }
079
080 /**
081 * Default constructor
082 */
083 public IntegerRangeValidator()
084 {
085 super();
086 }
087
088 /**
089 * Constructor to use when initialising Object
090 *
091 * @param paramMap
092 * @throws InvalidMaskException
093 */
094 public void init(final Map paramMap)
095 throws InvalidMaskException
096 {
097 super.init(paramMap);
098
099 compareCallback = new CompareCallback()
100 {
101 /**
102 * Compare the given values using the compare operation provided
103 *
104 * @param compare type of compare operation
105 * @param thisValue value of this field
106 * @param refValue value of the reference field
107 *
108 * @return the result of the comparison
109 */
110 public boolean compareValues(int compare, Object thisValue, Object refValue)
111 throws ClassCastException
112 {
113 boolean result = true;
114
115 Integer thisInt = (Integer)thisValue;
116 Integer otherInt = (Integer)refValue;
117
118 switch (compare)
119 {
120 case FieldReference.COMPARE_LT:
121 result = thisInt.compareTo(otherInt) < 0;
122 break;
123
124 case FieldReference.COMPARE_LTE:
125 result = thisInt.compareTo(otherInt) <= 0;
126 break;
127
128 case FieldReference.COMPARE_GT:
129 result = thisInt.compareTo(otherInt) > 0;
130 break;
131
132 case FieldReference.COMPARE_GTE:
133 result = thisInt.compareTo(otherInt) >= 0;
134 break;
135 }
136
137 return result;
138 }
139 };
140
141 fieldReferences = new ArrayList(10);
142
143 for (Iterator i = paramMap.entrySet().iterator(); i.hasNext();)
144 {
145 Map.Entry entry = (Map.Entry)i.next();
146 String key = (String)entry.getKey();
147 Constraint constraint = (Constraint)entry.getValue();
148
149 int compare = FieldReference.getCompareType(key);
150
151 if (compare != 0)
152 {
153 // found matching constraint
154 FieldReference fieldref = new FieldReference();
155 fieldref.setCompare(compare);
156 fieldref.setFieldName(constraint.getValue());
157 fieldref.setMessage(constraint.getMessage());
158
159 fieldReferences.add(fieldref);
160 }
161 }
162
163 if (fieldReferences.isEmpty())
164 {
165 log.warn("No reference field rules have been found.");
166 }
167 }
168
169 /**
170 * Determine whether a testValue meets the criteria specified
171 * in the constraints defined for this validator
172 *
173 * @param testField a <code>Field</code> to be tested
174 * @exception ValidationException containing an error message if the
175 * testValue did not pass the validation tests.
176 */
177 public void assertValidity(final Field testField)
178 throws ValidationException
179 {
180 super.assertValidity(testField);
181
182 Group thisGroup = testField.getGroup();
183
184 if (testField.isMultiValued())
185 {
186 String[] stringValues = (String[])testField.getTestValue();
187
188 for (int i = 0; i < stringValues.length; i++)
189 {
190 assertValidity(stringValues[i], thisGroup);
191 }
192 }
193 else
194 {
195 String testValue = (String)testField.getTestValue();
196
197 assertValidity(testValue, thisGroup);
198 }
199 }
200
201 /**
202 * Determine whether a testValue meets the criteria specified
203 * in the constraints defined for this validator
204 *
205 * @param testValue a <code>String</code> to be tested
206 * @param group the group this field belongs to
207 *
208 * @exception ValidationException containing an error message if the
209 * testValue did not pass the validation tests.
210 */
211 public void assertValidity(final String testValue, final Group group)
212 throws ValidationException
213 {
214 if (required || StringUtils.isNotEmpty(testValue))
215 {
216 Integer testInt = new Integer(testValue);
217
218 try
219 {
220 FieldReference.checkReferences(fieldReferences, compareCallback,
221 testInt, group);
222 }
223 catch (ValidationException e)
224 {
225 errorMessage = e.getMessage();
226 throw e;
227 }
228 }
229 }
230 }