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.Iterator; 023 import java.util.List; 024 025 import org.apache.commons.logging.Log; 026 import org.apache.commons.logging.LogFactory; 027 import org.apache.fulcrum.intake.IntakeException; 028 import org.apache.fulcrum.intake.model.Field; 029 import org.apache.fulcrum.intake.model.Group; 030 031 /** 032 * Helper Class to manage relations between fields. The following 033 * comparisons are supported: 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 FieldReference 065 { 066 /** a local logger */ 067 protected static final Log log = LogFactory.getLog(FieldReference.class); 068 069 /** Rule name for "<" comparison */ 070 public static final String RANGE_LT = "less-than"; 071 072 /** Rule name for ">" comparison */ 073 public static final String RANGE_GT = "greater-than"; 074 075 /** Rule name for "<=" comparison */ 076 public static final String RANGE_LTE = "less-than-or-equal"; 077 078 /** Rule name for ">=" comparison */ 079 public static final String RANGE_GTE = "greater-than-or-equal"; 080 081 /** Integer value for "<" comparison */ 082 public static final int COMPARE_LT = 1; 083 084 /** Integer value for ">" comparison */ 085 public static final int COMPARE_GT = 2; 086 087 /** Integer value for "<=" comparison */ 088 public static final int COMPARE_LTE = 3; 089 090 /** Integer value for ">=" comparison */ 091 public static final int COMPARE_GTE = 4; 092 093 /** Numeric comparison */ 094 private int compare = 0; 095 096 /** Name of referenced field */ 097 private String fieldName = null; 098 099 /** Error message */ 100 private String message = null; 101 102 /** 103 * Constructor 104 */ 105 public FieldReference() 106 { 107 // do nothing 108 } 109 110 /** 111 * @return the comparison type 112 */ 113 public int getCompare() 114 { 115 return compare; 116 } 117 118 /** 119 * @param compare the comparison type to set 120 */ 121 public void setCompare(int compare) 122 { 123 this.compare = compare; 124 } 125 126 /** 127 * @return the field name 128 */ 129 public String getFieldName() 130 { 131 return fieldName; 132 } 133 134 /** 135 * @param fieldName the field name to set 136 */ 137 public void setFieldName(String fieldName) 138 { 139 this.fieldName = fieldName; 140 } 141 142 /** 143 * @return the message 144 */ 145 public String getMessage() 146 { 147 return message; 148 } 149 150 /** 151 * @param message the message to set 152 */ 153 public void setMessage(String message) 154 { 155 this.message = message; 156 } 157 158 /** 159 * Map the comparison strings to their numeric counterparts 160 * 161 * @param key the string representation of a comparison operator 162 * @return the numeric representation of the given comparison operator 163 */ 164 public static int getCompareType(String key) 165 { 166 int compareType = 0; 167 168 if (key.equals(RANGE_LT)) 169 { 170 compareType = COMPARE_LT; 171 } 172 else if (key.equals(RANGE_LTE)) 173 { 174 compareType = COMPARE_LTE; 175 } 176 else if (key.equals(RANGE_GT)) 177 { 178 compareType = COMPARE_GT; 179 } 180 else if (key.equals(RANGE_GTE)) 181 { 182 compareType = COMPARE_GTE; 183 } 184 185 return compareType; 186 } 187 188 /** 189 * Check the parsed value against the referenced fields 190 * 191 * @param fieldReferences List of field references to check 192 * @param compareCallback Callback to the actual compare operation 193 * @param value the parsed value of the related field 194 * @param group the group the related field belongs to 195 * 196 * @throws ValidationException 197 */ 198 public static void checkReferences(List fieldReferences, CompareCallback compareCallback, 199 Object value, Group group) 200 throws ValidationException 201 { 202 for (Iterator i = fieldReferences.iterator(); i.hasNext();) 203 { 204 FieldReference ref = (FieldReference)i.next(); 205 boolean comp_true = true; 206 207 try 208 { 209 Field refField = group.get(ref.getFieldName()); 210 211 if (refField.isSet()) 212 { 213 /* 214 * Fields are processed in sequence so that our 215 * reference field might have been set but not 216 * yet validated. We check this here. 217 */ 218 if (!refField.isValidated()) 219 { 220 refField.validate(); 221 } 222 223 if (refField.isValid()) 224 { 225 try 226 { 227 comp_true = compareCallback.compareValues(ref.getCompare(), 228 value, 229 refField.getValue()); 230 } 231 catch (ClassCastException e) 232 { 233 throw new IntakeException("Type mismatch comparing " + 234 value + " with " + refField.getValue(), e); 235 } 236 } 237 } 238 } 239 catch (IntakeException e) 240 { 241 log.error("Validate operation failed.", e); 242 throw new ValidationException(ref.getMessage()); 243 } 244 245 if (comp_true == false) 246 { 247 throw new ValidationException(ref.getMessage()); 248 } 249 } 250 } 251 }