1 18 19 package org.objectweb.jac.core.rtti; 20 21 import java.lang.reflect.InvocationTargetException ; 22 import java.util.Collection ; 23 import java.util.HashSet ; 24 import java.util.Hashtable ; 25 import java.util.Map ; 26 import java.util.Set ; 27 import org.apache.log4j.Logger; 28 import org.objectweb.jac.core.AspectComponent; 29 import org.objectweb.jac.core.Wrappee; 30 import java.lang.reflect.Method ; 31 32 46 47 public class RttiAC extends AspectComponent implements RttiConf { 48 static Logger logger = Logger.getLogger("rtti"); 49 50 public static final String OPPOSITE_ROLE = "RttiAC.OPPOSITE_ROLE"; 51 public static final String FIELD_TYPE = "RttiAC.FIELD_TYPE"; 52 public static final String DYNAMIC_FIELD_TYPE = "RttiAC.DYNAMIC_FIELD_TYPE"; 53 public static final String PARAMETER_TYPES = "RttiAC.PARAMETERS_TYPES"; 54 public static final String CLONED_FIELDS = "RttiAC.CLONED_FIELDS"; 55 public static final String REPOSITORY_NAME = "RttiAC.REPOSITORY_NAME"; 56 public static final String REPOSITORY_COLLECTION = "RttiAC.REPOSITORY_COLLECTION"; 57 public static final String NULL_ALLOWED_PARAMETERS = "RttiAC.NULL_ALOWED_PARAMETERS"; 58 public static final String NULL_ALLOWED = "RttiAC.NULL_ALLOWED"; public static final String IS_INDEX = "RttiAC.IS_INDEX"; public static final String INDEXED_FIELD = "RttiAC.INDEXED_FIELD"; public static final String AUTHORIZED_VALUES = "RttiAC.AUTHORIZED_VALUES"; 62 public static final String FORBIDDEN_VALUES = "RttiAC.FORBIDDEN_VALUES"; 63 public static final String CONSTRAINTS = "RttiAC.CONSTRAINTS"; 64 public static final String PARAMETERS_FIELDS = "RttiAC.PARAMETERS_FIELDS"; 66 public static final String PRIMARY_KEY = "RttiAC.PRIMARY_KEY"; 67 68 public void addWrittenFields(AbstractMethodItem method, 69 String [] writtenFields) { 70 ClassItem cl = method.getClassItem(); 71 for( int i=0; i<writtenFields.length; i++ ) { 72 FieldItem fi = cl.getField(writtenFields[i]); 73 method.addWrittenField(fi); 74 } 75 } 76 77 public void declareCalculatedField(ClassItem cl, String fieldName, 78 String getterName) 79 { 80 MethodItem getter = cl.getMethod(getterName); 81 FieldItem calculatedField; 82 if (RttiAC.isCollectionType(getter.getType())) 83 calculatedField = new CollectionItem(fieldName,getter,cl); 84 else 85 calculatedField = new FieldItem(fieldName,getter,cl); 86 cl.addField(calculatedField); 87 FieldItem[] fields = getter.getAccessedFields(); 88 for (int i=0;i<fields.length;i++) { 89 if (fields[i]!=calculatedField) { 90 logger.debug(calculatedField.getLongName()+" depends on "+fields[i]); 91 fields[i].addDependentField(calculatedField); 92 } 93 } 94 } 95 96 public void setSetter(FieldItem field, String setterName) { 97 MethodItem setter = field.getClassItem().getMethod(setterName); 98 setter.setSetField(field); 99 field.setSetter(setter); 100 } 101 102 public void setGetter(FieldItem field, String getterName) { 103 MethodItem getter = field.getClassItem().getMethod(getterName); 104 getter.setReturnedField(field); 105 field.setGetter(getter); 106 } 107 108 public void addDependentField(FieldItem field, String dependentField) { 109 field.getClassItem().getField(dependentField).addDependentField(field); 110 } 111 112 public void addFieldDependency(FieldItem field, FieldItem dependentField) { 113 field.addDependentField(dependentField); 114 } 115 116 public void addAdder(CollectionItem collection, String methodName) { 117 MethodItem method = collection.getClassItem().getMethod(methodName); 118 collection.addAddingMethod(method); 119 method.addAddedCollection(collection); 120 } 121 122 public void setAdder(CollectionItem collection, String methodName) { 123 MethodItem method = collection.getClassItem().getMethod(methodName); 124 collection.setAdder(method); 125 method.addAddedCollection(collection); 126 } 127 128 public void addRemover(CollectionItem collection,String methodName) { 129 MethodItem method = collection.getClassItem().getMethod(methodName); 130 collection.addRemovingMethod(method); 131 method.addRemovedCollection(collection); 132 } 133 134 public void setRemover(CollectionItem collection,String methodName) { 135 MethodItem method = collection.getClassItem().getMethod(methodName); 136 collection.setRemover(method); 137 method.addRemovedCollection(collection); 138 } 139 140 public void addAccessedFields(MethodItem method, 141 String [] accessedFields) { 142 ClassItem cl = method.getClassItem(); 143 for(int i=0; i<accessedFields.length; i++) { 144 FieldItem fi = cl.getField(accessedFields[i]); 145 method.addAccessedField(fi); 146 } 147 } 148 149 public void setFieldType(FieldItem field, String type) 150 { 151 Object cl = ClassRepository.get().getObject(type); 152 153 if (cl == null) 154 throw new RuntimeException ("no such type "+type); 155 156 field.setAttribute(FIELD_TYPE, cl); 157 } 158 159 public void setDynamicFieldType(FieldItem field, MethodItem method) { 160 if (!method.isStatic()) { 161 error("Method must be static"); 162 } if (!(method.getType()==String .class 163 || method.getType()==Object .class 164 || MetaItem.class.isAssignableFrom(method.getType()))) { 165 error("Method must return a String, a MetaItem or an Object"); 166 } else { 167 field.setAttribute(DYNAMIC_FIELD_TYPE, method); 168 } 169 } 170 171 public void setComponentType(CollectionItem collection, String type) { 172 collection.setComponentType(currentImports.getClass(type)); 173 } 174 175 180 public static MetaItem getFieldType(FieldItem field) { 181 return (MetaItem)field.getAttribute(FIELD_TYPE); 182 } 183 184 190 public static MetaItem getFieldType(FieldItem field, Object substance) { 191 MethodItem dynType = (MethodItem)field.getAttribute(DYNAMIC_FIELD_TYPE); 192 if (dynType!=null) { 193 Object type = dynType.invokeStatic(new Object [] {field,substance}); 194 if (type instanceof String ) 195 return cr.getVirtualClass((String )type); 196 else 197 return (MetaItem)type; 198 } else { 199 return getFieldType(field); 200 } 201 } 202 203 public void setParametersType(AbstractMethodItem method, 204 String [] types) 205 { 206 ClassRepository cr = ClassRepository.get(); 207 MetaItem[] metaItems = new MetaItem[types.length]; 208 for (int i=0; i<types.length;i++) { 209 metaItems[i] = (MetaItem)cr.getObject(types[i]); 210 } 211 method.setAttribute(PARAMETER_TYPES,metaItems); 212 } 213 214 public void newVirtualClass(String className, ClassItem actualType) 215 { 216 logger.info("newVirtualClass("+className+")"); 217 ClassRepository.get().register(className, 218 new VirtualClassItem(className,actualType)); 219 } 220 221 public void defineRepository(ClassItem type, 222 String repositoryName, 223 CollectionItem repositoryCollection) 224 { 225 type.setAttribute(REPOSITORY_NAME, repositoryName); 226 type.setAttribute(REPOSITORY_COLLECTION, repositoryCollection); 227 } 228 229 public void setClonedFields(String className, String [] fields) { 230 ClassRepository.get().getClass(className) 231 .setAttribute(CLONED_FIELDS,fields); 232 } 233 234 public void whenClone(Wrappee cloned, Wrappee clone) { 235 236 ClassItem cli = ClassRepository.get().getClass(cloned.getClass()); 237 String [] clonedFields = (String [])cli.getAttribute(CLONED_FIELDS); 238 239 if( clonedFields != null ) { 240 for( int i=0; i<clonedFields.length; i++ ) { 241 FieldItem fi = cli.getField( clonedFields[i] ); 242 logger.debug("cloning field "+clonedFields[i]); 243 248 } 249 } 250 } 251 252 public void ignoreFields(String packageExpr) { 253 logger.info("ignoreFields"+packageExpr); 254 ClassRepository.get().ignoreFields(packageExpr); 255 } 256 257 void setItemClass(MetaItem item, String className, ClassItem actualType) { 258 MetaItem virtualClass; 259 ClassRepository cr = ClassRepository.get(); 260 try { 261 virtualClass = cr.getVirtualClass(className); 262 } catch (NoSuchClassException e) { 263 virtualClass = new VirtualClassItem(className,actualType); 264 cr.register(className,virtualClass); 265 } 266 item.setItemClass(virtualClass); 267 } 268 269 public void setClass(MemberItem member, String className) { 270 setItemClass(member,className,member.getTypeItem()); 271 } 272 273 public void setClass(ClassItem cli, String className) { 274 setItemClass(cli,className,cli); 275 } 276 277 282 283 public void setParametersFields(AbstractMethodItem method, 284 FieldItem[] fields) { 285 method.setAttribute(PARAMETERS_FIELDS, fields); 286 } 287 288 public void setNullAllowed(FieldItem field) { 289 setNullAllowed(field,true); 290 } 291 292 public void setNullAllowed(FieldItem field, boolean allowed) { 293 field.setAttribute(NULL_ALLOWED, allowed ? Boolean.TRUE : Boolean.FALSE); 294 logger.info("setNullAllowed("+field.getName()+")"); 295 } 296 297 public static boolean isNullAllowed(FieldItem field) { 298 Boolean result = (Boolean ) field.getAttribute(NULL_ALLOWED); 299 if (result == null) 300 return false; 301 return result.booleanValue(); 302 } 303 304 public void setNullAllowedParameters(AbstractMethodItem method, 305 boolean[] nulls) { 306 method.setAttribute(NULL_ALLOWED_PARAMETERS, nulls); 307 } 308 309 public static boolean isNullAllowedParameter(AbstractMethodItem method, 310 int i) { 311 boolean[] nulls=(boolean[])method.getAttribute(NULL_ALLOWED_PARAMETERS); 313 if(nulls==null) return false; 314 return nulls[i]; 316 } 317 318 public void setAggregation(FieldItem field, boolean isAggregation) { 319 field.setAggregation(isAggregation); 320 } 321 322 public void setIndexedField(CollectionItem collection, 323 FieldItem indexedField) { 324 setIsIndex(collection,true); 325 collection.setAttribute(INDEXED_FIELD, indexedField); 326 } 327 328 public void setIsIndex(CollectionItem collection, 329 boolean isIndex) { 330 collection.setAttribute(IS_INDEX, isIndex?Boolean.TRUE:Boolean.FALSE); 331 } 332 333 public static FieldItem getIndexFied(CollectionItem collection) { 334 return (FieldItem)collection.getAttribute(INDEXED_FIELD); 335 } 336 337 public static boolean isIndex(CollectionItem collection) { 338 Boolean result = (Boolean ) collection.getAttribute(IS_INDEX); 339 if (result == null) 340 return false; 341 return result.booleanValue(); 342 } 343 344 public String [] getDefaultConfigs() { 345 return new String [] {"org/objectweb/jac/core/rtti/rtti.acc", 346 "org/objectweb/jac/aspects/user/rtti.acc"}; 347 } 348 349 public void definePrimaryKey(CollectionItem collection, 350 String [] fields) { 351 collection.setAttribute(PRIMARY_KEY, fields); 352 } 353 354 357 public static boolean isCollectionType(Class type) { 358 return Collection .class.isAssignableFrom(type) || 359 Map .class.isAssignableFrom(type) || 360 (type.isArray() && type.getComponentType()!=byte.class); 361 } 362 363 static Hashtable allowedCasts = new Hashtable (); 364 public void addAllowedCast(ClassItem src, ClassItem dest) { 365 Set casts = (Set )allowedCasts.get(src); 366 if (casts == null) { 367 casts = new HashSet (); 368 allowedCasts.put(src,casts); 369 } 370 casts.add(dest); 371 } 372 373 public static boolean isCastAllowed(ClassItem src, ClassItem dest) { 374 Set casts = (Set )allowedCasts.get(src); 375 return casts!=null && casts.contains(dest); 376 } 377 378 public static boolean isCastAllowed(Class src, Class dest) { 379 ClassRepository cr = ClassRepository.get(); 380 return isCastAllowed(cr.getClass(src),cr.getClass(dest)); 381 } 382 383 HashSet classesWithAssociations = new HashSet (); 384 public Set getClassesWithAssociations() { 385 return classesWithAssociations; 386 } 387 388 public void setOppositeRole(FieldItem field, FieldItem oppositeRole) { 389 field.setOppositeRole(oppositeRole); 390 classesWithAssociations.add(field.getClassItem()); 391 } 392 393 public void declareAssociation(FieldItem roleA, FieldItem roleB) { 394 roleA.setOppositeRole(roleB); 395 roleB.setOppositeRole(roleA); 396 classesWithAssociations.add(roleA.getClassItem()); 397 classesWithAssociations.add(roleB.getClassItem()); 398 } 399 400 416 public static Object convert(Object value, Class type) 417 throws InstantiationException , IllegalAccessException , 418 InvocationTargetException , java.lang.NoSuchMethodException 419 { 420 Class valueType = value.getClass(); 421 if ((type==int.class || type==Integer .class) 422 && (valueType==float.class || valueType==Float .class 423 || valueType==double.class || valueType==Double .class)) { 424 return new Integer (((Number )value).intValue()); 425 } else if ((type==long.class || type==Long .class) 426 && (valueType==float.class || valueType==Float .class 427 || valueType==double.class || valueType==Double .class)) { 428 return new Long (((Number )value).longValue()); 429 } else if (type==String .class) { 430 return value.toString(); 431 } else { 432 if (RttiAC.isCastAllowed(valueType,type)) { 433 return 434 type.getConstructor(new Class [] {valueType}) 435 .newInstance(new Object [] {value}); 436 } 437 } 438 return value; 439 } 440 441 public void addMixinMethod(ClassItem cli, MethodItem method) 442 throws InvalidDelegateException 443 { 444 cli.addMethod(new MixinMethodItem((Method )method.getDelegate(),cli)); 445 } 446 447 } 448 | Popular Tags |