1 31 package org.objectweb.proactive.core.mop; 32 33 import java.io.ByteArrayInputStream ; 34 import java.io.ByteArrayOutputStream ; 35 import java.lang.reflect.InvocationTargetException ; 36 import java.lang.reflect.Method ; 37 38 import org.apache.log4j.Logger; 39 40 import sun.rmi.server.MarshalInputStream; 41 import sun.rmi.server.MarshalOutputStream; 42 43 44 51 public class MethodCall implements java.io.Serializable { 52 private String tag; 54 55 private String fcFunctionalInterfaceName; 58 59 63 68 private static transient java.util.Hashtable ASYNORNOT = new java.util.Hashtable (); 69 70 private static Logger logger = Logger.getLogger(MethodCall.class.getName()); 71 72 75 private static int RECYCLE_POOL_SIZE = 30; 76 77 80 private static MethodCall[] recyclePool; 81 82 85 private static int index; 86 87 88 private static boolean recycleMethodCallObject; 89 private static java.util.Hashtable reifiedMethodsTable = new java.util.Hashtable (); 90 91 public static final String COMPONENT_TAG = "component-methodCall"; 93 94 97 static { 98 MethodCall.setRecycleMethodCallObject(false); 99 } 100 101 105 108 private Object [] effectiveArguments; 109 110 113 private transient Method reifiedMethod; 114 115 118 private long methodCallID; 119 private String key; 120 121 127 private byte[] serializedEffectiveArguments = null; 128 129 132 public void transformEffectiveArgumentsIntoByteArray() { 133 if ((serializedEffectiveArguments == null) && 134 (effectiveArguments != null)) { 135 try { 136 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream (); 137 138 MarshalOutputStream objectOutputStream = new MarshalOutputStream(byteArrayOutputStream); 140 objectOutputStream.writeObject(effectiveArguments); 141 objectOutputStream.flush(); 142 objectOutputStream.close(); 143 byteArrayOutputStream.close(); 144 serializedEffectiveArguments = byteArrayOutputStream.toByteArray(); 145 } catch (Exception e) { 146 e.printStackTrace(); 147 } 148 effectiveArguments = null; 149 } 150 } 151 152 158 public static synchronized void setRecycleMethodCallObject(boolean value) { 159 if (recycleMethodCallObject == value) { 160 return; 161 } else { 162 recycleMethodCallObject = value; 163 if (value) { 164 recyclePool = new MethodCall[RECYCLE_POOL_SIZE]; 166 index = 0; 167 } else { 168 recyclePool = null; 172 } 173 } 174 } 175 176 181 public static synchronized boolean getRecycleMethodCallObject() { 182 return MethodCall.recycleMethodCallObject; 183 } 184 185 198 public synchronized static MethodCall getMethodCall(Method reifiedMethod, 199 Object [] effectiveArguments) { 200 if (MethodCall.getRecycleMethodCallObject()) { 201 if (MethodCall.index > 0) { 204 MethodCall.index--; 206 MethodCall result = MethodCall.recyclePool[MethodCall.index]; 207 MethodCall.recyclePool[MethodCall.index] = null; 208 result.reifiedMethod = reifiedMethod; 210 result.effectiveArguments = effectiveArguments; 211 result.key = buildKey(reifiedMethod); 212 return result; 213 } else { 214 return new MethodCall(reifiedMethod, effectiveArguments); 215 } 216 } else { 217 return new MethodCall(reifiedMethod, effectiveArguments); 218 } 219 } 220 221 231 public synchronized static MethodCall getComponentMethodCall( 232 Method reifiedMethod, Object [] effectiveArguments, 233 String fcFunctionalInterfaceName) { 234 MethodCall mc = MethodCall.getMethodCall(reifiedMethod, 236 effectiveArguments); 237 mc.setTag(COMPONENT_TAG); 238 mc.setFcFunctionalInterfaceName(fcFunctionalInterfaceName); 239 return mc; 240 } 241 242 247 public synchronized static void setMethodCall(MethodCall mc) { 248 if (MethodCall.getRecycleMethodCallObject()) { 249 if (MethodCall.recyclePool[MethodCall.index] == null) { 251 mc.fcFunctionalInterfaceName = null; 256 mc.tag = null; 257 mc.reifiedMethod = null; 258 mc.effectiveArguments = null; 259 mc.key = null; 260 MethodCall.recyclePool[MethodCall.index] = mc; 262 MethodCall.index++; 263 if (MethodCall.index == RECYCLE_POOL_SIZE) { 264 MethodCall.index = RECYCLE_POOL_SIZE - 1; 265 } 266 } 267 } 268 } 269 270 275 276 public MethodCall(Method reifiedMethod, Object [] effectiveArguments) { 280 this.reifiedMethod = reifiedMethod; 281 this.effectiveArguments = effectiveArguments; 282 this.key = buildKey(reifiedMethod); 283 } 284 285 292 public MethodCall(MethodCall mc) { 293 try { 294 this.fcFunctionalInterfaceName = mc.getFcFunctionalInterfaceName(); 295 this.reifiedMethod = mc.getReifiedMethod(); 296 this.tag = mc.getTag(); 297 if (mc.serializedEffectiveArguments == null) { 298 serializedEffectiveArguments = null; 299 } else { 300 byte[] source = mc.serializedEffectiveArguments; 302 serializedEffectiveArguments = new byte[source.length]; 303 for (int i = 0; i < serializedEffectiveArguments.length; i++) { 304 serializedEffectiveArguments[i] = source[i]; 305 } 306 } 307 if (mc.effectiveArguments == null) { 308 effectiveArguments = null; 309 } else { 310 effectiveArguments = (Object []) Utils.makeDeepCopy(mc.effectiveArguments); 312 } 313 this.key = MethodCall.buildKey(mc.getReifiedMethod()); 314 } catch (java.io.IOException e) { 316 e.printStackTrace(); 317 } 318 } 319 320 323 protected MethodCall() { 324 this.reifiedMethod = null; 325 this.effectiveArguments = null; 326 this.serializedEffectiveArguments = null; 327 } 328 329 330 345 public Object execute(Object targetObject) 346 throws InvocationTargetException , MethodCallExecutionFailedException { 347 if ((serializedEffectiveArguments != null) && 349 (effectiveArguments == null)) { 350 try { 351 ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream (serializedEffectiveArguments); 352 353 MarshalInputStream objectInputStream = new MarshalInputStream(byteArrayInputStream); 355 effectiveArguments = (Object []) objectInputStream.readObject(); 356 objectInputStream.close(); 357 byteArrayInputStream.close(); 358 } catch (Exception e) { 359 e.printStackTrace(); 360 } 361 serializedEffectiveArguments = null; 362 } 363 if (logger.isDebugEnabled()) { 364 logger.debug("MethodCall.execute() name = " + this.getName()); 365 logger.debug("MethodCall.execute() reifiedMethod = " + 366 reifiedMethod); 367 logger.debug( 368 "MethodCall.execute() reifiedMethod.getDeclaringClass() = " + 369 reifiedMethod.getDeclaringClass()); 370 logger.debug("MethodCall.execute() targetObject " + targetObject); 371 } 372 if (reifiedMethod.getParameterTypes().length > 0) { 373 reifiedMethod.setAccessible(true); 374 } 375 try { 376 return reifiedMethod.invoke(targetObject, effectiveArguments); 377 } catch (IllegalAccessException e) { 378 throw new MethodCallExecutionFailedException( 379 "Access rights to the method denied: " + e); 380 } 381 } 382 383 protected void finalize() { 384 MethodCall.setMethodCall(this); 385 } 386 387 public Method getReifiedMethod() { 388 return reifiedMethod; 389 } 390 391 395 public String getName() { 396 return reifiedMethod.getName(); 397 } 398 399 public int getNumberOfParameter() { 400 return this.effectiveArguments.length; 401 } 402 403 public Object getParameter(int index) { 404 return this.effectiveArguments[index]; 405 } 406 407 public void setEffectiveArguments(Object [] o) { 408 effectiveArguments = o; 409 } 410 411 414 public void makeDeepCopyOfArguments() throws java.io.IOException { 415 effectiveArguments = (Object []) Utils.makeDeepCopy(effectiveArguments); 416 } 417 418 422 public String getFcFunctionalInterfaceName() { 423 return fcFunctionalInterfaceName; 424 } 425 426 430 public void setFcFunctionalInterfaceName(String string) { 431 fcFunctionalInterfaceName = string; 432 } 433 434 437 public void setTag(String string) { 438 tag = string; 439 } 440 441 445 public String getTag() { 446 return tag; 447 } 448 449 private Class [] fixBugRead(FixWrapper[] para) { 453 Class [] tmp = new Class [para.length]; 454 for (int i = 0; i < para.length; i++) { 455 tmp[i] = para[i].getWrapped(); 457 } 458 return tmp; 459 } 460 461 private FixWrapper[] fixBugWrite(Class [] para) { 462 FixWrapper[] tmp = new FixWrapper[para.length]; 463 for (int i = 0; i < para.length; i++) { 464 tmp[i] = new FixWrapper(para[i]); 466 } 467 return tmp; 468 } 469 470 private static String buildKey(Method reifiedMethod) { 471 StringBuffer sb = new StringBuffer (); 472 sb.append(reifiedMethod.getDeclaringClass().getName()); 473 sb.append(reifiedMethod.getName()); 474 Class [] parameters = reifiedMethod.getParameterTypes(); 475 for (int i = 0; i < parameters.length; i++) { 476 sb.append(parameters[i].getName()); 477 } 478 return sb.toString(); 479 } 480 481 private void writeObject(java.io.ObjectOutputStream out) 485 throws java.io.IOException { 486 this.writeTheObject(out); 487 } 488 489 protected void writeTheObject(java.io.ObjectOutputStream out) 490 throws java.io.IOException { 491 out.defaultWriteObject(); 492 out.writeObject(reifiedMethod.getDeclaringClass()); 494 out.writeObject(reifiedMethod.getName()); 495 out.writeObject(fixBugWrite(reifiedMethod.getParameterTypes())); 496 } 497 498 499 private void readObject(java.io.ObjectInputStream in) 500 throws java.io.IOException , ClassNotFoundException { 501 this.readTheObject(in); 502 } 503 504 505 protected void readTheObject(java.io.ObjectInputStream in) 506 throws java.io.IOException , ClassNotFoundException { 507 in.defaultReadObject(); 508 reifiedMethod = (Method ) reifiedMethodsTable.get(key); 509 if (reifiedMethod == null) { 510 Class declaringClass = (Class ) in.readObject(); 512 String simpleName = (String ) in.readObject(); 513 Class [] parameters = this.fixBugRead((FixWrapper[]) in.readObject()); 514 515 try { 517 reifiedMethod = declaringClass.getMethod(simpleName, parameters); 518 reifiedMethodsTable.put(key, reifiedMethod); 519 } catch (NoSuchMethodException e) { 520 throw new InternalException("Lookup for method failed: " + e + 521 ". This may be caused by having different versions of the same class on different VMs. Check your CLASSPATH settings."); 522 } 523 } else { in.readObject(); 525 in.readObject(); 526 in.readObject(); 527 } 528 if ((serializedEffectiveArguments != null) && 529 (effectiveArguments == null)) { 530 try { 531 ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream (serializedEffectiveArguments); 532 533 MarshalInputStream objectInputStream = new MarshalInputStream(byteArrayInputStream); 535 effectiveArguments = (Object []) objectInputStream.readObject(); 536 objectInputStream.close(); 537 byteArrayInputStream.close(); 538 } catch (Exception e) { 539 e.printStackTrace(); 540 } 541 serializedEffectiveArguments = null; 542 } 543 } 544 545 546 553 public boolean isOneWayCall() { 554 return (this.getReifiedMethod().getReturnType().equals(java.lang.Void.TYPE)) && (this.getReifiedMethod().getExceptionTypes().length == 0); 555 } 556 557 558 569 public boolean isAsynchronousWayCall() { 570 Method m = this.getReifiedMethod(); 571 Boolean b = (Boolean )MethodCall.ASYNORNOT.get(m); 573 if (b != null) { 574 return b.booleanValue(); 575 } else { 577 boolean result; 578 if (this.isOneWayCall()) { 581 result = true; 582 } else { 583 try { 584 MOP.checkClassIsReifiable(m.getReturnType()); 585 if (m.getExceptionTypes().length > 0) { 587 result = false; 589 } else { 590 result = true; 591 } 592 } catch (ClassNotReifiableException e) { 593 result = false; 595 } 596 MethodCall.ASYNORNOT.put(m, new Boolean (result)); 599 } 600 return result; 601 } 602 603 } 604 605 public class FixWrapper implements java.io.Serializable { 609 public boolean isPrimitive; 610 public Class encapsulated; 611 612 public FixWrapper() { 613 } 614 615 618 public FixWrapper(Class c) { 619 if (!c.isPrimitive()) { 620 encapsulated = c; 621 return; 622 } 623 isPrimitive = true; 624 if (c.equals(Boolean.TYPE)) { 625 encapsulated = Boolean .class; 626 } else if (c.equals(Byte.TYPE)) { 627 encapsulated = Byte .class; 628 } else if (c.equals(Character.TYPE)) { 629 encapsulated = Character .class; 630 } else if (c.equals(Double.TYPE)) { 631 encapsulated = Double .class; 632 } else if (c.equals(Float.TYPE)) { 633 encapsulated = Float .class; 634 } else if (c.equals(Integer.TYPE)) { 635 encapsulated = Integer .class; 636 } else if (c.equals(Long.TYPE)) { 637 encapsulated = Long .class; 638 } else if (c.equals(Short.TYPE)) { 639 encapsulated = Short .class; 640 } 641 } 642 643 646 public Class getWrapped() { 647 if (!isPrimitive) { 648 return encapsulated; 649 } 650 if (encapsulated.equals(Boolean .class)) { 651 return Boolean.TYPE; 652 } 653 if (encapsulated.equals(Byte .class)) { 654 return Byte.TYPE; 655 } 656 if (encapsulated.equals(Character .class)) { 657 return Character.TYPE; 658 } 659 if (encapsulated.equals(Double .class)) { 660 return Double.TYPE; 661 } 662 if (encapsulated.equals(Float .class)) { 663 return Float.TYPE; 664 } 665 if (encapsulated.equals(Integer .class)) { 666 return Integer.TYPE; 667 } 668 if (encapsulated.equals(Long .class)) { 669 return Long.TYPE; 670 } 671 if (encapsulated.equals(Short .class)) { 672 return Short.TYPE; 673 } 674 throw new InternalException("FixWrapper encapsulated class unkown " + 675 encapsulated); 676 } 677 678 public String toString() { 679 return "FixWrapper: " + encapsulated.toString(); 680 } 681 } 682 683 } 685 | Popular Tags |