public void testMethodKey() throws Exception { MethodKey factory = (MethodKey) KeyFactory.create(MethodKey.class); Set methodSet = new HashSet(); methodSet.add(factory.newInstance(Number.class, new Class[] {int.class})); assertTrue(methodSet.contains(factory.newInstance(Number.class, new Class[] {int.class}))); assertTrue(!methodSet.contains(factory.newInstance(Number.class, new Class[] {Integer.class}))); }
public void testSimple() throws Exception { MyKey mykey = (MyKey) KeyFactory.create(MyKey.class); assertTrue( mykey.newInstance(5, new int[] {6, 7}, false).hashCode() == mykey.newInstance(5, new int[] {6, 7}, false).hashCode()); }
public void perform(ClassLoader loader) throws Throwable { KeyFactory.create(loader, MyKey.class, null); }
public void testEqualOtherClass() throws Exception { MyKey mykey = (MyKey) KeyFactory.create(MyKey.class); assertTrue(!mykey.newInstance(5, new int[] {6, 7}, false).equals(new Object())); }
public void testBooleanArray() throws Exception { BooleanArrayKey f = (BooleanArrayKey) KeyFactory.create(BooleanArrayKey.class); Object key1 = f.newInstance(new boolean[] {true, false, true}); Object key2 = f.newInstance(new boolean[] {true, false, true}); assertTrue(key1.equals(key2)); }
public void testCharArray() throws Exception { CharArrayKey f = (CharArrayKey) KeyFactory.create(CharArrayKey.class); Object key1 = f.newInstance(new char[] {'a', 'b'}); Object key2 = f.newInstance(new char[] {'a', '_'}); assertTrue(!key1.equals(key2)); }
/** * <b>DOCUMENTATION FROM APACHE AVALON DELEGATE CLASS</b> * * <p>Delegates are a typesafe pointer to another method. Since Java does not have language support * for such a construct, this utility will construct a proxy that forwards method calls to any * method with the same signature. This utility is inspired in part by the C# delegate mechanism. We * implemented it in a Java-centric manner. * * <h2>Delegate</h2> * * <p>Any interface with one method can become the interface for a delegate. Consider the example * below: * * <pre> * public interface MainDelegate { * int main(String[] args); * } * </pre> * * <p>The interface above is an example of an interface that can become a delegate. It has only one * method, and the interface is public. In order to create a delegate for that method, all we have * to do is call <code>MethodDelegate.create(this, "alternateMain", MainDelegate.class)</code>. The * following program will show how to use it: * * <pre> * public class Main { * public static int main( String[] args ) { * Main newMain = new Main(); * MainDelegate start = (MainDelegate) * MethodDelegate.create(newMain, "alternateMain", MainDelegate.class); * return start.main( args ); * } * * public int alternateMain( String[] args ) { * for (int i = 0; i < args.length; i++) { * System.out.println( args[i] ); * } * return args.length; * } * } * </pre> * * <p>By themselves, delegates don't do much. Their true power lies in the fact that they can be * treated like objects, and passed to other methods. In fact that is one of the key building blocks * of building Intelligent Agents which in tern are the foundation of artificial intelligence. In * the above program, we could have easily created the delegate to match the static <code>main * </code> method by substituting the delegate creation call with this: <code> * MethodDelegate.createStatic(getClass(), "main", MainDelegate.class)</code>. * * <p>Another key use for Delegates is to register event listeners. It is much easier to have all * the code for your events separated out into methods instead of individual classes. One of the * ways Java gets around that is to create anonymous classes. They are particularly troublesome * because many Debuggers do not know what to do with them. Anonymous classes tend to duplicate alot * of code as well. We can use any interface with one declared method to forward events to any * method that matches the signature (although the method name can be different). * * <h3>Equality</h3> * * The criteria that we use to test if two delegates are equal are: * * <ul> * <li>They both refer to the same instance. That is, the <code>instance</code> parameter passed * to the newDelegate method was the same for both. The instances are compared with the * identity equality operator, <code>==</code>. * <li>They refer to the same method as resolved by <code>Method.equals</code>. * </ul> * * @version $Id: MethodDelegate.java,v 1.25 2006/03/05 02:43:19 herbyderby Exp $ */ public abstract class MethodDelegate { private static final MethodDelegateKey KEY_FACTORY = (MethodDelegateKey) KeyFactory.create(MethodDelegateKey.class, KeyFactory.CLASS_BY_NAME); protected Object target; protected String eqMethod; interface MethodDelegateKey { Object newInstance(Class delegateClass, String methodName, Class iface); } public static MethodDelegate createStatic(Class targetClass, String methodName, Class iface) { Generator gen = new Generator(); gen.setTargetClass(targetClass); gen.setMethodName(methodName); gen.setInterface(iface); return gen.create(); } public static MethodDelegate create(Object target, String methodName, Class iface) { Generator gen = new Generator(); gen.setTarget(target); gen.setMethodName(methodName); gen.setInterface(iface); return gen.create(); } public boolean equals(Object obj) { MethodDelegate other = (MethodDelegate) obj; return target == other.target && eqMethod.equals(other.eqMethod); } public int hashCode() { return target.hashCode() ^ eqMethod.hashCode(); } public Object getTarget() { return target; } public abstract MethodDelegate newInstance(Object target); public static class Generator extends AbstractClassGenerator { private static final Source SOURCE = new Source(MethodDelegate.class.getName()); private static final Type METHOD_DELEGATE = TypeUtils.parseType("net.sf.cglib.reflect.MethodDelegate"); private static final Signature NEW_INSTANCE = new Signature("newInstance", METHOD_DELEGATE, new Type[] {Constants.TYPE_OBJECT}); private Object target; private Class targetClass; private String methodName; private Class iface; public Generator() { super(SOURCE); } public void setTarget(Object target) { this.target = target; this.targetClass = target.getClass(); } public void setTargetClass(Class targetClass) { this.targetClass = targetClass; } public void setMethodName(String methodName) { this.methodName = methodName; } public void setInterface(Class iface) { this.iface = iface; } protected ClassLoader getDefaultClassLoader() { return targetClass.getClassLoader(); } protected ProtectionDomain getProtectionDomain() { return ReflectUtils.getProtectionDomain(targetClass); } public MethodDelegate create() { setNamePrefix(targetClass.getName()); Object key = KEY_FACTORY.newInstance(targetClass, methodName, iface); return (MethodDelegate) super.create(key); } protected Object firstInstance(Class type) { return ((MethodDelegate) ReflectUtils.newInstance(type)).newInstance(target); } protected Object nextInstance(Object instance) { return ((MethodDelegate) instance).newInstance(target); } public void generateClass(ClassVisitor v) throws NoSuchMethodException { Method proxy = ReflectUtils.findInterfaceMethod(iface); final Method method = targetClass.getMethod(methodName, proxy.getParameterTypes()); if (!proxy.getReturnType().isAssignableFrom(method.getReturnType())) { throw new IllegalArgumentException("incompatible return types"); } MethodInfo methodInfo = ReflectUtils.getMethodInfo(method); boolean isStatic = TypeUtils.isStatic(methodInfo.getModifiers()); if ((target == null) ^ isStatic) { throw new IllegalArgumentException( "Static method " + (isStatic ? "not " : "") + "expected"); } ClassEmitter ce = new ClassEmitter(v); CodeEmitter e; ce.begin_class( Constants.V1_2, Constants.ACC_PUBLIC, getClassName(), METHOD_DELEGATE, new Type[] {Type.getType(iface)}, Constants.SOURCE_FILE); ce.declare_field(Constants.PRIVATE_FINAL_STATIC, "eqMethod", Constants.TYPE_STRING, null); EmitUtils.null_constructor(ce); // generate proxied method MethodInfo proxied = ReflectUtils.getMethodInfo(iface.getDeclaredMethods()[0]); int modifiers = Constants.ACC_PUBLIC; if ((proxied.getModifiers() & Constants.ACC_VARARGS) == Constants.ACC_VARARGS) { modifiers |= Constants.ACC_VARARGS; } e = EmitUtils.begin_method(ce, proxied, modifiers); e.load_this(); e.super_getfield("target", Constants.TYPE_OBJECT); e.checkcast(methodInfo.getClassInfo().getType()); e.load_args(); e.invoke(methodInfo); e.return_value(); e.end_method(); // newInstance e = ce.begin_method(Constants.ACC_PUBLIC, NEW_INSTANCE, null); e.new_instance_this(); e.dup(); e.dup2(); e.invoke_constructor_this(); e.getfield("eqMethod"); e.super_putfield("eqMethod", Constants.TYPE_STRING); e.load_arg(0); e.super_putfield("target", Constants.TYPE_OBJECT); e.return_value(); e.end_method(); // static initializer e = ce.begin_static(); e.push(methodInfo.getSignature().toString()); e.putfield("eqMethod"); e.return_value(); e.end_method(); ce.end_class(); } } }