
org.jingle.util.dydelegation.DelegationGenerator Maven / Gradle / Ivy
package org.jingle.util.dydelegation;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* Delegation generator
*
* @author JianLu
* @version 1.0 2004-9-23
* @since 1.0
*/
public class DelegationGenerator {
/**
* The generated delegation classes map. Key is DelegationGenerator.Key
* instance, Value is generated class.
*/
static Map classes = new HashMap();
/**
* Delegation Creator Factory instance
*/
static DelegationCreatorFactory factory = new DelegationCreatorFactory();
/**
*
* The internal class represents the key of the generated classes map
*
* @author JianLu
* @version 1.0 2004-10-29
* @since 1.0
*/
static class Key {
/**
* Source class names
*/
Set srcClassNames = new HashSet();
/**
* Target class name
*/
String targetClassName;
/**
* Constructor
*
* @param srcClassName
* Source class name
* @param targetClassName
* Target class name
*/
public Key(Class[] srcClasses, String targetClassName) {
if (srcClasses != null) {
for (int i = 1; i <= srcClasses.length; i++) {
srcClassNames.add(srcClasses[i - 1].getName());
}
}
this.targetClassName = targetClassName;
}
/**
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object obj) {
if (obj instanceof Key) {
Key key = (Key) obj;
if (srcClassNames.equals(key.srcClassNames)
&& ((targetClassName == null) ? (key.targetClassName == null)
: targetClassName.equals(key.targetClassName)))
return true;
}
return false;
}
/**
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
return srcClassNames.hashCode() + ("" + targetClassName).hashCode();
}
}
/**
* Protected constructor to avoid user to instantiate it
*
*/
protected DelegationGenerator() {
}
/**
* Get the DelegationInvocationHandler of a specific delegation object
*
* @param delegation
* The delegation object
* @return DelegationInvocationHandler of the delegation object. If the
* object is not a delegation, return null.
*/
public static DelegationInvocationHandler getInvocationHandler(
Object delegation) {
if (isDelegation(delegation)) {
return ((Delegation) delegation)._getInvocationHandler();
}
return null;
}
/**
* Set the delegation creator factory
*
* @param factory
* DelegationCreatorFactory
*/
public static void setDelegationCreatorFactory(
DelegationCreatorFactory factory) {
DelegationGenerator.factory = factory;
}
/**
* It is same as getDelegationClass(null, beanClasses).
*
* @see org.jingle.util.dydelegation.DelegationGenerator#getDelegationClass(java.lang.String,
* java.lang.Class[])
* @param beanClasses
* The classes to be delegated.
* @return The delegation class
*/
public static synchronized Class getDelegationClass(Class[] beanClasses) {
return getDelegationClass(null, beanClasses);
}
/**
* Get delegation class for a specific class
*
* @param targetClassName
* The generated delegation class full name. If it is null, the
* generator will give a system generated class name. The default
* package is same as the source class package.
* @param beanClasses
* The classes to be delegated. The class array can contains 1 class
* at most and can contains multiple interfaces.
* @return The delegation class
*/
public static synchronized Class getDelegationClass(String targetClassName,
Class[] beanClasses) {
Key key = new Key(beanClasses, targetClassName);
Class ret = (Class) classes.get(key);
if (ret == null) {
DelegationCreator creator = factory.getCreator(targetClassName,
beanClasses);
FileOutputStream os = null;
// try {
// os = new FileOutputStream(
// "c:/temp/TestBean_Delegation_0.class");
// } catch (FileNotFoundException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
try {
ret = creator.create(os);
} catch (IOException e1) {
e1.printStackTrace();
} finally {
if (os != null) {
try {
os.close();
} catch(Exception e) {
}
}
}
if (ret != null) {
classes.put(key, ret);
}
}
return ret;
}
/**
* Check whether the class is a delegation class or not
*
* @param beanClass
* The class to be checked
* @return true if the input class is a delegation class.
*/
public static boolean isDelegationClass(Class beanClass) {
if (Delegation.class.isAssignableFrom(beanClass))
return true;
return false;
}
/**
* Check whether the object is a delegation object or not
*
* @param obj
* The object to be checked
* @return true if the input object is a delegation object
*/
public static boolean isDelegation(Object obj) {
return isDelegationClass(obj.getClass());
}
/**
* It is same as newDelegationInstance(bean, null, h)
*
* @see org.jingle.util.dydelegation.DelegationGenerator#newDelegationInstance(java.lang.Object,
* java.lang.String,
* org.jingle.util.dydelegation.DelegationInvocationHandler)
* @param bean
* The object to be delegated
* @param h
* The delegation invocation handler
* @return The generated delegation object
*/
public static Object newDelegationInstance(Object bean,
DelegationInvocationHandler h) {
return newDelegationInstance(bean, null, h);
}
/**
* It is same as newDelegationInstance(bean, null, paraTypes, paras, h)
*
* @see org.jingle.util.dydelegation.DelegationGenerator#newDelegationInstance(java.lang.Object,
* java.lang.String, java.lang.Class[], java.lang.Object[],
* org.jingle.util.dydelegation.DelegationInvocationHandler)
* @param bean
* The object to be delegated
* @param paraTypes The parameter types for the constructor of delegated class
* @param paras The parameter values for the constructor of delegated class
* @param h
* The delegation invocation handler
* @return The generated delegation object
*/
public static Object newDelegationInstance(Object bean, Class[] paraTypes, Object[] paras,
DelegationInvocationHandler h) {
return newDelegationInstance(bean, null, paraTypes, paras, h);
}
/**
* It is same as newDelegationInstance(bean, new Class[] {bean.getClass()},
* targetClassName, h)
*
* @see org.jingle.util.dydelegation.DelegationGenerator#newDelegationInstance(java.lang.Object,
* java.lang.Class[], java.lang.String,
* org.jingle.util.dydelegation.DelegationInvocationHandler)
* @param bean
* The object to be delegated
* @param targetClassName
* The generated delegation's class name. If null, a system generated name is provided.
* @param h
* The delegation invocation handler
* @return The generated delegation object
*/
public static Object newDelegationInstance(Object bean,
String targetClassName, DelegationInvocationHandler h) {
return newDelegationInstance(bean, new Class[] { bean.getClass() },
targetClassName, h);
}
/**
* It is same as newDelegationInstance(bean, new Class[] {bean.getClass()},
* targetClassName, paraTypes, paras, h)
*
* @see org.jingle.util.dydelegation.DelegationGenerator#newDelegationInstance(java.lang.Object,
* java.lang.Class[], java.lang.String, java.lang.Class[], java.lang.Object[],
* org.jingle.util.dydelegation.DelegationInvocationHandler)
* @param bean
* The object to be delegated
* @param targetClassName
* The generated delegation's class name. If null, a system generated name is provided.
* @param paraTypes The parameter types for the constructor of delegated class
* @param paras The parameter values for the constructor of delegated class
* @param h
* The delegation invocation handler
* @return The generated delegation object
*/
public static Object newDelegationInstance(Object bean,
String targetClassName, Class[] paraTypes, Object[] paras,
DelegationInvocationHandler h) {
return newDelegationInstance(bean, new Class[] { bean.getClass() },
targetClassName, paraTypes, paras, h);
}
/**
* It is same as newDelegationInstance(bean, beanClasses,
* new Class[0], new Object[0], targetClassName, h)
*
* @see org.jingle.util.dydelegation.DelegationGenerator#newDelegationInstance(java.lang.Object,
* java.lang.Class[], java.lang.String, java.lang.Class[], java.lang.Object[],
* org.jingle.util.dydelegation.DelegationInvocationHandler)
*
* @param bean
* The object to be delegated
* @param beanClasses
* The classes to be delegated. If bean is not null, it should
* an instance of these classes. The calss array can contains 1
* class at most and can contains multiple interfaces.
* @param targetClassName
* The generated delegation's class name, it is useful when want
* to delegate a java core class. If null, a system generated name is provided.
* @param h
* The delegation invocation handler
* @return The generated delegation object
*/
public static Object newDelegationInstance(Object bean,
Class[] beanClasses, String targetClassName,
DelegationInvocationHandler h) {
return newDelegationInstance(bean, beanClasses,
targetClassName, new Class[0], new Object[0], h);
}
/**
* Create a delegation instance for the specific object
*
* @param bean
* The object to be delegated
* @param beanClasses
* The classes to be delegated. If bean is not null, it should
* an instance of these classes. The calss array can contains 1
* class at most and can contains multiple interfaces.
* @param targetClassName
* The generated delegation's class name, it is useful when want
* to delegate a java core class. If null, a system generated name is provided.
* @param paraTypes The parameter types for the constructor of delegated class
* @param paras The parameter values for the constructor of delegated class
* @param h
* The delegation invocation handler
* @return The generated delegation object
*/
public static Object newDelegationInstance(Object bean,
Class[] beanClasses, String targetClassName,
Class[] paraTypes, Object[] paras,
DelegationInvocationHandler h) {
Object ret = null;
// if (bean != null) {
// if (beanClasses != null) {
// Class clazz = bean.getClass();
// for (int i = 1; i <= beanClasses.length; i++) {
// if (!beanClasses[i - 1].isAssignableFrom(clazz))
// throw new IllegalArgumentException("The bean object must be an instance of each beanClass");
// }
// }
// }
Class clazz = getDelegationClass(targetClassName, beanClasses);
try {
Class[] constructorParaTypes = new Class[paraTypes.length + 1];
Object[] constructorParas = new Object[paras.length + 1];
constructorParaTypes[0] = Object.class;
constructorParas[0] = bean;
System.arraycopy(paraTypes, 0, constructorParaTypes, 1, paraTypes.length);
System.arraycopy(paras, 0, constructorParas, 1, paras.length);
Constructor c = clazz.getConstructor(constructorParaTypes);
ret = c.newInstance(constructorParas);
((Delegation) ret)._setInvocationHandler(h);
} catch (IllegalArgumentException e) {
throw e;
} catch (Exception e) {
e.printStackTrace();
throw new IllegalArgumentException(e.toString());
}
return ret;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy