KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > oracle > toplink > essentials > internal > descriptors > InstantiationPolicy


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the "License"). You may not use this file except
5  * in compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * glassfish/bootstrap/legal/CDDLv1.0.txt or
9  * https://glassfish.dev.java.net/public/CDDLv1.0.html.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * HEADER in each file and include the License file at
15  * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
16  * add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your
18  * own identifying information: Portions Copyright [yyyy]
19  * [name of copyright owner]
20  */

21 // Copyright (c) 1998, 2006, Oracle. All rights reserved.
22
package oracle.toplink.essentials.internal.descriptors;
23
24 import java.io.*;
25 import java.lang.reflect.*;
26 import java.security.AccessController JavaDoc;
27 import java.security.PrivilegedActionException JavaDoc;
28
29 import oracle.toplink.essentials.exceptions.*;
30 import oracle.toplink.essentials.internal.helper.*;
31 import oracle.toplink.essentials.internal.security.*;
32 import oracle.toplink.essentials.internal.sessions.AbstractSession;
33 import oracle.toplink.essentials.descriptors.ClassDescriptor;
34
35 /**
36  * <b>Purpose</b>: Allows customization of how an object is created/instantiated.<p>
37  *
38  * So, here is how it works:<p>
39  *
40  * If there is no method specified<br>
41  * - all the other settings are ignored and<br>
42  * - the descriptor class's default constructor is invoked.<br>
43  * If a factory is specified<br>
44  * - the factoryClass and factoryClassMethod are ignored and<br>
45  * - the method is invoked on the factory.<br>
46  * If neither a factory nor a factoryClass are specified<br>
47  * - the factoryClassMethod is ignored and<br>
48  * - the method is invoked on the descriptor class (as a static).<br>
49  * If only the factoryClass is specified<br>
50  * - the factory is created by invoking the factoryClass' default (zero-argument) constructor and<br>
51  * - the method is invoked on the resulting factory.<br>
52  * If both the factoryClass and the factoryClassMethod are specified<br>
53  * - the factory is created by invoking the factoryClassMethod on the factoryClass (as a static) and<br>
54  * - the method is invoked on the resulting factory.<p>
55  *
56  * The only thing we can't support in the current configuration is invoking a static on some,
57  * client-specified, factoryClass to build new instances of the descriptor class; and it's debatable
58  * whether that is desirable...<p>
59  *
60  * It might be reasonable to rework this into a number of different classes that implement
61  * an interface...
62  */

63 public class InstantiationPolicy implements Cloneable JavaDoc, Serializable {
64
65     /**
66      * The method invoked on either the descriptor class (in which case it is static) or
67      * the factory (in which case it is not static) to build a new instance of the descriptor class.
68      */

69     protected String JavaDoc methodName;
70
71     /** The method is resolved during initialization, and it is not serialized. */
72     protected transient Method method;
73
74     /**
75      * The class of the factory. The factory is instantiated by either invoking this class's default
76      * (zero-argument) constructor or the factoryMethod specified below.
77      */

78     protected Class JavaDoc factoryClass;
79     protected String JavaDoc factoryClassName;
80
81     /**
82      * Static method invoked on the factoryClass to get the factory instance. If this is null, the
83      * factory class's default (zero-argument) constructor is invoked.
84      */

85     protected String JavaDoc factoryMethodName;
86
87     /**
88      * The object factory. This can be specified directly by the client, or it can be built dynamically
89      * using the the factoryClass and, optionally, the factoryMethodName.
90      */

91     protected Object JavaDoc factory;
92
93     /** Backpointer to descriptor. */
94     protected ClassDescriptor descriptor;
95
96     /** Must be transient because java.lang.Constructor is not serializable. */
97     private transient Constructor defaultConstructor;
98
99     /**
100      * Default constructor
101      */

102     public InstantiationPolicy() {
103         super();
104     }
105
106     /**
107      * Build and return a new instance, using the appropriate mechanism.
108      */

109     public Object JavaDoc buildNewInstance() throws DescriptorException {
110         if (this.isUsingDefaultConstructor()) {
111             return this.buildNewInstanceUsingDefaultConstructor();
112         } else {
113             return this.buildNewInstanceUsingFactory();
114         }
115     }
116
117     /**
118      * Build and return a new instance, using the default (zero-argument) constructor.
119      */

120     protected Object JavaDoc buildNewInstanceUsingDefaultConstructor() throws DescriptorException {
121         try {
122             if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
123                 try {
124                     return AccessController.doPrivileged(new PrivilegedInvokeConstructor(this.getDefaultConstructor(), (Object JavaDoc[])null));
125                 } catch (PrivilegedActionException JavaDoc exception) {
126                     Exception JavaDoc throwableException = exception.getException();
127                     if (throwableException instanceof InvocationTargetException){
128                         throw DescriptorException.targetInvocationWhileConstructorInstantiationOfFactory(this.getDescriptor(), throwableException);
129                     } else if (throwableException instanceof IllegalAccessException JavaDoc){
130                         throw DescriptorException.illegalAccessWhileConstructorInstantiationOfFactory(this.getDescriptor(), throwableException);
131                     } else {
132                         throw DescriptorException.instantiationWhileConstructorInstantiationOfFactory(this.getDescriptor(), throwableException);
133                     }
134                  }
135             } else {
136                 return PrivilegedAccessHelper.invokeConstructor(this.getDefaultConstructor(), (Object JavaDoc[])null);
137             }
138         } catch (InvocationTargetException exception) {
139             throw DescriptorException.targetInvocationWhileConstructorInstantiation(this.getDescriptor(), exception);
140         } catch (IllegalAccessException JavaDoc exception) {
141             throw DescriptorException.illegalAccessWhileConstructorInstantiation(this.getDescriptor(), exception);
142         } catch (InstantiationException JavaDoc exception) {
143             throw DescriptorException.instantiationWhileConstructorInstantiation(this.getDescriptor(), exception);
144         } catch (NoSuchMethodError JavaDoc exception) {
145             // This exception is not documented but gets thrown.
146
throw DescriptorException.noSuchMethodWhileConstructorInstantiation(this.getDescriptor(), exception);
147         } catch (NullPointerException JavaDoc exception) {
148             // Some JVMs will throw a NULL pointer exception here
149
throw DescriptorException.nullPointerWhileConstructorInstantiation(this.getDescriptor(), exception);
150         }
151     }
152
153     /**
154      * Build and return a new instance, using the factory.
155      * The factory can be null, in which case the method is a static method defined by the descriptor class.
156      */

157     protected Object JavaDoc buildNewInstanceUsingFactory() throws DescriptorException {
158         try {
159             // If the method is static, the first argument is ignored and can be null
160
if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
161                 try {
162                     return AccessController.doPrivileged(new PrivilegedMethodInvoker(this.getMethod(), this.getFactory(), new Object JavaDoc[0]));
163                 } catch (PrivilegedActionException JavaDoc exception) {
164                     Exception JavaDoc throwableException = exception.getException();
165                     if (throwableException instanceof IllegalAccessException JavaDoc) {
166                         throw DescriptorException.illegalAccessWhileMethodInstantiation(this.getMethod().toString(), this.getDescriptor(), throwableException);
167                     } else {
168                         throw DescriptorException.targetInvocationWhileMethodInstantiation(this.getMethod().toString(), this.getDescriptor(), throwableException);
169                     }
170                 }
171             } else {
172                 return PrivilegedAccessHelper.invokeMethod(this.getMethod(), this.getFactory(), new Object JavaDoc[0]);
173             }
174         } catch (IllegalAccessException JavaDoc exception) {
175             throw DescriptorException.illegalAccessWhileMethodInstantiation(this.getMethod().toString(), this.getDescriptor(), exception);
176         } catch (InvocationTargetException exception) {
177             throw DescriptorException.targetInvocationWhileMethodInstantiation(this.getMethod().toString(), this.getDescriptor(), exception);
178         } catch (NullPointerException JavaDoc exception) {
179             // Some JVMs will throw a NULL pointer exception here
180
throw DescriptorException.nullPointerWhileMethodInstantiation(this.getMethod().toString(), this.getDescriptor(), exception);
181         }
182     }
183
184     /**
185      * INTERNAL:
186      * Clones the InstantiationPolicy
187      */

188     public Object JavaDoc clone() {
189         try {
190             // clones itself
191
return super.clone();
192         } catch (Exception JavaDoc exception) {
193             ;
194         }
195         return null;
196     }
197
198     /**
199      * Return the default (zero-argument) constructor for the descriptor class.
200      */

201     protected Constructor getDefaultConstructor() throws DescriptorException {
202         // Lazy initialize, because the constructor cannot be serialized
203
if (defaultConstructor == null) {
204             this.setDefaultConstructor(this.buildDefaultConstructor());
205         }
206         return defaultConstructor;
207     }
208
209     /**
210      * Build and return the default (zero-argument) constructor for the descriptor class.
211      */

212     protected Constructor buildDefaultConstructor() throws DescriptorException {
213         return this.buildDefaultConstructorFor(this.getDescriptor().getJavaClass());
214     }
215
216     /**
217      * Build and return the default (zero-argument) constructor for the specified class.
218      */

219     protected Constructor buildDefaultConstructorFor(Class JavaDoc javaClass) throws DescriptorException {
220         try {
221             if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
222                 try {
223                     return (Constructor)AccessController.doPrivileged(new PrivilegedGetDeclaredConstructorFor(javaClass, new Class JavaDoc[0], true));
224                 } catch (PrivilegedActionException JavaDoc exception) {
225                     throw DescriptorException.noSuchMethodWhileInitializingInstantiationPolicy(javaClass.getName() + ".<Default Constructor>", getDescriptor(), exception.getException());
226                 }
227             } else {
228                 return PrivilegedAccessHelper.getDeclaredConstructorFor(javaClass, new Class JavaDoc[0], true);
229             }
230         } catch (NoSuchMethodException JavaDoc exception) {
231             throw DescriptorException.noSuchMethodWhileInitializingInstantiationPolicy(javaClass.getName() + ".<Default Constructor>", getDescriptor(), exception);
232         }
233     }
234
235     protected ClassDescriptor getDescriptor() {
236         return descriptor;
237     }
238
239     public String JavaDoc getFactoryMethodName() {
240         return factoryMethodName;
241     }
242
243     public Object JavaDoc getFactory() {
244         return factory;
245     }
246
247     public Class JavaDoc getFactoryClass() {
248         return factoryClass;
249     }
250
251     public String JavaDoc getFactoryClassName() {
252         if ((factoryClassName == null) && (factoryClass != null)) {
253             factoryClassName = factoryClass.getName();
254         }
255         return factoryClassName;
256     }
257
258     protected Method getMethod() {
259         return method;
260     }
261
262     public String JavaDoc getMethodName() {
263         return methodName;
264     }
265
266     /**
267      * If necessary, initialize the factory and the method.
268      */

269     public void initialize(AbstractSession session) throws DescriptorException {
270         if (this.isUsingDefaultConstructor()) {
271             return;
272         }
273         try {
274             // If the factory has been specified directly, do not overwrite it
275
if (this.getFactory() == null) {
276                 this.setFactory(this.buildFactory());
277             }
278             this.initializeMethod();
279         } catch (DescriptorException ex) {
280             session.getIntegrityChecker().handleError(ex);
281         }
282     }
283
284     protected Object JavaDoc buildFactory() throws DescriptorException {
285         // If there is no factory class specified, there is no factory;
286
// we will be using a static method defined by the descriptor class...
287
if (this.getFactoryClass() == null) {
288             return null;
289         }
290
291         // If there is a factory class specified but no factory method name,
292
// instantiate the factory using the default constructor
293
if (this.getFactoryMethodName() == null) {
294             return this.buildFactoryUsingDefaultConstructor();
295         }
296
297         // If both the factory class and the factory method name have been specified,
298
// instantiate the factory by invoking the static factory method
299
return this.buildFactoryUsingStaticMethod();
300     }
301
302     /**
303      * Build and return the factory, using its default constructor.
304      */

305     protected Object JavaDoc buildFactoryUsingDefaultConstructor() throws DescriptorException {
306         try {
307             if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
308                 try {
309                     return AccessController.doPrivileged(new PrivilegedInvokeConstructor(this.buildFactoryDefaultConstructor(), (Object JavaDoc[])null));
310                 } catch (PrivilegedActionException JavaDoc exception) {
311                     Exception JavaDoc throwableException = exception.getException();
312                     if (throwableException instanceof InvocationTargetException){
313                         throw DescriptorException.targetInvocationWhileConstructorInstantiationOfFactory(this.getDescriptor(), throwableException);
314                     } else if (throwableException instanceof IllegalAccessException JavaDoc){
315                         throw DescriptorException.illegalAccessWhileConstructorInstantiationOfFactory(this.getDescriptor(), throwableException);
316                     } else {
317                         throw DescriptorException.instantiationWhileConstructorInstantiationOfFactory(this.getDescriptor(), throwableException);
318                     }
319                  }
320             } else {
321                 return PrivilegedAccessHelper.invokeConstructor(this.buildFactoryDefaultConstructor(), (Object JavaDoc[])null);
322             }
323         } catch (InvocationTargetException exception) {
324             throw DescriptorException.targetInvocationWhileConstructorInstantiationOfFactory(this.getDescriptor(), exception);
325         } catch (IllegalAccessException JavaDoc exception) {
326             throw DescriptorException.illegalAccessWhileConstructorInstantiationOfFactory(this.getDescriptor(), exception);
327         } catch (InstantiationException JavaDoc exception) {
328             throw DescriptorException.instantiationWhileConstructorInstantiationOfFactory(this.getDescriptor(), exception);
329         } catch (NoSuchMethodError JavaDoc exception) {
330             // This exception is not documented but gets thrown.
331
throw DescriptorException.noSuchMethodWhileConstructorInstantiationOfFactory(this.getDescriptor(), exception);
332         } catch (NullPointerException JavaDoc exception) {
333             // Some JVMs will throw a NULL pointer exception here
334
throw DescriptorException.nullPointerWhileConstructorInstantiationOfFactory(this.getDescriptor(), exception);
335         }
336     }
337
338     /**
339      * Build and return the default (zero-argument) constructor for the factory class.
340      */

341     protected Constructor buildFactoryDefaultConstructor() throws DescriptorException {
342         return this.buildDefaultConstructorFor(this.getFactoryClass());
343     }
344
345     /**
346      * Build and return the factory, using the specified static method.
347      */

348     protected Object JavaDoc buildFactoryUsingStaticMethod() throws DescriptorException {
349         Method factoryMethod = this.buildMethod(this.getFactoryClass(), this.getFactoryMethodName(), new Class JavaDoc[0]);
350
351         try {
352             // it should be static and zero-argument...
353
if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
354                 try {
355                     return AccessController.doPrivileged(new PrivilegedMethodInvoker(factoryMethod, null, null));
356                 } catch (PrivilegedActionException JavaDoc exception) {
357                     Exception JavaDoc throwableException = exception.getException();
358                     if (throwableException instanceof IllegalAccessException JavaDoc) {
359                         throw DescriptorException.illegalAccessWhileMethodInstantiationOfFactory(getFactoryMethodName(), getDescriptor(), throwableException);
360                     } else {
361                         throw DescriptorException.targetInvocationWhileMethodInstantiationOfFactory(getFactoryMethodName(), getDescriptor(), throwableException);
362                     }
363
364                 }
365             } else {
366                 return PrivilegedAccessHelper.invokeMethod(factoryMethod, null, null);
367             }
368         } catch (IllegalAccessException JavaDoc exception) {
369             throw DescriptorException.illegalAccessWhileMethodInstantiationOfFactory(getFactoryMethodName(), getDescriptor(), exception);
370         } catch (InvocationTargetException exception) {
371             throw DescriptorException.targetInvocationWhileMethodInstantiationOfFactory(getFactoryMethodName(), getDescriptor(), exception);
372         } catch (NullPointerException JavaDoc exception) {
373             // Some JVMs will throw a NULL pointer exception here
374
throw DescriptorException.nullPointerWhileMethodInstantiationOfFactory(getFactoryMethodName(), getDescriptor(), exception);
375         }
376     }
377
378     /**
379      * Initialize the method.
380      * It is either a static on the descriptor class, or it is a non-static on the factory.
381      */

382     protected void initializeMethod() throws DescriptorException {
383         Class JavaDoc tempClass;
384         if (this.getFactory() == null) {
385             tempClass = this.getDescriptor().getJavaClass();
386         } else {
387             tempClass = this.getFactory().getClass();
388         }
389         this.setMethod(this.buildMethod(tempClass, this.getMethodName(), new Class JavaDoc[0]));
390     }
391
392     /**
393      * Build the specified method.
394      */

395     protected Method buildMethod(Class JavaDoc methodClass, String JavaDoc methodName, Class JavaDoc[] methodParameterTypes) throws DescriptorException {
396         try {
397             return Helper.getDeclaredMethod(methodClass, methodName, methodParameterTypes);
398         } catch (NoSuchMethodException JavaDoc exception) {
399             throw DescriptorException.noSuchMethodWhileInitializingInstantiationPolicy(methodClass.getName() + "." + methodName, this.getDescriptor(), exception);
400         } catch (SecurityException JavaDoc exception) {
401             throw DescriptorException.securityWhileInitializingInstantiationPolicy(methodClass.getName() + "." + methodName, this.getDescriptor(), exception);
402         }
403     }
404
405     /**
406      * If no method name is specified, they we have to use the default (zero-argument) constructor.
407      */

408     public boolean isUsingDefaultConstructor() {
409         return this.getMethodName() == null;
410     }
411
412     protected void setDefaultConstructor(Constructor defaultConstructor) {
413         this.defaultConstructor = defaultConstructor;
414     }
415
416     public void setDescriptor(ClassDescriptor descriptor) {
417         this.descriptor = descriptor;
418     }
419
420     protected void setFactoryMethodName(String JavaDoc factoryMethodName) {
421         this.factoryMethodName = factoryMethodName;
422     }
423
424     protected void setFactory(Object JavaDoc factory) {
425         this.factory = factory;
426     }
427
428     protected void setFactoryClass(Class JavaDoc factoryClass) {
429         this.factoryClass = factoryClass;
430     }
431
432     protected void setFactoryClassName(String JavaDoc factoryClassName) {
433         this.factoryClassName = factoryClassName;
434     }
435
436     protected void setMethod(Method method) {
437         this.method = method;
438     }
439
440     public void setMethodName(String JavaDoc methodName) {
441         this.methodName = methodName;
442     }
443
444     /**
445      * INTERNAL:
446      * Convert all the class-name-based settings in this InstantiationPolicy to actual class-based
447      * settings. This method is used when converting a project that has been built
448      * with class names to a project with classes.
449      * @param classLoader
450      */

451     public void convertClassNamesToClasses(ClassLoader JavaDoc classLoader){
452         if (factoryClassName == null){
453             return;
454         }
455         Class JavaDoc factoryClass = null;
456         try{
457             if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
458                 try {
459                     factoryClass = (Class JavaDoc)AccessController.doPrivileged(new PrivilegedClassForName(factoryClassName, true, classLoader));
460                 } catch (PrivilegedActionException JavaDoc exception) {
461                     throw ValidationException.classNotFoundWhileConvertingClassNames(factoryClassName, exception.getException());
462                 }
463             } else {
464                 factoryClass = oracle.toplink.essentials.internal.security.PrivilegedAccessHelper.getClassForName(factoryClassName, true, classLoader);
465             }
466         } catch (ClassNotFoundException JavaDoc exc){
467             throw ValidationException.classNotFoundWhileConvertingClassNames(factoryClassName, exc);
468         }
469         setFactoryClass(factoryClass);
470     }
471
472     public String JavaDoc toString() {
473         String JavaDoc mName = null;
474         if (this.isUsingDefaultConstructor()) {
475             mName = "<CONSTRUCTOR>";
476         } else {
477             mName = this.getMethodName();
478         }
479         return Helper.getShortClassName(this) + "(" + mName + ")";
480     }
481
482     public void useDefaultConstructorInstantiationPolicy() {
483         setMethodName(null);
484         setFactory(null);
485         setFactoryClass(null);
486         setFactoryClassName(null);
487         setFactoryMethodName(null);
488     }
489
490     public void useFactoryInstantiationPolicy(Class JavaDoc factoryClass, String JavaDoc methodName) {
491         setMethodName(methodName);
492         setFactory(null);
493         setFactoryClass(factoryClass);
494         setFactoryClassName(factoryClass.getName());
495         setFactoryMethodName(null);
496     }
497
498     public void useFactoryInstantiationPolicy(Class JavaDoc factoryClass, String JavaDoc methodName, String JavaDoc factoryMethodName) {
499         setMethodName(methodName);
500         setFactory(null);
501         setFactoryClass(factoryClass);
502         setFactoryClassName(factoryClass.getName());
503         setFactoryMethodName(factoryMethodName);
504     }
505
506     public void useFactoryInstantiationPolicy(String JavaDoc factoryClassName, String JavaDoc methodName) {
507         setMethodName(methodName);
508         setFactory(null);
509         setFactoryClass(null);
510         setFactoryClassName(factoryClassName);
511         setFactoryMethodName(null);
512     }
513
514     public void useFactoryInstantiationPolicy(String JavaDoc factoryClassName, String JavaDoc methodName, String JavaDoc factoryMethodName) {
515         setMethodName(methodName);
516         setFactory(null);
517         setFactoryClass(null);
518         setFactoryClassName(factoryClassName);
519         setFactoryMethodName(factoryMethodName);
520     }
521
522     public void useFactoryInstantiationPolicy(Object JavaDoc factory, String JavaDoc methodName) {
523         setMethodName(methodName);
524         setFactory(factory);
525         setFactoryClass(null);
526         setFactoryClassName(null);
527         setFactoryMethodName(null);
528     }
529
530     public void useMethodInstantiationPolicy(String JavaDoc staticMethodName) {
531         setMethodName(staticMethodName);
532         setFactory(null);
533         setFactoryClass(null);
534         setFactoryClassName(null);
535         setFactoryMethodName(null);
536     }
537 }
538
Popular Tags