User: starksm Date: 01/11/20 01:42:56 Modified: src/main/org/jboss/proxy Tag: Branch_2_4 Proxies.java ProxyProxy.java Log: Change to the unified log4j based org.jboss.logging.Logger class. Revision Changes Path No revision No revision 1.2.6.1 +580 -467 jboss/src/main/org/jboss/proxy/Proxies.java Index: Proxies.java =================================================================== RCS file: /cvsroot/jboss/jboss/src/main/org/jboss/proxy/Proxies.java,v retrieving revision 1.2 retrieving revision 1.2.6.1 diff -u -r1.2 -r1.2.6.1 --- Proxies.java 2000/08/18 03:21:09 1.2 +++ Proxies.java 2001/11/20 09:42:55 1.2.6.1 @@ -5,14 +5,17 @@ import org.jboss.logging.Logger; /** -* Routines for converting between strongly-typed interfaces and -* generic InvocationHandler objects. -*/ -public final class Proxies { - private Proxies() {} - - - /** + * Routines for converting between strongly-typed interfaces and + * generic InvocationHandler objects. + */ +public final class Proxies +{ + static Logger log = Logger.getLogger(Proxies.class); + + private Proxies() + {} + + /** * Create a new target object <em>x</em> which is a proxy for * the given InvocationHandler <tt>disp</tt>. The new object will be equivalent * to <tt>disp</tt>, except that it will support normal Java method @@ -43,33 +46,35 @@ * // x1 != x3, but calls to x3 are forwarded via i to x1 * </code> */ - public static ProxyTarget newTarget(ClassLoader parent, InvocationHandler InvocationHandler, Class targetTypes[]) { - return Impl.getImpl(targetTypes).newTarget(InvocationHandler, parent); - } + public static ProxyTarget newTarget(ClassLoader parent, InvocationHandler InvocationHandler, Class targetTypes[]) + { + return Impl.getImpl(targetTypes).newTarget(InvocationHandler, parent); + } /*public static ProxyTarget newTarget(InvocationHandler InvocationHandler) { return newTarget(InvocationHandler, InvocationHandler.getTargetTypes()); }*/ - - /** + + /** * A common interface shared by all objects created * by <tt>Proxies.newTarget</tt>. */ - - public interface ProxyTarget extends Serializable/*extends Object*/ { - /** - * Recover the original InvocationHandler object around which this - * proxy is wrapped. - */ - InvocationHandler getInvocationHandler(); - - - /** - * Recover the original target types for which this proxy was wrapped. - */ - Class[] getTargetTypes(); - } - - /** + + public interface ProxyTarget extends Serializable/*extends Object*/ + { + /** + * Recover the original InvocationHandler object around which this + * proxy is wrapped. + */ + InvocationHandler getInvocationHandler(); + + + /** + * Recover the original target types for which this proxy was wrapped. + */ + Class[] getTargetTypes(); + } + + /** * Create a new reflective InvocationHandler object <tt>InvocationHandler</tt> wrapped * around the given target object, for the given target type(s). * <p> @@ -87,27 +92,29 @@ * InvocationHandler i = Proxies.newInvocationHandler(x1, MyInterface.class); * </code> */ - public static ProxyInvocationHandler newInvocationHandler(Object target, Class targetType) { - return Impl.getImpl(targetType).newInvocationHandler(target); - } - public static ProxyInvocationHandler newInvocationHandler(Object target, Class targetTypes[]) { - return Impl.getImpl(targetTypes).newInvocationHandler(target); - } - - /** + public static ProxyInvocationHandler newInvocationHandler(Object target, Class targetType) + { + return Impl.getImpl(targetType).newInvocationHandler(target); + } + public static ProxyInvocationHandler newInvocationHandler(Object target, Class targetTypes[]) + { + return Impl.getImpl(targetTypes).newInvocationHandler(target); + } + + /** * A common interface shared by all objects created * by <tt>Proxies.newInvocationHandler</tt>. */ - public interface ProxyInvocationHandler extends InvocationHandler, Serializable - { - /** - * Recover the original target object around which this - * InvocationHandler proxy is wrapped. - */ - Object getTarget(); - } - - /** + public interface ProxyInvocationHandler extends InvocationHandler, Serializable + { + /** + * Recover the original target object around which this + * InvocationHandler proxy is wrapped. + */ + Object getTarget(); + } + + /** * Utility built on top of <tt>newTarget</tt> to find * or create a proxy for the given InvocationHandler. * It is the inverse of <tt>getInvocationHandler</tt>. @@ -116,7 +123,8 @@ * for some original target object; extract and return that object. * Otherwise, just call <tt>newTarget</tt>. */ - public static Object getTarget(InvocationHandler InvocationHandler) { + public static Object getTarget(InvocationHandler InvocationHandler) + { /* if (InvocationHandler instanceof ProxyTargetMemo) { // this kind of InvocationHandler is able to memoize the ProxyTarget we build @@ -128,21 +136,23 @@ } return target; } - */ - - if (InvocationHandler instanceof ProxyInvocationHandler) { - Object target = ((ProxyInvocationHandler)InvocationHandler).getTarget(); - if (target != null) { - return target; - } - // and fall through... - } - //return newTarget(InvocationHandler); - return null; - } - - - /** + */ + + if (InvocationHandler instanceof ProxyInvocationHandler) + { + Object target = ((ProxyInvocationHandler)InvocationHandler).getTarget(); + if (target != null) + { + return target; + } + // and fall through... + } + //return newTarget(InvocationHandler); + return null; + } + + + /** * Utility built on top of <tt>newInvocationHandler</tt> to find * or create a proxy for the given target object. * It is the inverse of <tt>getTarget</tt>. @@ -152,27 +162,33 @@ * Otherwise, just call <tt>newInvocationHandler</tt>. * @see #newInvocationHandler */ - public static InvocationHandler getInvocationHandler(Object target, Class targetTypes[]) { - if (target instanceof ProxyTarget) { - ProxyTarget tproxy = (ProxyTarget)target; - InvocationHandler InvocationHandler = tproxy.getInvocationHandler(); - if (targetTypes == null || - Impl.sameTypes(tproxy.getTargetTypes(), targetTypes)) { - return InvocationHandler; - } - // and fall through... - } - return newInvocationHandler(target, targetTypes); - } - public static InvocationHandler getInvocationHandler(Object target, Class targetType) { - // (should this be optimized?) - if (targetType == null) { - return getInvocationHandler(target, (Class[])null); - } - return getInvocationHandler(target, new Class[]{ targetType }); - } - - /** + public static InvocationHandler getInvocationHandler(Object target, Class targetTypes[]) + { + if (target instanceof ProxyTarget) + { + ProxyTarget tproxy = (ProxyTarget)target; + InvocationHandler InvocationHandler = tproxy.getInvocationHandler(); + if (targetTypes == null || + Impl.sameTypes(tproxy.getTargetTypes(), targetTypes)) + { + return InvocationHandler; + } + // and fall through... + } + return newInvocationHandler(target, targetTypes); + } + public static InvocationHandler getInvocationHandler(Object target, Class targetType) + { + // (should this be optimized?) + if (targetType == null) + { + return getInvocationHandler(target, (Class[])null); + } + return getInvocationHandler(target, new Class[] + { targetType }); + } + + /** * Utility which reports the set of valid methods for a target type. * It is exactly the set of <tt>public</tt>, <tt>abstract</tt> methods * returned by <tt>targetType.getMethods()</tt>, which are neither @@ -184,393 +200,490 @@ * and must not be something silly like * an array or primitive type, or a <tt>final</tt> class. */ - public static Method[] getMethods(Class targetType) { - return Impl.getImpl(targetType).copyMethods(); - } - public static Method[] getMethods(Class targetTypes[]) { - return Impl.getImpl(targetTypes).copyMethods(); - } - - static class Impl implements Serializable { - static java.util.Hashtable impls = new java.util.Hashtable(); - - Class targetTypes[]; // the types that this impl processes - Method methods[]; - Impl more; // hashtable link to Impls sharing a target type - - Class superclass = Object.class; - String proxyString; // used in print names of proxies - Constructor proxyConstructor; - - static synchronized Impl getImpl(Class targetType) { - Impl impl = (Impl) impls.get(targetType); - if (impl == null) { - impl = new Impl(new Class[]{ targetType }); - impls.put(targetType, impl); - } - return impl; - } - - static synchronized Impl getImpl(Class targetTypes[]) { - int n = targetTypes.length; - if (n == 1) { - return getImpl(targetTypes[0]); - } - // note that the desired Impl could be in any one of n places - // this requires extra searching, which is not a big deal - for (int i = 0; i < n; ++i) { - for (Impl impl = (Impl) impls.get(targetTypes[i]); - impl != null; impl = impl.more) { - if (sameTypes(targetTypes, impl.targetTypes)) - return impl; - } - } - - // now link it into the table - targetTypes = copyAndUniquify(targetTypes); - Impl impl1 = getImpl(new Class[]{ targetTypes[0] }); - Impl impl = new Impl(targetTypes); - impl.more = impl1.more; - impl1.more = impl; - return impl; - } - - // do the arrays have the same elements? - // (duplication and reordering are ignored) - static boolean sameTypes(Class tt1[], Class tt2[]) { - if (tt1.length == 1 && tt2.length == 0) { - return tt1[0] == tt2[0]; - } - - int totalSeen2 = 0; - each_type: - for (int i = tt1.length; --i >= 0; ) { - Class c = tt1[i]; - for (int j = i; --j >= 0; ) { - if (c == tt1[j]) { - continue each_type; - } - } - // now c is a uniquified element of tt1 - // count its occurrences in tt2 - int seen2 = 0; - for (int j = tt2.length; --j >= 0; ) { - if (c == tt2[j]) { - ++seen2; - } - } - if (seen2 == 0) { - // c does not occur in tt2 - return false; - } - totalSeen2 += seen2; + public static Method[] getMethods(Class targetType) + { + return Impl.getImpl(targetType).copyMethods(); + } + public static Method[] getMethods(Class targetTypes[]) + { + return Impl.getImpl(targetTypes).copyMethods(); + } + + static class Impl implements Serializable + { + static java.util.Hashtable impls = new java.util.Hashtable(); + + Class targetTypes[]; // the types that this impl processes + Method methods[]; + Impl more; // hashtable link to Impls sharing a target type + + Class superclass = Object.class; + String proxyString; // used in print names of proxies + Constructor proxyConstructor; + + static synchronized Impl getImpl(Class targetType) + { + Impl impl = (Impl) impls.get(targetType); + if (impl == null) + { + impl = new Impl(new Class[] + { targetType }); + impls.put(targetType, impl); + } + return impl; + } + + static synchronized Impl getImpl(Class targetTypes[]) + { + int n = targetTypes.length; + if (n == 1) + { + return getImpl(targetTypes[0]); + } + // note that the desired Impl could be in any one of n places + // this requires extra searching, which is not a big deal + for (int i = 0; i < n; ++i) + { + for (Impl impl = (Impl) impls.get(targetTypes[i]); + impl != null; impl = impl.more) + { + if (sameTypes(targetTypes, impl.targetTypes)) + return impl; + } + } + + // now link it into the table + targetTypes = copyAndUniquify(targetTypes); + Impl impl1 = getImpl(new Class[] + { targetTypes[0] }); + Impl impl = new Impl(targetTypes); + impl.more = impl1.more; + impl1.more = impl; + return impl; + } + + // do the arrays have the same elements? + // (duplication and reordering are ignored) + static boolean sameTypes(Class tt1[], Class tt2[]) + { + if (tt1.length == 1 && tt2.length == 0) + { + return tt1[0] == tt2[0]; + } + + int totalSeen2 = 0; + each_type: + for (int i = tt1.length; --i >= 0; ) + { + Class c = tt1[i]; + for (int j = i; --j >= 0; ) + { + if (c == tt1[j]) + { + continue each_type; + } + } + // now c is a uniquified element of tt1 + // count its occurrences in tt2 + int seen2 = 0; + for (int j = tt2.length; --j >= 0; ) + { + if (c == tt2[j]) + { + ++seen2; + } + } + if (seen2 == 0) + { + // c does not occur in tt2 + return false; + } + totalSeen2 += seen2; } // now, each element of tt2 must have been visited return totalSeen2 != tt2.length; - } - - static Class[] copyAndUniquify(Class targetTypes[]) { - int n = targetTypes.length; - Class tt[] = new Class[n]; - int k = 0; - each_type: - for (int i = 0; i < n; i++) { - Class c = targetTypes[i]; - for (int j = i; --j >= 0; ) { - if (c == targetTypes[j]) { - continue each_type; - } - } - tt[k++] = c; - } - if (k < n) { - // oops; caller passed in duplicate - Class tt0[] = new Class[k]; - for (int i = 0; i < k; i++) { - tt0[i] = tt[i]; - } - tt = tt0; + } + + static Class[] copyAndUniquify(Class targetTypes[]) + { + int n = targetTypes.length; + Class tt[] = new Class[n]; + int k = 0; + each_type: + for (int i = 0; i < n; i++) + { + Class c = targetTypes[i]; + for (int j = i; --j >= 0; ) + { + if (c == targetTypes[j]) + { + continue each_type; + } + } + tt[k++] = c; + } + if (k < n) + { + // oops; caller passed in duplicate + Class tt0[] = new Class[k]; + for (int i = 0; i < k; i++) + { + tt0[i] = tt[i]; + } + tt = tt0; } return tt; - } - - // make sure a give target type is acceptable - // return a list of eligible methods (may also include nulls) - Method[] checkTargetType(Class targetType) { - if (targetType.isArray()) { - throw new IllegalArgumentException - ("cannot subclass an array type: " - +targetType.getName()); - } - if (targetType.isPrimitive()) { - throw new IllegalArgumentException - ("cannot subclass a primitive type: " - +targetType); - } - int tmod = targetType.getModifiers(); - if (Modifier.isFinal(tmod)) { - throw new IllegalArgumentException - ("cannot subclass a final type: " - +targetType); - } - if (!Modifier.isPublic(tmod)) { - throw new IllegalArgumentException - ("cannot subclass a non-public type: " - +targetType); - } - - // Make sure the subclass will not need a "super" statement. - if (!targetType.isInterface()) { - if (!targetType.isAssignableFrom(superclass)) { - if (superclass.isAssignableFrom(targetType)) { - superclass = targetType; - } else { - throw new IllegalArgumentException - ("inconsistent superclass: " - +targetType); - } - } - } - - // Decide what overrideable methods this type supports. - Method methodList[] = targetType.getMethods(); - int nm = 0; - for (int i = 0; i < methodList.length; i++) { - Method m = methodList[i]; - if (eligibleForInvocationHandler(m)) { - methodList[nm++] = m; // (reuse the method array) - } - } - while (nm < methodList.length) { - methodList[nm++] = null; // (pad the reused method array) - } - - return methodList; - } - - void checkSuperclass() { - Constructor constructors[] = superclass.getConstructors(); - for (int i = 0; i < constructors.length; i++) { - Constructor c = constructors[i]; - int mod = c.getModifiers(); - if (Modifier.isPublic(mod) - && c.getParameterTypes().length == 0) { - return; // OK - } - } + } + + // make sure a give target type is acceptable + // return a list of eligible methods (may also include nulls) + Method[] checkTargetType(Class targetType) + { + if (targetType.isArray()) + { throw new IllegalArgumentException - ("cannot subclass without nullary constructor: " - +superclass.getName()); - } - - // tell if a given method will be passed by a proxy to its InvocationHandler - static boolean eligibleForInvocationHandler(Method m) { - - int mod = m.getModifiers(); - if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) { - // can't override these - return false; - } - if (!Modifier.isAbstract(mod)) { - // do not support methods with "super" - return false; - } - return true; - } - - static Method[] combineMethodLists(Method methodLists[][]) { - int nm = 0; - for (int i = 0; i < methodLists.length; i++) { - nm += methodLists[i].length; - } - Method methods[] = new Method[nm]; - - nm = 0; - for (int i = 0; i < methodLists.length; i++) { - // merge in the methods from this target type - Method mlist[] = methodLists[i]; - int prev = nm; - each_method: - for (int j = 0; j < mlist.length; j++) { - Method m = mlist[j]; - if (m == null) { - continue; - } - // make sure the same method hasn't already appeared - for (int k = 0; k < prev; k++) { - if (checkSameMethod(m, methods[k])) { - continue each_method; - } - } - methods[nm++] = m; - } - } - - // shorten and copy the array - Method methodsCopy[] = new Method[nm]; - for (int i = 0; i < nm; i++) { - methodsCopy[i] = methods[i]; - } - - return methodsCopy; - } - - // return true if they have the same name and signature - static boolean checkSameMethod(Method m1, Method m2) { - - if (!m1.getName().equals(m2.getName())) { - return false; - } - Class p1[] = m1.getParameterTypes(); - Class p2[] = m2.getParameterTypes(); - if (p1.length != p2.length) { - return false; - } - for (int i = 0; i < p1.length; i++) { - if (p1[i] != p2[i]) { - return false; - } - } - return true; - } - - Method[] copyMethods() { - try { - return (Method[]) methods.clone(); - } catch (IllegalArgumentException ee) { - return new Method[0]; - } - } - Class[] copyTargetTypes() { - try { - return (Class[]) targetTypes.clone(); - } catch (IllegalArgumentException ee) { - return new Class[0]; - } - } - - Impl(Class targetTypes[]) { - this.targetTypes = targetTypes; - - Method methodLists[][] = new Method[targetTypes.length][]; - for (int i = 0; i < targetTypes.length; i++) { - methodLists[i] = checkTargetType(targetTypes[i]); - } - checkSuperclass(); - this.methods = combineMethodLists(methodLists); - } - - - ProxyTarget newTarget(InvocationHandler InvocationHandler, ClassLoader parent) { - if (proxyConstructor == null) { - try { - makeProxyConstructor( parent ); // do class loader stuff - } catch (LinkageError ee) { - Logger.exception(ee); - throw new RuntimeException("unexpected: "+ee); - } - } - - try { - Object arg[] = { InvocationHandler }; - return (ProxyTarget) proxyConstructor.newInstance(arg); - } catch (InvocationTargetException ee) { - throw new RuntimeException("unexpected: "+ee); - } catch (InstantiationException ee) { - throw new RuntimeException("unexpected: "+ee); - } catch (IllegalAccessException ee) { - throw new RuntimeException("unexpected: "+ee); - } - } - - ProxyInvocationHandler newInvocationHandler(final Object target) { - if (proxyString == null) { - String s = "InvocationHandler@" + targetTypes[0].getName(); - for (int i = 1; i < targetTypes.length; i++) { - s += "," + targetTypes[i].getName(); - } - proxyString = s; - } - return new ProxyInvocationHandler() { - // (ISSUE: Should this be made subclassable?) - public Object getTarget() { - return target; - } - - public Class[] getTargetTypes() { - return copyTargetTypes(); - } - - public String toString() { - return proxyString + "[" + target + "]"; - } - - public Object invoke(Object dummy, Method method, Object values[]) - throws Throwable { - return Impl.this.invoke(target, method, values); - } - }; - } - - // the heart of a ProxyInvocationHandler: - Object invoke(Object target, Member method, Object values[]) - throws Throwable { - - // Note: We will not invoke the method unless we are expecting it. - // Thus, we cannot blindly call Method.invoke, but must first - // check our list of allowed methods. - - try { - Method methods[] = this.methods; // cache - - // use fast pointer equality (it usually succeeds) - for (int i = methods.length; --i >= 0; ) { - if (methods[i] == method) { - return methods[i].invoke(target, values); - } - } - - // special case: allow a null method to select the unique one - if (method == null) { - if (methods.length == 1) { - return methods[0].invoke(target, values); - } - throw new IllegalArgumentException("non-unique method"); - } - - // try the slower form of equality - for (int i = methods.length; --i >= 0; ) { - if (methods[i].equals(method)) { - return methods[i].invoke(target, values); - } - } - - } catch (IllegalAccessException ee) { - throw new IllegalArgumentException("method access "+method); - } catch (InvocationTargetException ee) { - Throwable te = ee.getTargetException(); - if (te instanceof Error) { - throw (Error)te; - } - if (te instanceof RuntimeException) { - throw (RuntimeException)te; - } - throw te; - } - - throw new IllegalArgumentException("method unexpected "+method); - } - - void makeProxyConstructor( ClassLoader parent ) { - ProxyCompiler pc = new ProxyCompiler(parent, superclass, - targetTypes, methods); - try { - Class type[] = { InvocationHandler.class }; - proxyConstructor = pc.getProxyType().getConstructor(type); - } catch (NoSuchMethodException ee) { - Logger.exception(ee); - throw new RuntimeException("unexpected: "+ee); - } - } - } + ("cannot subclass an array type: " + +targetType.getName()); + } + if (targetType.isPrimitive()) + { + throw new IllegalArgumentException + ("cannot subclass a primitive type: " + +targetType); + } + int tmod = targetType.getModifiers(); + if (Modifier.isFinal(tmod)) + { + throw new IllegalArgumentException + ("cannot subclass a final type: " + +targetType); + } + if (!Modifier.isPublic(tmod)) + { + throw new IllegalArgumentException + ("cannot subclass a non-public type: " + +targetType); + } + + // Make sure the subclass will not need a "super" statement. + if (!targetType.isInterface()) + { + if (!targetType.isAssignableFrom(superclass)) + { + if (superclass.isAssignableFrom(targetType)) + { + superclass = targetType; + } else + { + throw new IllegalArgumentException + ("inconsistent superclass: " + +targetType); + } + } + } + + // Decide what overrideable methods this type supports. + Method methodList[] = targetType.getMethods(); + int nm = 0; + for (int i = 0; i < methodList.length; i++) + { + Method m = methodList[i]; + if (eligibleForInvocationHandler(m)) + { + methodList[nm++] = m; // (reuse the method array) + } + } + while (nm < methodList.length) + { + methodList[nm++] = null; // (pad the reused method array) + } + + return methodList; + } + + void checkSuperclass() + { + Constructor constructors[] = superclass.getConstructors(); + for (int i = 0; i < constructors.length; i++) + { + Constructor c = constructors[i]; + int mod = c.getModifiers(); + if (Modifier.isPublic(mod) + && c.getParameterTypes().length == 0) + { + return; // OK + } + } + throw new IllegalArgumentException + ("cannot subclass without nullary constructor: " + +superclass.getName()); + } + + // tell if a given method will be passed by a proxy to its InvocationHandler + static boolean eligibleForInvocationHandler(Method m) + { + + int mod = m.getModifiers(); + if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) + { + // can't override these + return false; + } + if (!Modifier.isAbstract(mod)) + { + // do not support methods with "super" + return false; + } + return true; + } + + static Method[] combineMethodLists(Method methodLists[][]) + { + int nm = 0; + for (int i = 0; i < methodLists.length; i++) + { + nm += methodLists[i].length; + } + Method methods[] = new Method[nm]; + + nm = 0; + for (int i = 0; i < methodLists.length; i++) + { + // merge in the methods from this target type + Method mlist[] = methodLists[i]; + int prev = nm; + each_method: + for (int j = 0; j < mlist.length; j++) + { + Method m = mlist[j]; + if (m == null) + { + continue; + } + // make sure the same method hasn't already appeared + for (int k = 0; k < prev; k++) + { + if (checkSameMethod(m, methods[k])) + { + continue each_method; + } + } + methods[nm++] = m; + } + } + + // shorten and copy the array + Method methodsCopy[] = new Method[nm]; + for (int i = 0; i < nm; i++) + { + methodsCopy[i] = methods[i]; + } + + return methodsCopy; + } + + // return true if they have the same name and signature + static boolean checkSameMethod(Method m1, Method m2) + { + + if (!m1.getName().equals(m2.getName())) + { + return false; + } + Class p1[] = m1.getParameterTypes(); + Class p2[] = m2.getParameterTypes(); + if (p1.length != p2.length) + { + return false; + } + for (int i = 0; i < p1.length; i++) + { + if (p1[i] != p2[i]) + { + return false; + } + } + return true; + } + + Method[] copyMethods() + { + try + { + return (Method[]) methods.clone(); + } catch (IllegalArgumentException ee) + { + return new Method[0]; + } + } + Class[] copyTargetTypes() + { + try + { + return (Class[]) targetTypes.clone(); + } catch (IllegalArgumentException ee) + { + return new Class[0]; + } + } + + Impl(Class targetTypes[]) + { + this.targetTypes = targetTypes; + + Method methodLists[][] = new Method[targetTypes.length][]; + for (int i = 0; i < targetTypes.length; i++) + { + methodLists[i] = checkTargetType(targetTypes[i]); + } + checkSuperclass(); + this.methods = combineMethodLists(methodLists); + } + + + ProxyTarget newTarget(InvocationHandler InvocationHandler, ClassLoader parent) + { + if (proxyConstructor == null) + { + try + { + makeProxyConstructor( parent ); // do class loader stuff + } catch (LinkageError ee) + { + log.error("unexpected error", ee); + throw new RuntimeException("unexpected: "+ee); + } + } + + try + { + Object arg[] = + { InvocationHandler }; + return (ProxyTarget) proxyConstructor.newInstance(arg); + } catch (InvocationTargetException ee) + { + throw new RuntimeException("unexpected: "+ee); + } catch (InstantiationException ee) + { + throw new RuntimeException("unexpected: "+ee); + } catch (IllegalAccessException ee) + { + throw new RuntimeException("unexpected: "+ee); + } + } + + ProxyInvocationHandler newInvocationHandler(final Object target) + { + if (proxyString == null) + { + String s = "InvocationHandler@" + targetTypes[0].getName(); + for (int i = 1; i < targetTypes.length; i++) + { + s += "," + targetTypes[i].getName(); + } + proxyString = s; + } + return new ProxyInvocationHandler() + { + // (ISSUE: Should this be made subclassable?) + public Object getTarget() + { + return target; + } + + public Class[] getTargetTypes() + { + return copyTargetTypes(); + } + + public String toString() + { + return proxyString + "[" + target + "]"; + } + + public Object invoke(Object dummy, Method method, Object values[]) + throws Throwable + { + return Impl.this.invoke(target, method, values); + } + }; + } + + // the heart of a ProxyInvocationHandler: + Object invoke(Object target, Member method, Object values[]) + throws Throwable + { + + // Note: We will not invoke the method unless we are expecting it. + // Thus, we cannot blindly call Method.invoke, but must first + // check our list of allowed methods. + + try + { + Method methods[] = this.methods; // cache + + // use fast pointer equality (it usually succeeds) + for (int i = methods.length; --i >= 0; ) + { + if (methods[i] == method) + { + return methods[i].invoke(target, values); + } + } + + // special case: allow a null method to select the unique one + if (method == null) + { + if (methods.length == 1) + { + return methods[0].invoke(target, values); + } + throw new IllegalArgumentException("non-unique method"); + } + + // try the slower form of equality + for (int i = methods.length; --i >= 0; ) + { + if (methods[i].equals(method)) + { + return methods[i].invoke(target, values); + } + } + + } catch (IllegalAccessException ee) + { + throw new IllegalArgumentException("method access "+method); + } catch (InvocationTargetException ee) + { + Throwable te = ee.getTargetException(); + if (te instanceof Error) + { + throw (Error)te; + } + if (te instanceof RuntimeException) + { + throw (RuntimeException)te; + } + throw te; + } + + throw new IllegalArgumentException("method unexpected "+method); + } + + void makeProxyConstructor( ClassLoader parent ) + { + ProxyCompiler pc = new ProxyCompiler(parent, superclass, + targetTypes, methods); + try + { + Class type[] = + { InvocationHandler.class }; + proxyConstructor = pc.getProxyType().getConstructor(type); + } catch (NoSuchMethodException ee) + { + log.error("unexpected error", ee); + throw new RuntimeException("unexpected: "+ee); + } + } + } } 1.2.6.1 +61 -125 jboss/src/main/org/jboss/proxy/ProxyProxy.java Index: ProxyProxy.java =================================================================== RCS file: /cvsroot/jboss/jboss/src/main/org/jboss/proxy/ProxyProxy.java,v retrieving revision 1.2 retrieving revision 1.2.6.1 diff -u -r1.2 -r1.2.6.1 --- ProxyProxy.java 2000/08/18 03:21:09 1.2 +++ ProxyProxy.java 2001/11/20 09:42:55 1.2.6.1 @@ -1,141 +1,77 @@ package org.jboss.proxy; - import java.io.*; - import javax.ejb.EJBHome; - import javax.ejb.Handle; - import javax.ejb.EJBObject; - import org.jboss.logging.Logger; public class ProxyProxy implements Serializable, EJBObject - { - - InvocationHandler handler; - - String[] targetNames; - - - - public ProxyProxy( InvocationHandler handler, Class[] targetTypes ) - - { - this.handler = handler; - - targetNames = new String[ targetTypes.length ]; - - for (int iter=0; iter<targetTypes.length; iter++) - - { - - targetNames[iter] = targetTypes[iter].getName(); - - } - - } - - - - private Class[] getClasses() - - { - - try - - { - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - Class[] classes = new Class[targetNames.length]; - - for (int iter=0; iter<targetNames.length; iter++) - + static Logger log = Logger.getLogger(ProxyProxy.class); + InvocationHandler handler; + String[] targetNames; + + + public ProxyProxy( InvocationHandler handler, Class[] targetTypes ) + { + this.handler = handler; + targetNames = new String[ targetTypes.length ]; + for (int iter=0; iter<targetTypes.length; iter++) { - - classes[iter] = cl.loadClass( targetNames[iter] ); - + targetNames[iter] = targetTypes[iter].getName(); } - - return classes; - - } - - catch (Exception e) - - { - - Logger.exception(e); - - return null; - - } - - } - - - - public Object readResolve() throws ObjectStreamException + } - { - return Proxy.newProxyInstance( Thread.currentThread().getContextClassLoader(), - getClasses(), handler ); - - } - - - - public EJBHome getEJBHome() throws java.rmi.RemoteException - - { - - throw new UnsupportedOperationException(); - - } - - - - public Handle getHandle() throws java.rmi.RemoteException - - { - - throw new UnsupportedOperationException(); - - } - - - - public Object getPrimaryKey() throws java.rmi.RemoteException - - { - - throw new UnsupportedOperationException(); - - } - - - - public boolean isIdentical(EJBObject parm1) throws java.rmi.RemoteException - - { - - throw new UnsupportedOperationException(); - - } - - - - public void remove() throws java.rmi.RemoteException, javax.ejb.RemoveException - - { - - throw new UnsupportedOperationException(); - - } + private Class[] getClasses() + { + try + { + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + Class[] classes = new Class[targetNames.length]; + for (int iter=0; iter<targetNames.length; iter++) + { + classes[iter] = cl.loadClass( targetNames[iter] ); + } + return classes; + } + catch (Exception e) + { + log.error("getClasses", e); + return null; + } + } + public Object readResolve() throws ObjectStreamException + { + return Proxy.newProxyInstance( Thread.currentThread().getContextClassLoader(), + getClasses(), handler ); + } + + public EJBHome getEJBHome() throws java.rmi.RemoteException + { + throw new UnsupportedOperationException(); + } + + public Handle getHandle() throws java.rmi.RemoteException + { + throw new UnsupportedOperationException(); + } + + public Object getPrimaryKey() throws java.rmi.RemoteException + { + throw new UnsupportedOperationException(); + } + + public boolean isIdentical(EJBObject parm1) throws java.rmi.RemoteException + { + throw new UnsupportedOperationException(); + } + + public void remove() throws java.rmi.RemoteException, javax.ejb.RemoveException + { + throw new UnsupportedOperationException(); + } + } - - -
_______________________________________________ Jboss-development mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/jboss-development