1 18 19 package org.objectweb.jac.core.rtti; 20 21 import java.lang.NoSuchMethodException ; 22 import java.lang.reflect.InvocationTargetException ; 23 import java.lang.reflect.Method ; 24 import java.util.Arrays ; 25 import java.util.Vector ; 26 import org.apache.log4j.Logger; 27 import org.objectweb.jac.core.Wrappee; 28 import org.objectweb.jac.util.Strings; 29 import org.objectweb.jac.util.WrappedThrowableException; 30 31 62 63 public class MethodItem extends AbstractMethodItem { 64 static Logger logger = Logger.getLogger("rtti.method"); 65 66 74 75 public static Method [] toMethods( MethodItem[] methodItems ) { 76 Method [] res = new Method [methodItems.length]; 77 for ( int i = 0; i < methodItems.length; i++ ) { 78 if ( methodItems[i] == null ) { 79 res[i] = null; 80 } else { 81 res[i] = methodItems[i].getActualMethod(); 82 } 83 } 84 return res; 85 } 86 87 92 93 public MethodItem(Method delegate, ClassItem parent) 94 throws InvalidDelegateException 95 { 96 super(delegate,parent); 97 Class cl = delegate.getDeclaringClass(); 98 if (Wrappee.class.isAssignableFrom(cl)) { 99 String orgName = "_org_"+delegate.getName()+ 100 (isStatic?"":"_"+Strings.getShortClassName(cl)); 101 try { 102 orgMethod = 103 cl.getDeclaredMethod(orgName,delegate.getParameterTypes()); 104 orgMethod.setAccessible(true); 105 } catch(NoSuchMethodException e) { 106 } 108 } 109 } 110 111 Method orgMethod; 112 113 public final Method getOrgMethod() { 114 return orgMethod; 115 } 116 117 122 123 public final boolean hasAccessedReferences() { 124 ((ClassItem)parent).buildFieldInfo(); 125 return numAccessedReferences>0; 126 } 127 128 FieldItem returnedField; 129 134 public final FieldItem getReturnedField() { 135 return returnedField; 136 } 137 141 public void setReturnedField(FieldItem returnedField) { 142 if (this.returnedField!=null && 143 !(returnedField.isCalculated() && this.returnedField.isCalculated())) { 144 logger.warn("overriding returned field "+this.returnedField.getName()+ 145 " for "+getParent().getName()+"."+getName()+ 146 " with "+returnedField.getName()); 147 } 148 this.returnedField = returnedField; 149 } 150 151 FieldItem setField; 152 158 public final FieldItem getSetField() { 159 return setField; 160 } 161 165 public void setSetField(FieldItem setField) { 166 if (this.setField!=null && this.setField!=setField) { 167 logger.warn("overriding set field "+this.setField.getName()+ 168 " for "+getParent().getName()+"."+getName()+ 169 " with "+setField.getName()); 170 } 171 this.setField = setField; 172 } 173 174 175 CollectionItem[] addedCollections = null; 176 177 178 183 184 public final CollectionItem[] getAddedCollections() { 185 ((ClassItem)parent).buildFieldInfo(); 186 return addedCollections; 187 } 188 189 192 public final boolean hasAddedCollections() { 193 ((ClassItem)parent).buildFieldInfo(); 194 return addedCollections!=null && addedCollections.length>0; 195 } 196 197 203 204 public final void setAddedCollections(CollectionItem[] addedCollections) { 205 this.addedCollections = addedCollections; 206 } 207 208 214 215 public final void addAddedCollection(CollectionItem addedCollection) { 216 if (addedCollections == null) { 217 addedCollections = new CollectionItem[] { addedCollection }; 218 } else { 219 CollectionItem[] tmp = new CollectionItem[addedCollections.length + 1]; 220 System.arraycopy(addedCollections, 0, tmp, 0, addedCollections.length); 221 tmp[addedCollections.length] = addedCollection; 222 addedCollections = tmp; 223 } 224 } 225 226 232 public final void removeAddedCollection(CollectionItem collection) { 233 if (addedCollections != null) { 234 Vector v = new Vector (Arrays.asList(addedCollections)); 235 v.remove(collection); 236 addedCollections = new CollectionItem[v.size()]; 237 System.arraycopy(v.toArray(),0,addedCollections,0,v.size()); 238 } 239 } 240 241 246 247 public final Method getActualMethod() { 248 return (Method )delegate; 249 } 250 251 public final String getName() { 252 return ((Method )delegate).getName(); 253 } 254 255 public final Class getType() { 256 return ((Method )delegate).getReturnType(); 257 } 258 259 public Class [] getParameterTypes() { 260 return ((Method )delegate).getParameterTypes(); 261 } 262 263 int collectionIndexArgument = -1; 264 268 public int getCollectionIndexArgument() { 269 return collectionIndexArgument; 270 } 271 275 public void setCollectionIndexArgument(int collectionIndexArgument) { 276 this.collectionIndexArgument = collectionIndexArgument; 277 } 278 279 int collectionItemArgument = -1; 280 284 public int getCollectionItemArgument() { 285 return collectionItemArgument; 286 } 287 291 public void setCollectionItemArgument(int collectionItemArgument) { 292 this.collectionItemArgument = collectionItemArgument; 293 } 294 295 public void addAccessedField(FieldItem accessedField) { 296 super.addAccessedField(accessedField); 297 if (getType()!=void.class) 298 accessedField.addDependentMethod(this); 299 } 300 301 309 public Object invoke(Object object, Object [] parameters) 310 { 311 logger.debug(toString()+" invoke("+object+","+Arrays.asList(parameters)+")"); 312 if (!isStatic() && object==null) 313 throw new NullPointerException ( 314 "Invoking instance method "+ 315 parent.getName()+"."+this+" on null"); 316 try { 317 return ((Method )delegate).invoke(object,parameters); 318 } catch (IllegalArgumentException e) { 319 Class cl = (Class )getParent().getDelegate(); 320 if (!cl.isAssignableFrom(object.getClass())) { 321 throw new IllegalArgumentException ( 322 getLongName()+": called object "+Strings.hex(object)+ 323 " is not an instance of "+cl.getName()); 324 } 325 if (parameters.length == getParameterCount()) { 326 checkParameters(parameters); 327 } 328 throw e; 329 } catch (Exception e) { 330 logger.info("caught exception "+e); 331 throw new WrappedThrowableException(e); 332 } 333 } 334 335 340 void checkParameters(Object [] parameters) { 341 Class [] types = getParameterTypes(); 342 for (int i=0; i<types.length; i++) { 343 if (!types[i].isAssignableFrom(parameters[i].getClass())) 344 throw new IllegalArgumentException ( 345 getLongName()+", argument n°"+(i+1)+":"+ 346 parameters[i].getClass().getName()+ 347 " cannot be converted to "+types[i].getName()); 348 } 349 } 350 351 356 357 public final Object invokeStatic(Object [] parameters) 358 { 359 if (!isStatic()) 360 throw new RuntimeException ("Cannot invokeStatic a non static method: "+getLongName()); 361 try { 363 return ((Method )delegate).invoke(null,parameters); 364 } catch (IllegalArgumentException e) { 365 if (parameters.length == getParameterCount()) { 366 checkParameters(parameters); 367 } 368 throw e; 369 } catch (Exception e) { 370 logger.info("Caught exception in "+getFullName(),e); 371 throw new WrappedThrowableException(e); 372 } 373 } 374 375 384 385 public final Object invokeWithInit(Object object, 386 Object [] parameters) 387 throws IllegalAccessException , InvocationTargetException 388 { 389 390 Class [] paramTypes = getParameterTypes(); 391 for (int i=0; i< parameters.length; i++) { 392 if (parameters[i]==null) { 393 if (paramTypes[i] == float.class) { 394 parameters[i] = new Float (0.0); 395 } else if (paramTypes[i] == long.class) { 396 parameters[i] = new Long (0); 397 } else if (paramTypes[i] == double.class) { 398 parameters[i] = new Double (0.0); 399 } else if (paramTypes[i] == byte.class) { 400 parameters[i] = new Byte ((byte)0); 401 } else if (paramTypes[i] == char.class) { 402 parameters[i] = new Character (' '); 403 } else if (paramTypes[i] == short.class) { 404 parameters[i] = new Short ((short)0); 405 } else if (paramTypes[i] == int.class) { 406 parameters[i] = new Integer (0); 407 } else if (paramTypes[i] == boolean.class) { 408 parameters[i] = Boolean.FALSE; 409 } 410 } 411 } 412 return ((Method )delegate).invoke(object,parameters); 413 } 414 415 416 public final boolean isGetter() { 417 ((ClassItem)parent).buildFieldInfo(); 418 return returnedField!=null; 419 } 420 421 public final boolean isCollectionGetter() { 422 ((ClassItem)parent).buildFieldInfo(); 423 return returnedField!=null && (returnedField instanceof CollectionItem); 424 } 425 426 427 public final boolean isSetter() { 428 ((ClassItem)parent).buildFieldInfo(); 429 return setField!=null; 430 } 431 432 433 public final boolean isAdder() { 434 ((ClassItem)parent).buildFieldInfo(); 435 return addedCollections!=null && addedCollections.length>0; 436 } 437 438 439 440 CollectionItem[] removedCollections = null; 441 442 447 448 public final CollectionItem[] getRemovedCollections() { 449 ((ClassItem)parent).buildFieldInfo(); 450 return removedCollections; 451 } 452 453 public final CollectionItem getRemovedCollection() { 454 CollectionItem[] colls = getRemovedCollections(); 455 return ((colls != null) ? colls[0] : null); 456 } 457 458 461 462 public final boolean hasRemovedCollections() { 463 ((ClassItem)parent).buildFieldInfo(); 464 return removedCollections!=null && removedCollections.length>0; 465 } 466 467 473 474 public final void setRemovedCollections(CollectionItem[] removedCollections) { 475 this.removedCollections = removedCollections; 476 } 477 478 485 486 public final void addRemovedCollection(CollectionItem removedCollection) { 487 if (removedCollections == null) { 488 removedCollections = new CollectionItem[] { removedCollection }; 489 } else { 490 CollectionItem[] tmp = new CollectionItem[removedCollections.length+1]; 491 System.arraycopy(removedCollections, 0, tmp, 0, 492 removedCollections.length); 493 tmp[removedCollections.length] = removedCollection; 494 removedCollections = tmp; 495 } 496 } 497 498 504 public final void removeRemovedCollection(CollectionItem collection) { 505 if (removedCollections != null) { 506 Vector v = new Vector (Arrays.asList(removedCollections)); 507 v.remove(collection); 508 removedCollections = new CollectionItem[v.size()]; 509 System.arraycopy(v.toArray(),0,removedCollections,0,v.size()); 510 } 511 } 512 513 514 public final boolean isRemover() { 515 ((ClassItem)parent).buildFieldInfo(); 516 return removedCollections!=null && removedCollections.length>0; 517 } 518 519 public final boolean isAccessor() { 520 ((ClassItem)parent).buildFieldInfo(); 521 return accessedFields!=null && accessedFields.length>0; 522 } 523 524 public final boolean isWriter() { 525 ((ClassItem)parent).buildFieldInfo(); 526 return hasWrittenFields(); 527 } 528 529 public final boolean isCollectionAccessor() { 530 ((ClassItem)parent).buildFieldInfo(); 531 if (accessedFields!=null) { 532 for (int i=0; i<accessedFields.length; i++) { 533 if (accessedFields[i] instanceof CollectionItem) { 534 return true; 535 } 536 } 537 } 538 return false; 539 } 540 541 public final boolean isReferenceAccessor() { 542 ((ClassItem)parent).buildFieldInfo(); 543 if (accessedFields!=null) { 544 for (int i=0; i<accessedFields.length; i++) { 545 if (accessedFields[i].isReference()) { 546 return true; 547 } 548 } 549 } 550 return false; 551 } 552 553 public final boolean isCollectionSetter() { 554 ((ClassItem)parent).buildFieldInfo(); 555 return setField instanceof CollectionItem; 556 } 557 558 public final boolean isFieldSetter() { 559 ((ClassItem)parent).buildFieldInfo(); 560 return setField!=null && setField.isPrimitive(); 561 } 562 563 public final boolean isReferenceSetter() { 564 ((ClassItem)parent).buildFieldInfo(); 565 return setField!=null && setField.isReference(); 566 } 567 568 public final boolean isFieldGetter() { 569 ((ClassItem)parent).buildFieldInfo(); 570 return !(returnedField instanceof CollectionItem) 571 && returnedField.isPrimitive(); 572 } 573 574 public final boolean isReferenceGetter() { 575 ((ClassItem)parent).buildFieldInfo(); 576 return returnedField!=null && returnedField.isReference(); 577 } 578 579 580 public final boolean isJacMethod() { 581 return ClassRepository.isJacMethod(getName()); 582 } 583 584 public final static MethodItem[] emptyArray = new MethodItem[0]; 585 } | Popular Tags |