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