All Downloads are FREE. Search and download functionalities are using the official Maven repository.

oracle.toplink.essentials.internal.descriptors.InstantiationPolicy Maven / Gradle / Ivy

The newest version!
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 * 
 * // Copyright (c) 1998, 2007, Oracle. All rights reserved.
 * 
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License. You can obtain
 * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
 * or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 * 
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
 * Sun designates this particular file as subject to the "Classpath" exception
 * as provided by Sun in the GPL Version 2 section of the License file that
 * accompanied this code.  If applicable, add the following below the License
 * Header, with the fields enclosed by brackets [] replaced by your own
 * identifying information: "Portions Copyrighted [year]
 * [name of copyright owner]"
 * 
 * Contributor(s):
 * 
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */
package oracle.toplink.essentials.internal.descriptors;

import java.io.*;
import java.lang.reflect.*;
import java.security.AccessController;
import java.security.PrivilegedActionException;

import oracle.toplink.essentials.exceptions.*;
import oracle.toplink.essentials.internal.helper.*;
import oracle.toplink.essentials.internal.security.*;
import oracle.toplink.essentials.internal.sessions.AbstractSession;
import oracle.toplink.essentials.descriptors.ClassDescriptor;

/**
 * Purpose: Allows customization of how an object is created/instantiated.

* * So, here is how it works:

* * If there is no method specified
* - all the other settings are ignored and
* - the descriptor class's default constructor is invoked.
* If a factory is specified
* - the factoryClass and factoryClassMethod are ignored and
* - the method is invoked on the factory.
* If neither a factory nor a factoryClass are specified
* - the factoryClassMethod is ignored and
* - the method is invoked on the descriptor class (as a static).
* If only the factoryClass is specified
* - the factory is created by invoking the factoryClass' default (zero-argument) constructor and
* - the method is invoked on the resulting factory.
* If both the factoryClass and the factoryClassMethod are specified
* - the factory is created by invoking the factoryClassMethod on the factoryClass (as a static) and
* - the method is invoked on the resulting factory.

* * The only thing we can't support in the current configuration is invoking a static on some, * client-specified, factoryClass to build new instances of the descriptor class; and it's debatable * whether that is desirable...

* * It might be reasonable to rework this into a number of different classes that implement * an interface... */ public class InstantiationPolicy implements Cloneable, Serializable { /** * The method invoked on either the descriptor class (in which case it is static) or * the factory (in which case it is not static) to build a new instance of the descriptor class. */ protected String methodName; /** The method is resolved during initialization, and it is not serialized. */ protected transient Method method; /** * The class of the factory. The factory is instantiated by either invoking this class's default * (zero-argument) constructor or the factoryMethod specified below. */ protected Class factoryClass; protected String factoryClassName; /** * Static method invoked on the factoryClass to get the factory instance. If this is null, the * factory class's default (zero-argument) constructor is invoked. */ protected String factoryMethodName; /** * The object factory. This can be specified directly by the client, or it can be built dynamically * using the the factoryClass and, optionally, the factoryMethodName. */ protected Object factory; /** Backpointer to descriptor. */ protected ClassDescriptor descriptor; /** Must be transient because java.lang.Constructor is not serializable. */ private transient Constructor defaultConstructor; /** * Default constructor */ public InstantiationPolicy() { super(); } /** * Build and return a new instance, using the appropriate mechanism. */ public Object buildNewInstance() throws DescriptorException { if (this.isUsingDefaultConstructor()) { return this.buildNewInstanceUsingDefaultConstructor(); } else { return this.buildNewInstanceUsingFactory(); } } /** * Build and return a new instance, using the default (zero-argument) constructor. */ protected Object buildNewInstanceUsingDefaultConstructor() throws DescriptorException { try { if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){ try { return AccessController.doPrivileged(new PrivilegedInvokeConstructor(this.getDefaultConstructor(), (Object[])null)); } catch (PrivilegedActionException exception) { Exception throwableException = exception.getException(); if (throwableException instanceof InvocationTargetException){ throw DescriptorException.targetInvocationWhileConstructorInstantiationOfFactory(this.getDescriptor(), throwableException); } else if (throwableException instanceof IllegalAccessException){ throw DescriptorException.illegalAccessWhileConstructorInstantiationOfFactory(this.getDescriptor(), throwableException); } else { throw DescriptorException.instantiationWhileConstructorInstantiationOfFactory(this.getDescriptor(), throwableException); } } } else { return PrivilegedAccessHelper.invokeConstructor(this.getDefaultConstructor(), (Object[])null); } } catch (InvocationTargetException exception) { throw DescriptorException.targetInvocationWhileConstructorInstantiation(this.getDescriptor(), exception); } catch (IllegalAccessException exception) { throw DescriptorException.illegalAccessWhileConstructorInstantiation(this.getDescriptor(), exception); } catch (InstantiationException exception) { throw DescriptorException.instantiationWhileConstructorInstantiation(this.getDescriptor(), exception); } catch (NoSuchMethodError exception) { // This exception is not documented but gets thrown. throw DescriptorException.noSuchMethodWhileConstructorInstantiation(this.getDescriptor(), exception); } catch (NullPointerException exception) { // Some JVMs will throw a NULL pointer exception here throw DescriptorException.nullPointerWhileConstructorInstantiation(this.getDescriptor(), exception); } } /** * Build and return a new instance, using the factory. * The factory can be null, in which case the method is a static method defined by the descriptor class. */ protected Object buildNewInstanceUsingFactory() throws DescriptorException { try { // If the method is static, the first argument is ignored and can be null if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){ try { return AccessController.doPrivileged(new PrivilegedMethodInvoker(this.getMethod(), this.getFactory(), new Object[0])); } catch (PrivilegedActionException exception) { Exception throwableException = exception.getException(); if (throwableException instanceof IllegalAccessException) { throw DescriptorException.illegalAccessWhileMethodInstantiation(this.getMethod().toString(), this.getDescriptor(), throwableException); } else { throw DescriptorException.targetInvocationWhileMethodInstantiation(this.getMethod().toString(), this.getDescriptor(), throwableException); } } } else { return PrivilegedAccessHelper.invokeMethod(this.getMethod(), this.getFactory(), new Object[0]); } } catch (IllegalAccessException exception) { throw DescriptorException.illegalAccessWhileMethodInstantiation(this.getMethod().toString(), this.getDescriptor(), exception); } catch (InvocationTargetException exception) { throw DescriptorException.targetInvocationWhileMethodInstantiation(this.getMethod().toString(), this.getDescriptor(), exception); } catch (NullPointerException exception) { // Some JVMs will throw a NULL pointer exception here throw DescriptorException.nullPointerWhileMethodInstantiation(this.getMethod().toString(), this.getDescriptor(), exception); } } /** * INTERNAL: * Clones the InstantiationPolicy */ public Object clone() { try { // clones itself return super.clone(); } catch (Exception exception) { ; } return null; } /** * Return the default (zero-argument) constructor for the descriptor class. */ protected Constructor getDefaultConstructor() throws DescriptorException { // Lazy initialize, because the constructor cannot be serialized if (defaultConstructor == null) { this.setDefaultConstructor(this.buildDefaultConstructor()); } return defaultConstructor; } /** * Build and return the default (zero-argument) constructor for the descriptor class. */ protected Constructor buildDefaultConstructor() throws DescriptorException { return this.buildDefaultConstructorFor(this.getDescriptor().getJavaClass()); } /** * Build and return the default (zero-argument) constructor for the specified class. */ protected Constructor buildDefaultConstructorFor(Class javaClass) throws DescriptorException { try { if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){ try { return (Constructor)AccessController.doPrivileged(new PrivilegedGetDeclaredConstructorFor(javaClass, new Class[0], true)); } catch (PrivilegedActionException exception) { throw DescriptorException.noSuchMethodWhileInitializingInstantiationPolicy(javaClass.getName() + ".", getDescriptor(), exception.getException()); } } else { return PrivilegedAccessHelper.getDeclaredConstructorFor(javaClass, new Class[0], true); } } catch (NoSuchMethodException exception) { throw DescriptorException.noSuchMethodWhileInitializingInstantiationPolicy(javaClass.getName() + ".", getDescriptor(), exception); } } protected ClassDescriptor getDescriptor() { return descriptor; } public String getFactoryMethodName() { return factoryMethodName; } public Object getFactory() { return factory; } public Class getFactoryClass() { return factoryClass; } public String getFactoryClassName() { if ((factoryClassName == null) && (factoryClass != null)) { factoryClassName = factoryClass.getName(); } return factoryClassName; } protected Method getMethod() { return method; } public String getMethodName() { return methodName; } /** * If necessary, initialize the factory and the method. */ public void initialize(AbstractSession session) throws DescriptorException { if (this.isUsingDefaultConstructor()) { return; } try { // If the factory has been specified directly, do not overwrite it if (this.getFactory() == null) { this.setFactory(this.buildFactory()); } this.initializeMethod(); } catch (DescriptorException ex) { session.getIntegrityChecker().handleError(ex); } } protected Object buildFactory() throws DescriptorException { // If there is no factory class specified, there is no factory; // we will be using a static method defined by the descriptor class... if (this.getFactoryClass() == null) { return null; } // If there is a factory class specified but no factory method name, // instantiate the factory using the default constructor if (this.getFactoryMethodName() == null) { return this.buildFactoryUsingDefaultConstructor(); } // If both the factory class and the factory method name have been specified, // instantiate the factory by invoking the static factory method return this.buildFactoryUsingStaticMethod(); } /** * Build and return the factory, using its default constructor. */ protected Object buildFactoryUsingDefaultConstructor() throws DescriptorException { try { if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){ try { return AccessController.doPrivileged(new PrivilegedInvokeConstructor(this.buildFactoryDefaultConstructor(), (Object[])null)); } catch (PrivilegedActionException exception) { Exception throwableException = exception.getException(); if (throwableException instanceof InvocationTargetException){ throw DescriptorException.targetInvocationWhileConstructorInstantiationOfFactory(this.getDescriptor(), throwableException); } else if (throwableException instanceof IllegalAccessException){ throw DescriptorException.illegalAccessWhileConstructorInstantiationOfFactory(this.getDescriptor(), throwableException); } else { throw DescriptorException.instantiationWhileConstructorInstantiationOfFactory(this.getDescriptor(), throwableException); } } } else { return PrivilegedAccessHelper.invokeConstructor(this.buildFactoryDefaultConstructor(), (Object[])null); } } catch (InvocationTargetException exception) { throw DescriptorException.targetInvocationWhileConstructorInstantiationOfFactory(this.getDescriptor(), exception); } catch (IllegalAccessException exception) { throw DescriptorException.illegalAccessWhileConstructorInstantiationOfFactory(this.getDescriptor(), exception); } catch (InstantiationException exception) { throw DescriptorException.instantiationWhileConstructorInstantiationOfFactory(this.getDescriptor(), exception); } catch (NoSuchMethodError exception) { // This exception is not documented but gets thrown. throw DescriptorException.noSuchMethodWhileConstructorInstantiationOfFactory(this.getDescriptor(), exception); } catch (NullPointerException exception) { // Some JVMs will throw a NULL pointer exception here throw DescriptorException.nullPointerWhileConstructorInstantiationOfFactory(this.getDescriptor(), exception); } } /** * Build and return the default (zero-argument) constructor for the factory class. */ protected Constructor buildFactoryDefaultConstructor() throws DescriptorException { return this.buildDefaultConstructorFor(this.getFactoryClass()); } /** * Build and return the factory, using the specified static method. */ protected Object buildFactoryUsingStaticMethod() throws DescriptorException { Method factoryMethod = this.buildMethod(this.getFactoryClass(), this.getFactoryMethodName(), new Class[0]); try { // it should be static and zero-argument... if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){ try { return AccessController.doPrivileged(new PrivilegedMethodInvoker(factoryMethod, null, null)); } catch (PrivilegedActionException exception) { Exception throwableException = exception.getException(); if (throwableException instanceof IllegalAccessException) { throw DescriptorException.illegalAccessWhileMethodInstantiationOfFactory(getFactoryMethodName(), getDescriptor(), throwableException); } else { throw DescriptorException.targetInvocationWhileMethodInstantiationOfFactory(getFactoryMethodName(), getDescriptor(), throwableException); } } } else { return PrivilegedAccessHelper.invokeMethod(factoryMethod, null, null); } } catch (IllegalAccessException exception) { throw DescriptorException.illegalAccessWhileMethodInstantiationOfFactory(getFactoryMethodName(), getDescriptor(), exception); } catch (InvocationTargetException exception) { throw DescriptorException.targetInvocationWhileMethodInstantiationOfFactory(getFactoryMethodName(), getDescriptor(), exception); } catch (NullPointerException exception) { // Some JVMs will throw a NULL pointer exception here throw DescriptorException.nullPointerWhileMethodInstantiationOfFactory(getFactoryMethodName(), getDescriptor(), exception); } } /** * Initialize the method. * It is either a static on the descriptor class, or it is a non-static on the factory. */ protected void initializeMethod() throws DescriptorException { Class tempClass; if (this.getFactory() == null) { tempClass = this.getDescriptor().getJavaClass(); } else { tempClass = this.getFactory().getClass(); } this.setMethod(this.buildMethod(tempClass, this.getMethodName(), new Class[0])); } /** * Build the specified method. */ protected Method buildMethod(Class methodClass, String methodName, Class[] methodParameterTypes) throws DescriptorException { try { return Helper.getDeclaredMethod(methodClass, methodName, methodParameterTypes); } catch (NoSuchMethodException exception) { throw DescriptorException.noSuchMethodWhileInitializingInstantiationPolicy(methodClass.getName() + "." + methodName, this.getDescriptor(), exception); } catch (SecurityException exception) { throw DescriptorException.securityWhileInitializingInstantiationPolicy(methodClass.getName() + "." + methodName, this.getDescriptor(), exception); } } /** * If no method name is specified, they we have to use the default (zero-argument) constructor. */ public boolean isUsingDefaultConstructor() { return this.getMethodName() == null; } protected void setDefaultConstructor(Constructor defaultConstructor) { this.defaultConstructor = defaultConstructor; } public void setDescriptor(ClassDescriptor descriptor) { this.descriptor = descriptor; } protected void setFactoryMethodName(String factoryMethodName) { this.factoryMethodName = factoryMethodName; } protected void setFactory(Object factory) { this.factory = factory; } protected void setFactoryClass(Class factoryClass) { this.factoryClass = factoryClass; } protected void setFactoryClassName(String factoryClassName) { this.factoryClassName = factoryClassName; } protected void setMethod(Method method) { this.method = method; } public void setMethodName(String methodName) { this.methodName = methodName; } /** * INTERNAL: * Convert all the class-name-based settings in this InstantiationPolicy to actual class-based * settings. This method is used when converting a project that has been built * with class names to a project with classes. * @param classLoader */ public void convertClassNamesToClasses(ClassLoader classLoader){ if (factoryClassName == null){ return; } Class factoryClass = null; try{ if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){ try { factoryClass = (Class)AccessController.doPrivileged(new PrivilegedClassForName(factoryClassName, true, classLoader)); } catch (PrivilegedActionException exception) { throw ValidationException.classNotFoundWhileConvertingClassNames(factoryClassName, exception.getException()); } } else { factoryClass = oracle.toplink.essentials.internal.security.PrivilegedAccessHelper.getClassForName(factoryClassName, true, classLoader); } } catch (ClassNotFoundException exc){ throw ValidationException.classNotFoundWhileConvertingClassNames(factoryClassName, exc); } setFactoryClass(factoryClass); } public String toString() { String mName = null; if (this.isUsingDefaultConstructor()) { mName = ""; } else { mName = this.getMethodName(); } return Helper.getShortClassName(this) + "(" + mName + ")"; } public void useDefaultConstructorInstantiationPolicy() { setMethodName(null); setFactory(null); setFactoryClass(null); setFactoryClassName(null); setFactoryMethodName(null); } public void useFactoryInstantiationPolicy(Class factoryClass, String methodName) { setMethodName(methodName); setFactory(null); setFactoryClass(factoryClass); setFactoryClassName(factoryClass.getName()); setFactoryMethodName(null); } public void useFactoryInstantiationPolicy(Class factoryClass, String methodName, String factoryMethodName) { setMethodName(methodName); setFactory(null); setFactoryClass(factoryClass); setFactoryClassName(factoryClass.getName()); setFactoryMethodName(factoryMethodName); } public void useFactoryInstantiationPolicy(String factoryClassName, String methodName) { setMethodName(methodName); setFactory(null); setFactoryClass(null); setFactoryClassName(factoryClassName); setFactoryMethodName(null); } public void useFactoryInstantiationPolicy(String factoryClassName, String methodName, String factoryMethodName) { setMethodName(methodName); setFactory(null); setFactoryClass(null); setFactoryClassName(factoryClassName); setFactoryMethodName(factoryMethodName); } public void useFactoryInstantiationPolicy(Object factory, String methodName) { setMethodName(methodName); setFactory(factory); setFactoryClass(null); setFactoryClassName(null); setFactoryMethodName(null); } public void useMethodInstantiationPolicy(String staticMethodName) { setMethodName(staticMethodName); setFactory(null); setFactoryClass(null); setFactoryClassName(null); setFactoryMethodName(null); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy