1 31 package org.objectweb.proactive.core.mop; 32 33 import java.lang.reflect.Constructor ; 34 import java.lang.reflect.InvocationTargetException ; 35 import java.lang.reflect.Modifier ; 36 37 import java.util.HashMap ; 38 39 import org.apache.log4j.Logger; 40 41 42 45 public abstract class MOP { 46 47 50 protected static String STUB_OBJECT_INTERFACE_NAME = "org.objectweb.proactive.core.mop.StubObject"; 51 protected static Class STUB_OBJECT_INTERFACE; 52 protected static Logger logger = Logger.getLogger(MOP.class.getName()); 53 54 57 58 61 64 protected static final Class [] EMPTY_CLASS_ARRAY = new Class [0]; 65 66 69 protected static final Object [] EMPTY_OBJECT_ARRAY = new Object [0]; 70 71 74 protected static Class [] PROXY_CONSTRUCTOR_PARAMETERS_TYPES_ARRAY = new Class [2]; 75 76 79 protected static java.util.Hashtable stubTable = new java.util.Hashtable (); 80 81 84 protected static java.util.Hashtable proxyTable = new java.util.Hashtable (); 85 86 90 protected static java.util.Hashtable secondProxyTable = new java.util.Hashtable (); 91 ; 92 protected static MOPClassLoader singleton = MOPClassLoader.getMOPClassLoader(); 94 98 protected static HashMap loadedClass = new HashMap (); 99 100 static { 101 PROXY_CONSTRUCTOR_PARAMETERS_TYPES_ARRAY = new Class [] { 102 org.objectweb.proactive.core.mop.ConstructorCall.class, 103 EMPTY_OBJECT_ARRAY.getClass() 104 }; 105 106 try { 107 STUB_OBJECT_INTERFACE = forName(STUB_OBJECT_INTERFACE_NAME); 108 } catch (ClassNotFoundException e) { 109 throw new CannotFindClassException(STUB_OBJECT_INTERFACE_NAME); 110 } 111 112 } 118 119 124 public static Class forName(String s) 125 throws java.lang.ClassNotFoundException { 126 try { 127 return Class.forName(s); 128 } catch (ClassNotFoundException e) { 129 Class cl = (Class ) loadedClass.get(s); 132 if (cl == null) { 135 throw e; 136 } else { 137 return cl; 138 } 139 } 140 } 141 142 149 public static Object newInstance(String nameOfClass, 150 Object [] constructorParameters, String nameOfProxy, 151 Object [] proxyParameters) 152 throws ClassNotFoundException , ClassNotReifiableException, 153 InvalidProxyClassException, 154 ConstructionOfProxyObjectFailedException, 155 ConstructionOfReifiedObjectFailedException { 156 try { 157 return newInstance(nameOfClass, nameOfClass, constructorParameters, 158 nameOfProxy, proxyParameters); 159 } catch (ReifiedCastException e) { 160 throw new InternalException(e); 161 } 162 } 163 164 165 public static Object newInstance(Class clazz, 166 Object [] constructorParameters, String nameOfProxy, 167 Object [] proxyParameters) 168 throws ClassNotFoundException , ClassNotReifiableException, 169 InvalidProxyClassException, 170 ConstructionOfProxyObjectFailedException, 171 ConstructionOfReifiedObjectFailedException { 172 try { 173 return newInstance(clazz, clazz.getName(), constructorParameters, 174 nameOfProxy, proxyParameters); 175 } catch (ReifiedCastException e) { 176 throw new InternalException(e); 177 } 178 } 179 180 188 public static Object newInstance(String nameOfStubClass, 189 String nameOfClass, Object [] constructorParameters, String nameOfProxy, 190 Object [] proxyParameters) 191 throws ClassNotFoundException , ClassNotReifiableException, 192 ReifiedCastException, InvalidProxyClassException, 193 ConstructionOfProxyObjectFailedException, 194 ConstructionOfReifiedObjectFailedException { 195 if (constructorParameters == null) { 197 constructorParameters = EMPTY_OBJECT_ARRAY; 198 } 199 if (proxyParameters == null) { 200 proxyParameters = EMPTY_OBJECT_ARRAY; 201 } 202 203 Class targetClass = forName(nameOfClass); 205 206 219 StubObject stub = createStubObject(nameOfStubClass, targetClass); 221 222 ConstructorCall reifiedCall = buildTargetObjectConstructorCall(targetClass, 224 constructorParameters); 225 226 Proxy proxy = createProxyObject(nameOfProxy, proxyParameters, 228 reifiedCall); 229 230 stub.setProxy(proxy); 232 return stub; 233 } 234 235 public static Object newInstance(Class stubClass, 236 String nameOfClass, Object [] constructorParameters, String nameOfProxy, 237 Object [] proxyParameters) 238 throws ClassNotFoundException , ClassNotReifiableException, 239 ReifiedCastException, InvalidProxyClassException, 240 ConstructionOfProxyObjectFailedException, 241 ConstructionOfReifiedObjectFailedException { 242 if (constructorParameters == null) { 244 constructorParameters = EMPTY_OBJECT_ARRAY; 245 } 246 if (proxyParameters == null) { 247 proxyParameters = EMPTY_OBJECT_ARRAY; 248 } 249 250 Class targetClass = null; 253 try { 255 targetClass = forName(nameOfClass); 256 } catch (ClassNotFoundException e) { 257 if (stubClass.getClassLoader() != null) { 258 targetClass = stubClass.getClassLoader().loadClass(nameOfClass); 259 } else { 260 logger.info("TargetClass " + targetClass + " has null classloader"); 261 262 } 263 } 265 266 StubObject stub = createStubObject(stubClass.getName(), targetClass); 268 269 ConstructorCall reifiedCall = buildTargetObjectConstructorCall(targetClass, 271 constructorParameters); 272 273 Proxy proxy = createProxyObject(nameOfProxy, proxyParameters, 275 reifiedCall); 276 277 stub.setProxy(proxy); 279 return stub; 280 } 281 282 283 284 301 315 321 public static Object turnReified(String nameOfProxyClass, 322 Object [] proxyParameters, Object target) 323 throws ClassNotFoundException , ClassNotReifiableException, 324 InvalidProxyClassException, 325 ConstructionOfProxyObjectFailedException { 326 try { 327 return turnReified(target.getClass().getName(), nameOfProxyClass, 328 proxyParameters, target); 329 } catch (ReifiedCastException e) { 331 throw new InternalException(e); 332 } 333 } 334 335 352 359 public static Object turnReified(String nameOfStubClass, 360 String nameOfProxyClass, Object [] proxyParameters, Object target) 361 throws ClassNotFoundException , ReifiedCastException, 362 ClassNotReifiableException, InvalidProxyClassException, 363 ConstructionOfProxyObjectFailedException { 364 if (proxyParameters == null) { 367 proxyParameters = EMPTY_OBJECT_ARRAY; 368 } 369 370 Class targetClass = target.getClass(); 372 373 StubObject stub = createStubObject(nameOfStubClass, targetClass); 375 376 ConstructorCall reifiedCall = new FakeConstructorCall(target); 381 382 Proxy proxy = createProxyObject(nameOfProxyClass, proxyParameters, 384 reifiedCall); 385 386 stub.setProxy(proxy); 388 return stub; 389 } 390 391 414 431 static void checkClassIsReifiable(String className) 432 throws ClassNotReifiableException, ClassNotFoundException { 433 checkClassIsReifiable(forName(className)); 434 } 435 436 public static void checkClassIsReifiable(Class cl) 437 throws ClassNotReifiableException { 438 int mods = cl.getModifiers(); 439 if (cl.isInterface()) { 440 return; 443 } else { 444 if (cl.isPrimitive()) { 446 throw new ClassNotReifiableException( 447 "Cannot reify primitive types: " + cl.getName()); 448 } else if (Modifier.isFinal(mods)) { 449 throw new ClassNotReifiableException( 450 "Cannot reify final classes: " + cl.getName()); 451 } else if (!(checkNoArgsConstructor(cl))) { 452 throw new ClassNotReifiableException("Class " + cl.getName() + 453 " needs to have an empty noarg constructor."); 454 } else { 455 return; 456 } 457 } 458 } 459 460 463 protected static boolean checkNoArgsConstructor(Class cl) { 464 try { 465 cl.getConstructor(EMPTY_CLASS_ARRAY); 466 return true; 467 } catch (NoSuchMethodException e) { 468 return false; 469 } 470 } 471 472 481 public static boolean isReifiedObject(Object o) { 482 return (STUB_OBJECT_INTERFACE.isAssignableFrom(o.getClass())); 483 } 484 485 490 private static Class createStubClass(String nameOfBaseClass) { 491 try { 492 return singleton.loadClass(Utils.convertClassNameToStubClassName( 494 nameOfBaseClass)); 495 } catch (ClassNotFoundException e) { 496 throw new GenerationOfStubClassFailedException( 497 "Cannot create the Stub class : " + 498 Utils.convertClassNameToStubClassName(nameOfBaseClass) + 499 "\nThe class \"" + nameOfBaseClass + 500 "\" must have a public access "); 501 } 502 } 503 504 private static Class createStubClass(String nameOfClass, ClassLoader cl) { 505 try { 506 return singleton.loadClass(Utils.convertClassNameToStubClassName( 508 nameOfClass), cl); 509 } catch (ClassNotFoundException e) { 510 throw new GenerationOfStubClassFailedException( 511 "Cannot load Stub class : " + 512 Utils.convertClassNameToStubClassName(nameOfClass)); 513 } 514 } 515 516 522 static Constructor findStubConstructor(String nameOfClass) 523 throws ClassNotFoundException { 524 return findStubConstructor(forName(nameOfClass)); 525 } 526 527 532 private static Constructor findStubConstructor(Class targetClass) { 533 Constructor stubConstructor; 534 String nameOfClass = targetClass.getName(); 535 536 stubConstructor = (Constructor ) stubTable.get(nameOfClass); 538 539 if (stubConstructor == null) { 542 Class stubClass; 543 try { 544 stubClass = forName(Utils.convertClassNameToStubClassName( 545 nameOfClass)); 546 } catch (ClassNotFoundException e) { 547 stubClass = createStubClass(nameOfClass, targetClass.getClassLoader()); 549 } 552 553 try { 555 stubConstructor = stubClass.getConstructor(EMPTY_CLASS_ARRAY); 556 stubTable.put(nameOfClass, stubConstructor); 557 } catch (NoSuchMethodException e) { 558 throw new GenerationOfStubClassFailedException( 559 "Stub for class " + nameOfClass + 560 "has no noargs constructor. This is a bug in ProActive."); 561 } 562 } 563 return stubConstructor; 564 } 565 566 572 private static Constructor findProxyConstructor(Class proxyClass) 573 throws InvalidProxyClassException { 574 Constructor proxyConstructor; 575 576 proxyConstructor = (Constructor ) proxyTable.get(proxyClass.getName()); 578 579 if (proxyConstructor == null) { 582 try { 583 proxyConstructor = proxyClass.getConstructor(PROXY_CONSTRUCTOR_PARAMETERS_TYPES_ARRAY); 584 proxyTable.put(proxyClass.getName(), proxyConstructor); 585 } catch (NoSuchMethodException e) { 586 throw new InvalidProxyClassException( 587 "No constructor matching (ConstructorCall, Object[]) found in proxy class " + 588 proxyClass.getName()); 589 } 590 } 591 return proxyConstructor; 592 } 593 594 private static StubObject instantiateStubObject(Constructor stubConstructor) 595 throws ConstructionOfStubObjectFailedException { 596 try { 597 Object o = stubConstructor.newInstance(EMPTY_OBJECT_ARRAY); 598 return (StubObject) o; 599 } catch (InstantiationException e) { 600 throw new ConstructionOfStubObjectFailedException("Constructor " + 601 stubConstructor + " belongs to an abstract class."); 602 } catch (IllegalArgumentException e) { 603 throw new ConstructionOfStubObjectFailedException( 604 "Wrapping problem with constructor " + stubConstructor); 605 } catch (IllegalAccessException e) { 606 throw new ConstructionOfStubObjectFailedException( 607 "Access denied to constructor " + stubConstructor); 608 } catch (InvocationTargetException e) { 609 throw new ConstructionOfStubObjectFailedException("The constructor of the stub has thrown an exception: ", 610 e.getTargetException()); 611 } 612 } 613 614 private static StubObject createStubObject(String nameOfBaseClass, 615 Class targetClass) 616 throws ClassNotFoundException , ReifiedCastException, 617 ClassNotReifiableException { 618 Class baseClass = null; 625 try { 626 baseClass = forName(nameOfBaseClass); 627 } catch (ClassNotFoundException e) { 628 baseClass = targetClass.getClassLoader().loadClass(nameOfBaseClass); 629 MOP.addClassToCache(nameOfBaseClass, baseClass); 630 } 631 632 if (!(baseClass.isAssignableFrom(targetClass))) { 635 throw new ReifiedCastException("Cannot convert " + 636 targetClass.getName() + "into " + baseClass.getName()); 637 } 638 639 checkClassIsReifiable(baseClass); 641 642 Constructor stubConstructor = findStubConstructor(baseClass); 646 647 return instantiateStubObject(stubConstructor); 649 } 650 651 protected static void addClassToCache(String name, Class cl) { 653 loadedClass.put(name, cl); 668 } 669 670 private static Proxy createProxyObject(String nameOfProxy, 672 Object [] proxyParameters, ConstructorCall reifiedCall) 673 throws ConstructionOfProxyObjectFailedException, ClassNotFoundException , 674 InvalidProxyClassException { 675 Class proxyClass = forName(nameOfProxy); 677 678 Constructor proxyConstructor = findProxyConstructor(proxyClass); 680 681 Object [] params = new Object [] { reifiedCall, proxyParameters }; 683 try { 684 return (Proxy) proxyConstructor.newInstance(params); 685 } catch (InstantiationException e) { 686 throw new ConstructionOfProxyObjectFailedException("Constructor " + 687 proxyConstructor + " belongs to an abstract class"); 688 } catch (IllegalArgumentException e) { 689 throw new ConstructionOfProxyObjectFailedException( 690 "Wrapping problem with constructor " + proxyConstructor); 691 } catch (IllegalAccessException e) { 692 throw new ConstructionOfProxyObjectFailedException( 693 "Access denied to constructor " + proxyConstructor); 694 } catch (InvocationTargetException e) { 695 throw new ConstructionOfProxyObjectFailedException("The constructor of the proxy object has thrown an exception: ", 696 e.getTargetException()); 697 } 698 } 699 700 private static ConstructorCall buildTargetObjectConstructorCall( 701 Class targetClass, Object [] constructorParameters) 702 throws ConstructionOfReifiedObjectFailedException { 703 Constructor targetConstructor; 707 708 Class [] targetConstructorArgs = new Class [constructorParameters.length]; 710 for (int i = 0; i < constructorParameters.length; i++) { 711 targetConstructorArgs[i] = constructorParameters[i].getClass(); 713 } 715 716 try { 720 if (targetClass.isInterface()) { 722 targetConstructor = null; 725 } else { 726 targetConstructor = targetClass.getDeclaredConstructor(targetConstructorArgs); 727 } 728 } catch (NoSuchMethodException e) { 729 targetConstructor = findReifiedConstructor(targetClass, 731 targetConstructorArgs); 732 733 if (targetConstructor == null) 734 { 737 targetConstructor = investigateAmbiguity(targetClass, 738 targetConstructorArgs); 739 if (targetConstructor == null) { 740 throw new ConstructionOfReifiedObjectFailedException( 741 "Cannot locate this constructor in class " + 742 targetClass + " : " + targetConstructorArgs); 743 } 744 } 745 } 746 return new ConstructorCallImpl(targetConstructor, constructorParameters); 747 } 748 749 811 817 private static Constructor investigateAmbiguity(Class targetClass, 818 Class [] targetConstructorArgs) { 819 int n = 1; 821 for (int i = 0; i < targetConstructorArgs.length; i++) { 822 if (Utils.isWrapperClass(targetConstructorArgs[i])) { 823 n = n * 2; 824 } 825 } 826 if (n == 1) { 827 return null; } 829 830 for (int i = 0; i < targetConstructorArgs.length; i++) { 831 if (Utils.isWrapperClass(targetConstructorArgs[i])) { 832 targetConstructorArgs[i] = Utils.getPrimitiveType(targetConstructorArgs[i]); 833 } 834 } 835 return findReifiedConstructor(targetClass, targetConstructorArgs); 836 } 837 838 844 private static Constructor findReifiedConstructor(Class targetClass, 845 Class [] targetConstructorArgs) { 846 Constructor [] publicConstructors; 847 Constructor currentConstructor; 848 Class [] currentConstructorParameterTypes; 849 boolean match; 850 851 publicConstructors = targetClass.getConstructors(); 852 for (int i = 0; i < publicConstructors.length; i++) { 854 currentConstructor = publicConstructors[i]; 855 currentConstructorParameterTypes = currentConstructor.getParameterTypes(); 856 match = true; 857 858 if (currentConstructorParameterTypes.length == targetConstructorArgs.length) { 861 for (int j = 0; j < currentConstructorParameterTypes.length; 862 j++) { 863 if (!(currentConstructorParameterTypes[j].isAssignableFrom( 864 targetConstructorArgs[j]))) { 865 match = false; 866 break; 867 } 868 } 869 } else { 870 match = false; 871 } 872 if (match == true) { 873 return currentConstructor; 874 } 875 } 876 return null; 877 } 878 879 886 private static Object castInto(Object sourceObject, String targetTypeName) 887 throws ReifiedCastException { 888 try { 889 Class cl = forName(targetTypeName); 890 return castInto(sourceObject, cl); 891 } catch (ClassNotFoundException e) { 892 throw new ReifiedCastException("Cannot load class " + 893 targetTypeName); 894 } 896 } 897 898 905 private static Object castInto(Object sourceObject, Class targetType) 906 throws ReifiedCastException { 907 if (!(isReifiedObject(sourceObject))) { 909 throw new ReifiedCastException( 910 "Cannot perform a reified cast on an object that is not reified"); 911 } 912 913 Class sourceType = sourceObject.getClass().getSuperclass(); 915 916 if (!((sourceType.isAssignableFrom(targetType)) || 920 (targetType.isAssignableFrom(sourceType)))) { 921 throw new ReifiedCastException("Cannot cast " + 922 sourceObject.getClass().getName() + " into " + 923 targetType.getName()); 924 } 925 926 Constructor stubConstructor = findStubConstructor(targetType); 928 929 StubObject stub = instantiateStubObject(stubConstructor); 931 932 stub.setProxy(((StubObject) sourceObject).getProxy()); 934 return stub; 935 } 936 937 public static Class loadClass(String name) throws ClassNotFoundException { 938 return forName(name); 940 } 941 } 942 | Popular Tags |