KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > proactive > core > mop > MOP


1 /*
2 * ################################################################
3 *
4 * ProActive: The Java(TM) library for Parallel, Distributed,
5 * Concurrent computing with Security and Mobility
6 *
7 * Copyright (C) 1997-2002 INRIA/University of Nice-Sophia Antipolis
8 * Contact: proactive-support@inria.fr
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
23 * USA
24 *
25 * Initial developer(s): The ProActive Team
26 * http://www.inria.fr/oasis/ProActive/contacts.html
27 * Contributor(s):
28 *
29 * ################################################################
30 */

31 package org.objectweb.proactive.core.mop;
32
33 import java.lang.reflect.Constructor JavaDoc;
34 import java.lang.reflect.InvocationTargetException JavaDoc;
35 import java.lang.reflect.Modifier JavaDoc;
36
37 import java.util.HashMap JavaDoc;
38
39 import org.apache.log4j.Logger;
40
41
42 /**
43  * A place where static methods go
44  */

45 public abstract class MOP {
46
47     /**
48      * The name of the interface that caracterizes all stub classes
49      */

50     protected static String JavaDoc STUB_OBJECT_INTERFACE_NAME = "org.objectweb.proactive.core.mop.StubObject";
51     protected static Class JavaDoc STUB_OBJECT_INTERFACE;
52     protected static Logger logger = Logger.getLogger(MOP.class.getName());
53
54     /**
55      * The root interface of all metabehaviors
56      */

57
58     //protected static String ROOT_INTERFACE_NAME = "org.objectweb.proactive.core.mop.Reflect";
59
//protected static Class ROOT_INTERFACE;
60

61     /**
62      * Class array representing no parameters
63      */

64     protected static final Class JavaDoc[] EMPTY_CLASS_ARRAY = new Class JavaDoc[0];
65
66     /**
67      * Empty object array
68      */

69     protected static final Object JavaDoc[] EMPTY_OBJECT_ARRAY = new Object JavaDoc[0];
70
71     /**
72      * Class array representing (Constructor Call, Object[])
73      */

74     protected static Class JavaDoc[] PROXY_CONSTRUCTOR_PARAMETERS_TYPES_ARRAY = new Class JavaDoc[2];
75
76     /**
77      * A Hashtable to cache (reified class, stub class constructor) couples.
78      */

79     protected static java.util.Hashtable JavaDoc stubTable = new java.util.Hashtable JavaDoc();
80
81     /**
82      * A Hashtable to cache (proxy class, proxy class constructor) couples
83      */

84     protected static java.util.Hashtable JavaDoc proxyTable = new java.util.Hashtable JavaDoc();
85
86     /**
87      * A Hashtable to cache (Class name, proxy class name) couples
88      * this is meant for class-based reification
89      */

90     protected static java.util.Hashtable JavaDoc secondProxyTable = new java.util.Hashtable JavaDoc();
91     ;
92     protected static MOPClassLoader singleton = MOPClassLoader.getMOPClassLoader();//MOPClassLoader.createMOPClassLoader();
93

94     /**
95      * As this class is center to the API, its static initializer is
96      * a good place to initialize general stuff.
97      */

98     protected static HashMap JavaDoc loadedClass = new HashMap JavaDoc();
99
100     static {
101         PROXY_CONSTRUCTOR_PARAMETERS_TYPES_ARRAY = new Class JavaDoc[] {
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 JavaDoc e) {
109             throw new CannotFindClassException(STUB_OBJECT_INTERFACE_NAME);
110         }
111
112         //try {
113
// ROOT_INTERFACE = forName(ROOT_INTERFACE_NAME);
114
//} catch (ClassNotFoundException e) {
115
// throw new CannotFindClassException(ROOT_INTERFACE_NAME);
116
//}
117
}
118
119     /**
120      * Loads a class using standard classloader or a hashtable
121      * @param s the name of the class to fetch
122      * @return the Class object representing class s
123      */

124     public static Class JavaDoc forName(String JavaDoc s)
125         throws java.lang.ClassNotFoundException JavaDoc {
126         try {
127             return Class.forName(s);
128         } catch (ClassNotFoundException JavaDoc e) {
129 // System.out.println(
130
// "MOP forName failed for class " + s + ", looking in table");
131
Class JavaDoc cl = (Class JavaDoc) loadedClass.get(s);
132 // System.out.println("MOP forName failed, result is " +
133
// cl);
134
if (cl == null) {
135                 throw e;
136             } else {
137                 return cl;
138             }
139         }
140     }
141
142     /**
143      * Creates an instance of an object
144      * @param nameOfClass The class to instanciate
145      * @param constructorParameters Array of the constructor's parameters [wrapper]
146      * @param nameOfProxy The name of its proxy class
147      * @param proxyParameters The array holding the proxy parameter
148      */

149     public static Object JavaDoc newInstance(String JavaDoc nameOfClass,
150         Object JavaDoc[] constructorParameters, String JavaDoc nameOfProxy,
151         Object JavaDoc[] proxyParameters)
152         throws ClassNotFoundException JavaDoc, 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 JavaDoc newInstance(Class JavaDoc clazz,
166         Object JavaDoc[] constructorParameters, String JavaDoc nameOfProxy,
167         Object JavaDoc[] proxyParameters)
168         throws ClassNotFoundException JavaDoc, 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     /**
181      * Creates an instance of an object
182      * @param nameOfStubClass The name of the Stub class corresponding to the object
183      * @param nameOfClass The class to instanciate
184      * @param constructorParameters Array of the constructor's parameters [wrapper]
185      * @param nameOfProxy The name of its proxy class
186      * @param proxyParameters The array holding the proxy parameter
187      */

188     public static Object JavaDoc newInstance(String JavaDoc nameOfStubClass,
189         String JavaDoc nameOfClass, Object JavaDoc[] constructorParameters, String JavaDoc nameOfProxy,
190         Object JavaDoc[] proxyParameters)
191         throws ClassNotFoundException JavaDoc, ClassNotReifiableException,
192             ReifiedCastException, InvalidProxyClassException,
193             ConstructionOfProxyObjectFailedException,
194             ConstructionOfReifiedObjectFailedException {
195         // For convenience, allows 'null' to be equivalent to an empty array
196
if (constructorParameters == null) {
197             constructorParameters = EMPTY_OBJECT_ARRAY;
198         }
199         if (proxyParameters == null) {
200             proxyParameters = EMPTY_OBJECT_ARRAY;
201         }
202
203         // Throws a ClassNotFoundException
204
Class JavaDoc targetClass = forName(nameOfClass);
205
206        // Class stubClass = null;
207
// try {
208
// targetClass = forName(nameOfStubClass);
209
// } catch (ClassNotFoundException e) {
210
// //if (targetClass.getClassLoader() != null) {
211
// // targetClass = targetClass.getClassLoader().loadClass(nameOfClass);
212
// //} else {
213
// // System.out.println("TargetClass " + targetClass + " has null classloader");
214
//
215
// // }
216
// MOP.forName(nameOfClass);// addClassToCache(nameOfStubClass, targetClass);
217
// }
218

219         // Instanciates the stub object
220
StubObject stub = createStubObject(nameOfStubClass, targetClass);
221
222         // build the constructor call for the target object to create
223
ConstructorCall reifiedCall = buildTargetObjectConstructorCall(targetClass,
224                 constructorParameters);
225
226         // Instanciates the proxy object
227
Proxy proxy = createProxyObject(nameOfProxy, proxyParameters,
228                 reifiedCall);
229
230         // Connects the proxy to the stub
231
stub.setProxy(proxy);
232         return stub;
233     }
234     
235     public static Object JavaDoc newInstance(Class JavaDoc stubClass,
236            String JavaDoc nameOfClass, Object JavaDoc[] constructorParameters, String JavaDoc nameOfProxy,
237            Object JavaDoc[] proxyParameters)
238            throws ClassNotFoundException JavaDoc, ClassNotReifiableException,
239                ReifiedCastException, InvalidProxyClassException,
240                ConstructionOfProxyObjectFailedException,
241                ConstructionOfReifiedObjectFailedException {
242            // For convenience, allows 'null' to be equivalent to an empty array
243
if (constructorParameters == null) {
244                constructorParameters = EMPTY_OBJECT_ARRAY;
245            }
246            if (proxyParameters == null) {
247                proxyParameters = EMPTY_OBJECT_ARRAY;
248            }
249
250            // Throws a ClassNotFoundException
251
Class JavaDoc targetClass = null; // forName(nameOfClass);
252

253          // Class stubClass = null;
254
try {
255                  targetClass = forName(nameOfClass);
256              } catch (ClassNotFoundException JavaDoc 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                 // MOP.forName(nameOfClass);// addClassToCache(nameOfStubClass, targetClass);
264
}
265
266            // Instanciates the stub object
267
StubObject stub = createStubObject(stubClass.getName(), targetClass);
268
269            // build the constructor call for the target object to create
270
ConstructorCall reifiedCall = buildTargetObjectConstructorCall(targetClass,
271                    constructorParameters);
272
273            // Instanciates the proxy object
274
Proxy proxy = createProxyObject(nameOfProxy, proxyParameters,
275                    reifiedCall);
276
277            // Connects the proxy to the stub
278
stub.setProxy(proxy);
279            return stub;
280        }
281     
282     
283
284     /**
285      * Creates an instance of an object
286      * @param nameOfClass The class to instanciate
287      * @param constructorParameters Array of the constructor's parameters [wrapper]
288      * @param proxyParameters The array holding the proxy parameter
289      *
290     public static Object newInstance(String nameOfClass, Object[] constructorParameters, Object[] proxyParameters)
291       throws
292         ClassNotFoundException,
293         ClassNotReifiableException,
294         CannotGuessProxyNameException,
295         InvalidProxyClassException,
296         ConstructionOfProxyObjectFailedException,
297         ConstructionOfReifiedObjectFailedException {
298       String nameOfProxy = guessProxyName(forName(nameOfClass));
299       return newInstance(nameOfClass, constructorParameters, nameOfProxy, proxyParameters);
300     }*/

301     /**
302      * Reifies an object
303      * @param proxyParameters Array holding the proxy parameters
304      * @param target the object to reify
305      *
306     public static Object turnReified(Object[] proxyParameters, Object target)
307       throws ClassNotReifiableException, CannotGuessProxyNameException, InvalidProxyClassException, ConstructionOfProxyObjectFailedException {
308
309       try {
310         return turnReified(guessProxyName(target.getClass()), proxyParameters, target);
311       } catch (ClassNotFoundException e) {
312         throw new CannotGuessProxyNameException();
313       }
314     }*/

315     /**
316      * Reifies an object
317      * @param nameOfProxyClass the name of the object's proxy
318      * @param proxyParameters Array holding the proxy parameters
319      * @param target the object to reify
320      */

321     public static Object JavaDoc turnReified(String JavaDoc nameOfProxyClass,
322         Object JavaDoc[] proxyParameters, Object JavaDoc target)
323         throws ClassNotFoundException JavaDoc, ClassNotReifiableException,
324             InvalidProxyClassException,
325             ConstructionOfProxyObjectFailedException {
326         try {
327             return turnReified(target.getClass().getName(), nameOfProxyClass,
328                 proxyParameters, target);
329             // return turnReifiedFAb(target.getClass(), nameOfProxyClass, proxyParameters, target);
330
} catch (ReifiedCastException e) {
331             throw new InternalException(e);
332         }
333     }
334
335     /**
336      * Reifies an object
337      * @param proxyParameters Array holding the proxy parameters
338      * @param nameOfStubClass The name of the object's stub class
339      * @param target the object to reify
340      *
341     public static Object turnReified(Object[] proxyParameters, String nameOfStubClass, Object target)
342       throws
343         ClassNotFoundException,
344         ReifiedCastException,
345         ClassNotReifiableException,
346         CannotGuessProxyNameException,
347         InvalidProxyClassException,
348         ConstructionOfProxyObjectFailedException {
349       String nameOfProxy = guessProxyName(target.getClass());
350       return turnReified(nameOfStubClass, nameOfProxy, proxyParameters, target);
351     }*/

352     /**
353      * Reifies an object
354      * @param nameOfProxyClass the name of the object's proxy
355      * @param nameOfStubClass The name of the object's stub class
356      * @param proxyParameters Array holding the proxy parameters
357      * @param target the object to reify
358      */

359     public static Object JavaDoc turnReified(String JavaDoc nameOfStubClass,
360         String JavaDoc nameOfProxyClass, Object JavaDoc[] proxyParameters, Object JavaDoc target)
361         throws ClassNotFoundException JavaDoc, ReifiedCastException,
362             ClassNotReifiableException, InvalidProxyClassException,
363             ConstructionOfProxyObjectFailedException {
364         // For convenience, allows 'null' to be equivalent to an empty array
365
// System.out.println("MOP.turnReified");
366
if (proxyParameters == null) {
367             proxyParameters = EMPTY_OBJECT_ARRAY;
368         }
369
370         // Throws a ClassNotFoundException
371
Class JavaDoc targetClass = target.getClass();
372
373         // Instanciates the stub object
374
StubObject stub = createStubObject(nameOfStubClass, targetClass);
375
376         // First, build the FakeConstructorCall object to pass to the constructor
377
// of the proxy Object
378
// FakeConstructorCall fakes a ConstructorCall object by returning
379
// an already-existing object as the result of its execution
380
ConstructorCall reifiedCall = new FakeConstructorCall(target);
381
382         // Instanciates the proxy object
383
Proxy proxy = createProxyObject(nameOfProxyClass, proxyParameters,
384                 reifiedCall);
385
386         // Connects the proxy to the stub
387
stub.setProxy(proxy);
388         return stub;
389     }
390
391     // public static Object turnReifiedFAb(Class targetClass, String nameOfProxyClass, Object[] proxyParameters, Object target)
392
// throws ClassNotFoundException, ReifiedCastException, ClassNotReifiableException, InvalidProxyClassException, ConstructionOfProxyObjectFailedException {
393
// For convenience, allows 'null' to be equivalent to an empty array
394
// System.out.println("MOP.turnReified");
395
// System.out.println("turnReifiedFAb");
396
// if (proxyParameters == null)
397
// proxyParameters = EMPTY_OBJECT_ARRAY;
398
// Throws a ClassNotFoundException
399
// Class targetClass = target.getClass();
400
// Instanciates the stub object
401
// StubObject stub = createStubObjectFAb(targetClass);
402
// First, build the FakeConstructorCall object to pass to the constructor
403
// of the proxy Object
404
// FakeConstructorCall fakes a ConstructorCall object by returning
405
// an already-existing object as the result of its execution
406
// ConstructorCall reifiedCall = new FakeConstructorCall(target);
407
// Instanciates the proxy object
408
// Proxy proxy = createProxyObject(nameOfProxyClass, proxyParameters, reifiedCall);
409
// Connects the proxy to the stub
410
// stub.setProxy(proxy);
411
// return stub;
412
// }
413

414     /**
415      * Checks if a stub class can be created for the class <code>cl</code>.
416      *
417      * A class cannot be reified if at least one of the following conditions are
418      * met : <UL>
419      * <LI>This <code>Class</code> objects represents a primitive type
420      * (except void)
421      * <LI>The class is <code>final</code>
422      * <LI>There is an ambiguity in constructors signatures
423      * <LI>There is no noargs constructor
424      * </UL>
425      *
426      * @author Julien Vayssi?re, INRIA
427      * @param cl Class to be checked
428      * @return <code>true</code> is the class exists and can be reified,
429      * <code>false</code> otherwise.
430      */

431     static void checkClassIsReifiable(String JavaDoc className)
432         throws ClassNotReifiableException, ClassNotFoundException JavaDoc {
433         checkClassIsReifiable(forName(className));
434     }
435
436     public static void checkClassIsReifiable(Class JavaDoc cl)
437         throws ClassNotReifiableException {
438         int mods = cl.getModifiers();
439         if (cl.isInterface()) {
440             // Interfaces are always reifiable, although some of the methods
441
// they contain may not be reifiable
442
return;
443         } else {
444             // normal case, this is a class
445
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     /**
461      * Checks if class <code>c</code> has a noargs constructor
462      */

463     protected static boolean checkNoArgsConstructor(Class JavaDoc cl) {
464         try {
465             cl.getConstructor(EMPTY_CLASS_ARRAY);
466             return true;
467         } catch (NoSuchMethodException JavaDoc e) {
468             return false;
469         }
470     }
471
472     /**
473      * Checks if an object is a stub object
474      *
475      * Being a stub object is equivalent to implementing the StubObject
476      * interface
477      *
478      * @param o the object to check
479      * @return <code>true</code> if it is a stub object, <code>false</code>
480      * otherwise */

481     public static boolean isReifiedObject(Object JavaDoc o) {
482         return (STUB_OBJECT_INTERFACE.isAssignableFrom(o.getClass()));
483     }
484
485     /**
486      * Creates a stub class for the specified class
487      * @param nameOfBaseClass The name of the class
488      * @return A class object representing the class, or NULL if failed
489      */

490     private static Class JavaDoc createStubClass(String JavaDoc nameOfBaseClass) {
491         try {
492             //return Class.forName(Utils.convertClassNameToStubClassName(nameOfClass), true, singleton);
493
return singleton.loadClass(Utils.convertClassNameToStubClassName(
494                     nameOfBaseClass));
495         } catch (ClassNotFoundException JavaDoc 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 JavaDoc createStubClass(String JavaDoc nameOfClass, ClassLoader JavaDoc cl) {
505         try {
506             //return Class.forName(Utils.convertClassNameToStubClassName(nameOfClass), true, singleton);
507
return singleton.loadClass(Utils.convertClassNameToStubClassName(
508                     nameOfClass), cl);
509         } catch (ClassNotFoundException JavaDoc e) {
510             throw new GenerationOfStubClassFailedException(
511                 "Cannot load Stub class : " +
512                 Utils.convertClassNameToStubClassName(nameOfClass));
513         }
514     }
515
516     /**
517      * Finds the Stub Constructor for a specified class
518      * @param nameOfClass the name of the class
519      * @return The Constructor object.
520      * @throws ClassNotFoundException if the class cannot be located
521      */

522     static Constructor JavaDoc findStubConstructor(String JavaDoc nameOfClass)
523         throws ClassNotFoundException JavaDoc {
524         return findStubConstructor(forName(nameOfClass));
525     }
526
527     /**
528      * Finds the Stub Constructor for a specified class
529      * @param targetClass the representation of the class
530      * @return The Constructor object.
531      */

532     private static Constructor JavaDoc findStubConstructor(Class JavaDoc targetClass) {
533         Constructor JavaDoc stubConstructor;
534         String JavaDoc nameOfClass = targetClass.getName();
535
536         // Is it cached in Hashtable ?
537
stubConstructor = (Constructor JavaDoc) stubTable.get(nameOfClass);
538
539         //System.out.println("xxxxxx targetClass is " + targetClass);
540
// On cache miss, finds the constructor
541
if (stubConstructor == null) {
542             Class JavaDoc stubClass;
543             try {
544                 stubClass = forName(Utils.convertClassNameToStubClassName(
545                             nameOfClass));
546             } catch (ClassNotFoundException JavaDoc e) {
547                 // No stub class can be found, let's create it from scratch
548
stubClass = createStubClass(nameOfClass, targetClass.getClassLoader());
549 // stubClass = createStubClass(nameOfClass,
550
// targetClass.getClassLoader());
551
}
552
553             // Verifies that the stub has a noargs constructor and caches it
554
try {
555                 stubConstructor = stubClass.getConstructor(EMPTY_CLASS_ARRAY);
556                 stubTable.put(nameOfClass, stubConstructor);
557             } catch (NoSuchMethodException JavaDoc 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     /**
567      * Finds the Constructor of the proxy for a specified class
568      * @param proxyClass The represenation of the proxy
569      * @return the Constructor
570      * @throws InvalidProxyClassException If the class is not a valid Proxy
571      */

572     private static Constructor JavaDoc findProxyConstructor(Class JavaDoc proxyClass)
573         throws InvalidProxyClassException {
574         Constructor JavaDoc proxyConstructor;
575
576         // Localizes the proxy class constructor
577
proxyConstructor = (Constructor JavaDoc) proxyTable.get(proxyClass.getName());
578
579         //System.out.println("MOP: The class of the proxy is " + proxyClass.getName());
580
// Cache miss
581
if (proxyConstructor == null) {
582             try {
583                 proxyConstructor = proxyClass.getConstructor(PROXY_CONSTRUCTOR_PARAMETERS_TYPES_ARRAY);
584                 proxyTable.put(proxyClass.getName(), proxyConstructor);
585             } catch (NoSuchMethodException JavaDoc 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 JavaDoc stubConstructor)
595         throws ConstructionOfStubObjectFailedException {
596         try {
597             Object JavaDoc o = stubConstructor.newInstance(EMPTY_OBJECT_ARRAY);
598             return (StubObject) o;
599         } catch (InstantiationException JavaDoc e) {
600             throw new ConstructionOfStubObjectFailedException("Constructor " +
601                 stubConstructor + " belongs to an abstract class.");
602         } catch (IllegalArgumentException JavaDoc e) {
603             throw new ConstructionOfStubObjectFailedException(
604                 "Wrapping problem with constructor " + stubConstructor);
605         } catch (IllegalAccessException JavaDoc e) {
606             throw new ConstructionOfStubObjectFailedException(
607                 "Access denied to constructor " + stubConstructor);
608         } catch (InvocationTargetException JavaDoc 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 JavaDoc nameOfBaseClass,
615         Class JavaDoc targetClass)
616         throws ClassNotFoundException JavaDoc, ReifiedCastException,
617             ClassNotReifiableException {
618         //System.out.println("StubClass is " + nameOfBaseClass);
619
// BUG ID: #327
620
//this has been added to deal with downloaded classes
621
//if we cannot load the stub class using its name
622
//it is probably because it has been downloaded by another classloader
623
//thus we ask the classloader of the target class to load it
624
Class JavaDoc baseClass = null;
625         try {
626             baseClass = forName(nameOfBaseClass);
627         } catch (ClassNotFoundException JavaDoc e) {
628             baseClass = targetClass.getClassLoader().loadClass(nameOfBaseClass);
629             MOP.addClassToCache(nameOfBaseClass, baseClass);
630         }
631
632         // Class stubClass = forName(nameOfStubClass,targetClass.getClassLoader());
633
// Check that the type of the class is compatible with the type of the stub
634
if (!(baseClass.isAssignableFrom(targetClass))) {
635             throw new ReifiedCastException("Cannot convert " +
636                 targetClass.getName() + "into " + baseClass.getName());
637         }
638
639         // Throws a ClassNotReifiableException exception if not reifiable
640
checkClassIsReifiable(baseClass);
641
642         // Finds the constructor of the stub class
643
// If the stub class has not yet been created,
644
// it is created within this call
645
Constructor JavaDoc stubConstructor = findStubConstructor(baseClass);
646
647         // Instanciates the stub object
648
return instantiateStubObject(stubConstructor);
649     }
650
651     // BUG ID: #327
652
protected static void addClassToCache(String JavaDoc name, Class JavaDoc cl) {
653         // System.out.println("MOP: puting " + nameOfStubClass +
654
// " in loadedClass");
655
// loadedClass.put(nameOfStubClass, stubClass);
656
// Field[] clArray = stubClass.getDeclaredFields();
657
// System.out.println("MOP: nuumber of declared classes " +
658
// clArray.length);
659
// for (int i = 0; i < clArray.length; i++) {
660
// Field ob1 = clArray[i];
661
// System.out.println("MOP: field " + ob1.getName());
662
// Class cl = ob1.getType();
663
// System.out.println("MOP: key = " + cl.getName() + " value = " +
664
// cl);
665
// loadedClass.put(cl.getName(), cl);
666
// }
667
loadedClass.put(name, cl);
668     }
669
670     // Instanciates the proxy object
671
private static Proxy createProxyObject(String JavaDoc nameOfProxy,
672         Object JavaDoc[] proxyParameters, ConstructorCall reifiedCall)
673         throws ConstructionOfProxyObjectFailedException, ClassNotFoundException JavaDoc,
674             InvalidProxyClassException {
675         // Throws a ClassNotFoundException
676
Class JavaDoc proxyClass = forName(nameOfProxy);
677
678         // Finds constructor of the proxy class
679
Constructor JavaDoc proxyConstructor = findProxyConstructor(proxyClass);
680
681         // Now calls the constructor of the proxy
682
Object JavaDoc[] params = new Object JavaDoc[] { reifiedCall, proxyParameters };
683         try {
684             return (Proxy) proxyConstructor.newInstance(params);
685         } catch (InstantiationException JavaDoc e) {
686             throw new ConstructionOfProxyObjectFailedException("Constructor " +
687                 proxyConstructor + " belongs to an abstract class");
688         } catch (IllegalArgumentException JavaDoc e) {
689             throw new ConstructionOfProxyObjectFailedException(
690                 "Wrapping problem with constructor " + proxyConstructor);
691         } catch (IllegalAccessException JavaDoc e) {
692             throw new ConstructionOfProxyObjectFailedException(
693                 "Access denied to constructor " + proxyConstructor);
694         } catch (InvocationTargetException JavaDoc 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 JavaDoc targetClass, Object JavaDoc[] constructorParameters)
702         throws ConstructionOfReifiedObjectFailedException {
703         // First, build the ConstructorCall object to pass to the constructor
704
// of the proxy Object. It represents the construction of the reified
705
// object.
706
Constructor JavaDoc targetConstructor;
707
708         // Locates the right constructor (should use a cache here ?)
709
Class JavaDoc[] targetConstructorArgs = new Class JavaDoc[constructorParameters.length];
710         for (int i = 0; i < constructorParameters.length; i++) {
711             // System.out.println("MOP: constructorParameters[i] = " + constructorParameters[i]);
712
targetConstructorArgs[i] = constructorParameters[i].getClass();
713             // System.out.println("MOP: targetConstructorArgs[i] = " + targetConstructorArgs[i]);
714
}
715
716         //System.out.println("MOP: targetClass is " + targetClass);
717
// System.out.println("MOP: targetConstructorArgs = " + targetConstructorArgs);
718
// System.out.println("MOP: targetConstructorArgs.length = " + targetConstructorArgs.length);
719
try {
720             //MODIFIED 4/5/00
721
if (targetClass.isInterface()) {
722                 //there is no point in looking for the constructor of an interface
723
// System.out.println("MOP: WARNING Interface detected");
724
targetConstructor = null;
725             } else {
726                 targetConstructor = targetClass.getDeclaredConstructor(targetConstructorArgs);
727             }
728         } catch (NoSuchMethodException JavaDoc e) {
729             // This may have failed because getConstructor does not allow subtypes
730
targetConstructor = findReifiedConstructor(targetClass,
731                     targetConstructorArgs);
732
733             if (targetConstructor == null)
734             // This may have failed because some wrappers should be interpreted
735
// as primitive types. Let's investigate it
736
{
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     /**
750      * Try to guess the name of the proxy for a specified class
751      * @param targetClass the source class
752      * @return the name of the proxy class
753      * @throws CannotGuessProxyNameException If the MOP cannot guess the name of the proxy
754      *
755     private static String guessProxyName(Class targetClass) throws CannotGuessProxyNameException {
756       int i;
757       Class cl;
758       Class myInterface = null;
759       Class[] interfaces;
760       Field myField = null;
761
762       // Checks the cache
763       String nameOfProxy = (String) secondProxyTable.get(targetClass.getName());
764       if (nameOfProxy == null) {
765         Class currentClass;
766         // Checks if this class or any of its superclasses implements an
767         // interface that is a subinterface of ROOT_INTERFACE
768         currentClass = targetClass;
769         //System.out.println("MOP: guessProxyName for targetClass " + targetClass);
770
771         while ((currentClass != null) && (myInterface == null)) {
772           boolean multipleMatches = false;
773           interfaces = currentClass.getInterfaces();
774           for (i = 0; i < interfaces.length; i++) {
775             if (ROOT_INTERFACE.isAssignableFrom(interfaces[i])) {
776               if (multipleMatches == false) {
777                 myInterface = interfaces[i];
778                 multipleMatches = true;
779               } else {
780                 // There are multiple interfaces in the current class
781                 // that inherit from ROOT_INTERFACE.
782                 System.err.println(
783                   "More than one interfaces declared in class " + currentClass.getName() + " inherit from " + ROOT_INTERFACE + ". Using " + myInterface);
784               }
785             }
786           }
787           currentClass = currentClass.getSuperclass();
788         }
789
790         if (myInterface == null) {
791           throw new CannotGuessProxyNameException(
792             "Class " + targetClass.getName() + " does not implement any interface that inherits from org.objectweb.proactive.core.mop.Reflect");
793         }
794
795         // Now look for the PROXY_CLASS_NAME field in this interface
796         try {
797           myField = myInterface.getField("PROXY_CLASS_NAME");
798         } catch (NoSuchFieldException e) {
799           throw new CannotGuessProxyNameException("No field PROXY_CLASS_NAME in interface " + myInterface);
800         }
801
802         try {
803           nameOfProxy = (String) myField.get(null);
804         } catch (IllegalAccessException e) {
805           throw new CannotGuessProxyNameException("Cannot access field PROXY_CLASS_NAME in interface " + myInterface);
806         }
807         secondProxyTable.put(targetClass.getName(), nameOfProxy);
808       }
809       return nameOfProxy;
810     }*/

811     /**
812      * Tries to solve ambiguity problems in constructors
813      * @param targetClass the class
814      * @param targetConstructorArgs The arguments which will determine wich constructor is to be used
815      * @return The corresponding Constructor
816      */

817     private static Constructor JavaDoc investigateAmbiguity(Class JavaDoc targetClass,
818         Class JavaDoc[] targetConstructorArgs) {
819         // Find the number of possible constructors ambiguities
820
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; // No wrapper found
828
}
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     /**
839      * Finds the reified constructor
840      * @param targetClass The class
841      * @param the effective arguments
842      * @return The constructor
843      */

844     private static Constructor JavaDoc findReifiedConstructor(Class JavaDoc targetClass,
845         Class JavaDoc[] targetConstructorArgs) {
846         Constructor JavaDoc[] publicConstructors;
847         Constructor JavaDoc currentConstructor;
848         Class JavaDoc[] currentConstructorParameterTypes;
849         boolean match;
850
851         publicConstructors = targetClass.getConstructors();
852         // For each public constructor of the reified class
853
for (int i = 0; i < publicConstructors.length; i++) {
854             currentConstructor = publicConstructors[i];
855             currentConstructorParameterTypes = currentConstructor.getParameterTypes();
856             match = true;
857
858             // Check if the parameters types of this constructor are
859
// assignable from the actual parameter types.
860
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     /**
880      * Dynamic cast
881      * @param sourceObject The source object
882      * @param targetTypeName the destination class
883      * @return The resulting object
884      * @throws ReifiedCastException if the class cast is invalid
885      */

886     private static Object JavaDoc castInto(Object JavaDoc sourceObject, String JavaDoc targetTypeName)
887         throws ReifiedCastException {
888         try {
889             Class JavaDoc cl = forName(targetTypeName);
890             return castInto(sourceObject, cl);
891         } catch (ClassNotFoundException JavaDoc e) {
892             throw new ReifiedCastException("Cannot load class " +
893                 targetTypeName);
894             // throw new ReifiedCastException ("Cannot cast "+sourceObject.getClass().getName()+" into "+targetTypeName);
895
}
896     }
897
898     /**
899      * Dynamic cast
900      * @param sourceObject The source object
901      * @param targetType the destination class
902      * @return The resulting object
903      * @throws ReifiedCastException if the class cast is invalid
904      */

905     private static Object JavaDoc castInto(Object JavaDoc sourceObject, Class JavaDoc targetType)
906         throws ReifiedCastException {
907         // First, check if sourceObject is a reified object
908
if (!(isReifiedObject(sourceObject))) {
909             throw new ReifiedCastException(
910                 "Cannot perform a reified cast on an object that is not reified");
911         }
912
913         // Gets a Class object representing the type of sourceObject
914
Class JavaDoc sourceType = sourceObject.getClass().getSuperclass();
915
916         // Check if types are compatible
917
// Here we assume that the 'type of the stub' (i.e, the type of the
918
// reified object) is its direct superclass
919
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         // Let's create a stub object for the target type
927
Constructor JavaDoc stubConstructor = findStubConstructor(targetType);
928
929         // Instanciates the stub object
930
StubObject stub = instantiateStubObject(stubConstructor);
931
932         // Connects the proxy of the old stub to the new stub
933
stub.setProxy(((StubObject) sourceObject).getProxy());
934         return stub;
935     }
936
937     public static Class JavaDoc loadClass(String JavaDoc name) throws ClassNotFoundException JavaDoc {
938         //return singleton.loadClass(name);
939
return forName(name);
940     }
941 }
942
Popular Tags