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 }