001 /* 002 Copyright (C) 2002 Julien van Malderen, Renaud Pawlak <renaud@aopsys.com> 003 004 This program is free software; you can redistribute it and/or modify 005 it under the terms of the GNU Lesser General Public License as 006 published by the Free Software Foundation; either version 2 of the 007 License, or (at your option) any later version. 008 009 This program is distributed in the hope that it will be useful, 010 but WITHOUT ANY WARRANTY; without even the implied warranty of 011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 012 GNU Lesser General Public License for more details. 013 014 You should have received a copy of the GNU Lesser General Public License 015 along with this program; if not, write to the Free Software 016 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 017 018 package org.objectweb.jac.aspects.integrity; 019 020 import java.util.Iterator; 021 import org.apache.log4j.Logger; 022 import org.objectweb.jac.core.ACConfiguration; 023 import org.objectweb.jac.core.ObjectRepository; 024 import org.objectweb.jac.core.rtti.ClassItem; 025 import org.objectweb.jac.core.rtti.ClassRepository; 026 import org.objectweb.jac.core.rtti.FieldItem; 027 028 /** 029 * Some basic methods for constraints on fields values. 030 * 031 * <p>Constraint methods must return a Boolean that is 032 * <code>Boolean.TRUE</code> if the test has been validated (passed), 033 * <code>Boolean.FALSE</code> else. Their parameters are :</p> 034 * 035 * <ul><li><code>Wrappee wrappee</code>: the substance object 036 * (holding the field)</li> 037 * 038 * <li><code>FieldItem field</code>: the constrained field</li> 039 * 040 * <li><code>Object value</code>: the proposed future value of the 041 * field (can be refused by the contraint)</li> 042 * 043 * <li><code>Object[] values</code>: some configuration params that 044 * can be used in the test</li></ul> 045 * 046 * @see IntegrityAC#addPreCondition(FieldItem,MethodItem,Object[],String) 047 * @see IntegrityAC#addPostCondition(FieldItem,MethodItem,Object[],String) 048 * @see IntegrityAC#doCheck() */ 049 050 public class GenericConditions { 051 static final Logger logger = Logger.getLogger("integrity.conditions"); 052 053 /** 054 * If obj1 and obj2 are instances of String, uses equals(), else ==. 055 */ 056 private static boolean areEqual(Object obj1, Object obj2) 057 { 058 logger.debug("areEqual("+obj1+","+obj2+")"); 059 if(obj1 instanceof String && obj2 instanceof String) { 060 return ((String) obj1).equals((String) obj2); 061 } 062 063 return (obj1 == obj2); 064 } 065 066 /** 067 * Check if field's value is not equal to the forbidden values. If 068 * it is, the method returns <code>false</code>. 069 * 070 * @param substance the object that owns the field 071 * @param field the tested field 072 * @param value the value that is about to be set 073 * @param values the forbidden values 074 */ 075 public static boolean forbiddenValues(Object substance, 076 FieldItem field, 077 Object value, 078 Object[] values) 079 { 080 for (int i=0; i<values.length; i++) 081 if (areEqual(value, values[i])) 082 return false; 083 return true; 084 } 085 086 /** 087 * Check if field's value is equal to one of the authorized 088 * values. If it is not, the method returns 089 * <code>false</code>. 090 * 091 * @param substance the object that owns the field 092 * @param field the tested field 093 * @param value the value that is about to be set 094 * @param values the authorized values 095 */ 096 public static boolean authorizedValues(Object substance, 097 FieldItem field, 098 Object value, 099 Object[] values) 100 { 101 for (int i=0; i<values.length; i++) 102 if (areEqual(value, values[i])) 103 return true; 104 return false; 105 } 106 107 /** 108 * Check if this field already has the same value in another object 109 * of the same type. 110 * 111 * @param substance the object that owns the field 112 * @param field the tested field 113 * @param value the value that is about to be set 114 * @param values unused 115 */ 116 public static boolean isUniqueValue(Object substance, 117 FieldItem field, 118 Object value, 119 Object[] values) 120 { 121 ClassItem cli = ClassRepository.get().getClass(substance); 122 Iterator it = ObjectRepository.getObjects(cli).iterator(); 123 return true; 124 } 125 126 /** 127 * Tells if the value is an upper-case char begining string. 128 * 129 * @param substance the object that owns the field 130 * @param field the tested field 131 * @param value the value that is about to be set 132 * @param values unused 133 */ 134 public static boolean isBeginingWithUpperCaseChar(Object substance, 135 FieldItem field, 136 Object value, 137 Object[] values) 138 { 139 if (value instanceof String) { 140 String s = (String)value; 141 if (s==null || s.length()==0 || 142 Character.isUpperCase(s.charAt(0))) 143 { 144 return true; 145 } else { 146 return false; 147 } 148 } 149 throw new RuntimeException("Invalid constraint check: "+value+ 150 " is not a string"); 151 } 152 153 public static boolean isNotNull(Object substance, 154 FieldItem field, 155 Object value, 156 Object[] values) 157 { 158 return value != null; 159 } 160 161 public static boolean isNull(Object substance, 162 FieldItem field, 163 Object value, 164 Object[] values) 165 { 166 return value == null; 167 } 168 169 170 /** 171 * Tells if the value is a letter begining string. 172 * 173 * @param substance the object that owns the field 174 * @param field the tested field 175 * @param value the value that is about to be set 176 * @param values unused 177 */ 178 public static boolean isBeginingWithLetter(Object substance, 179 FieldItem field, 180 Object value, 181 Object[] values) 182 { 183 if (value instanceof String) { 184 String s = (String)value; 185 if (s==null || s.length()==0 || 186 Character.isLetter(s.charAt(0))) 187 { 188 return true; 189 } else { 190 return false; 191 } 192 } 193 throw new RuntimeException("Invalid constraint check: "+value+ 194 " is not a string"); 195 } 196 197 /** 198 * Tells if the value is a valid java identifier. 199 * 200 * @param substance the object that owns the field 201 * @param field the tested field 202 * @param value the value that is about to be set 203 * @param values unused 204 */ 205 public static boolean isJavaIdentifier(Object substance, 206 FieldItem field, 207 Object value, 208 Object[] values) 209 { 210 if (value instanceof String) { 211 String s=(String)value; 212 if (s==null) 213 return true; 214 if (s.length()==0) 215 return false; 216 if (!Character.isJavaIdentifierStart(s.charAt(0))) 217 return false; 218 for(int i=1;i<s.length(); i++) { 219 if(!Character.isJavaIdentifierPart(s.charAt(i))) 220 return false; 221 } 222 return true; 223 } 224 throw new RuntimeException("Invalid constraint check: "+value+ 225 " is not a string"); 226 } 227 228 /** 229 * Tells if the value is greater than a given number. 230 * 231 * @param substance the object that owns the field 232 * @param field the tested field 233 * @param value the value that is about to be set 234 * @param values unused 235 */ 236 public static boolean isGreaterThan(Object substance, 237 FieldItem field, 238 Object value, 239 Object[] values) 240 throws Exception 241 { 242 if (value instanceof Number) { 243 Number th = (Number)ACConfiguration.convertValue(values[0], 244 value.getClass()); 245 if (((Number)value).doubleValue()>th.doubleValue()) { 246 return true; 247 } else { 248 return false; 249 } 250 } 251 throw new RuntimeException("Invalid constraint check: "+value+ 252 " is not a number"); 253 } 254 255 /** 256 * Tells if the value is lower than a given number. 257 * 258 * @param substance the object that owns the field 259 * @param field the tested field 260 * @param value the value that is about to be set 261 * @param values unused 262 */ 263 public static boolean isLowerThan(Object substance, 264 FieldItem field, 265 Object value, 266 Object[] values) 267 throws Exception 268 { 269 if (value instanceof Number) { 270 Number th = (Number)ACConfiguration.convertValue(values[0], 271 value.getClass()); 272 if (((Number)value).doubleValue()<th.doubleValue()) { 273 return true; 274 } else { 275 return false; 276 } 277 } 278 throw new RuntimeException("Invalid constraint check: "+value+ 279 " is not a number"); 280 } 281 282 }