User: fleury  
  Date: 00/08/17 20:21:10

  Modified:    src/main/org/jboss/proxy Proxies.java Proxy.java
                        ProxyCompiler.java ProxyProxy.java
  Log:
  Logger messages and clean up for binary
  
  Revision  Changes    Path
  1.2       +535 -534  jboss/src/main/org/jboss/proxy/Proxies.java
  
  Index: Proxies.java
  ===================================================================
  RCS file: /products/cvs/ejboss/jboss/src/main/org/jboss/proxy/Proxies.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- Proxies.java      2000/05/14 07:26:17     1.1
  +++ Proxies.java      2000/08/18 03:21:09     1.2
  @@ -3,573 +3,574 @@
   import java.lang.reflect.*;
   import java.io.*;
   
  +import org.jboss.logging.Logger;
   /**
  - * Routines for converting between strongly-typed interfaces and
  - * generic InvocationHandler objects.
  - */
  +* Routines for converting between strongly-typed interfaces and
  +* generic InvocationHandler objects.
  +*/
   public final class Proxies {
       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
  -     * invocation, in place of the <tt>InvocationHandler.invoke</tt> protocol,
  -     * for each method supported by the InvocationHandler.
  -     * <p>
  -     * The new object will implement each of the given target types.
  -     * (The target types default to those declared by the InvocationHandler itself.)
  -     * The new object will also implement the "administrative" interface
  -     * <tt>Proxies.ProxyTarget</tt>.
  -     * <p>
  -     * For each "overrideable" (public, non-static, non-final)
  -     * method <tt>T.m</tt> of <tt>T</tt>, calling <tt>x.m(...)</tt>
  -     * will immediately cause a corresponding reflective call of the
  -     * form <tt>disp.invoke(RM, new Object[]{ ... })</tt>, where <tt>RM</tt>
  -     * is the reflective object for <tt>m</tt>.
  -     * <p>
  -     * The concrete class of this target object will be
  -     * something mysterious and indefinite.  Many callers will
  -     * immediately cast the resulting proxy object to the target type
  -     * of the InvocationHandler.  For example:
  -     * <code>
  -     * MyInterface x1 = ...;
  -     * InvocationHandler i = Proxies.newInvocationHandler(x1, MyInterface.class);
  -     * MyInterface x2 = (MyInterface) 
((Proxies.ProxyInvocationHandler)i).getTarget();
  -     *   // x1 == x2
  -     * MyInterface x3 = (MyInterface) Proxies.newTarget(i);
  -     *   // x1 != x3, but calls to x3 are forwarded via i to x1
  -     * </code>
  -     */
  +    * 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
  +    * invocation, in place of the <tt>InvocationHandler.invoke</tt> protocol,
  +    * for each method supported by the InvocationHandler.
  +    * <p>
  +    * The new object will implement each of the given target types.
  +    * (The target types default to those declared by the InvocationHandler itself.)
  +    * The new object will also implement the "administrative" interface
  +    * <tt>Proxies.ProxyTarget</tt>.
  +    * <p>
  +    * For each "overrideable" (public, non-static, non-final)
  +    * method <tt>T.m</tt> of <tt>T</tt>, calling <tt>x.m(...)</tt>
  +    * will immediately cause a corresponding reflective call of the
  +    * form <tt>disp.invoke(RM, new Object[]{ ... })</tt>, where <tt>RM</tt>
  +    * is the reflective object for <tt>m</tt>.
  +    * <p>
  +    * The concrete class of this target object will be
  +    * something mysterious and indefinite.  Many callers will
  +    * immediately cast the resulting proxy object to the target type
  +    * of the InvocationHandler.  For example:
  +    * <code>
  +    * MyInterface x1 = ...;
  +    * InvocationHandler i = Proxies.newInvocationHandler(x1, MyInterface.class);
  +    * MyInterface x2 = (MyInterface) 
((Proxies.ProxyInvocationHandler)i).getTarget();
  +    *   // x1 == x2
  +    * MyInterface x3 = (MyInterface) Proxies.newTarget(i);
  +    *   // 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);
  +        return Impl.getImpl(targetTypes).newTarget(InvocationHandler, parent);
       }
       /*public static ProxyTarget newTarget(InvocationHandler InvocationHandler) {
  -     return newTarget(InvocationHandler, InvocationHandler.getTargetTypes());
  +    return newTarget(InvocationHandler, InvocationHandler.getTargetTypes());
       }*/
  -
  +    
       /**
  -     * A common interface shared by all objects created
  -     * by <tt>Proxies.newTarget</tt>.
  -     */
  -
  +    * 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();
  +        /**
  +        * 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>
  -     * The new object will be operationally equivalent to
  -     * <tt>target</tt>, except that it will support a reflective method
  -     * invocation sequence (<tt>InvocationHandler.invoke</tt>) instead of the normal
  -     * Java method invocation mechanism.
  -     * <p>
  -     * The target type must be specified, since the complete implementation
  -     * type of the target object is usually irrelevant to the application.
  -     * The target object must match the specified target type.
  -     * For example:
  -     * <code>
  -     * MyInterface x1 = ...;
  -     * InvocationHandler i = Proxies.newInvocationHandler(x1, MyInterface.class);
  -     * </code>
  -     */
  +    * Create a new reflective InvocationHandler object <tt>InvocationHandler</tt> 
wrapped
  +    * around the given target object, for the given target type(s).
  +    * <p>
  +    * The new object will be operationally equivalent to
  +    * <tt>target</tt>, except that it will support a reflective method
  +    * invocation sequence (<tt>InvocationHandler.invoke</tt>) instead of the normal
  +    * Java method invocation mechanism.
  +    * <p>
  +    * The target type must be specified, since the complete implementation
  +    * type of the target object is usually irrelevant to the application.
  +    * The target object must match the specified target type.
  +    * For example:
  +    * <code>
  +    * MyInterface x1 = ...;
  +    * InvocationHandler i = Proxies.newInvocationHandler(x1, MyInterface.class);
  +    * </code>
  +    */
       public static ProxyInvocationHandler newInvocationHandler(Object target, Class 
targetType) {
  -     return Impl.getImpl(targetType).newInvocationHandler(target);
  +        return Impl.getImpl(targetType).newInvocationHandler(target);
       }
       public static ProxyInvocationHandler newInvocationHandler(Object target, Class 
targetTypes[]) {
  -     return Impl.getImpl(targetTypes).newInvocationHandler(target);
  +        return Impl.getImpl(targetTypes).newInvocationHandler(target);
       }
  -
  +    
       /**
  -     * A common interface shared by all objects created
  -     * by <tt>Proxies.newInvocationHandler</tt>.
  -     */
  +    * 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();
  +        /**
  +        * 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>.
  -     * <p>
  -     * If the InvocationHandler implements <tt>ProxyInvocationHandler</tt>, it is a 
proxy
  -     * for some original target object; extract and return that object.
  -     * Otherwise, just call <tt>newTarget</tt>.
  -     */
  +    * 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>.
  +    * <p>
  +    * If the InvocationHandler implements <tt>ProxyInvocationHandler</tt>, it is a 
proxy
  +    * for some original target object; extract and return that object.
  +    * Otherwise, just call <tt>newTarget</tt>.
  +    */
       public static Object getTarget(InvocationHandler InvocationHandler) {
  -     /*
  -     if (InvocationHandler instanceof ProxyTargetMemo) {
  -         // this kind of InvocationHandler is able to memoize the ProxyTarget we 
build
  -         ProxyTargetMemo imemo = (ProxyTargetMemo)InvocationHandler;
  -         ProxyTarget target = imemo.getProxyTarget();
  -         if (target == null) {
  -             target = newTarget(imemo);
  -             imemo.setProxyTarget(target);
  -         }
  -         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 ProxyTargetMemo) {
  +        // this kind of InvocationHandler is able to memoize the ProxyTarget we 
build
  +        ProxyTargetMemo imemo = (ProxyTargetMemo)InvocationHandler;
  +        ProxyTarget target = imemo.getProxyTarget();
  +        if (target == null) {
  +        target = newTarget(imemo);
  +        imemo.setProxyTarget(target);
  +        }
  +        return target;
  +        }
  +        */
  +        
  +        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>.
  -     * <p>
  -     * If the target implements <tt>ProxyTarget</tt>, it is a proxy
  -     * for some original InvocationHandler; extract and return that 
InvocationHandler.
  -     * Otherwise, just call <tt>newInvocationHandler</tt>.
  -     * @see #newInvocationHandler
  -     */
  +    * 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>.
  +    * <p>
  +    * If the target implements <tt>ProxyTarget</tt>, it is a proxy
  +    * for some original InvocationHandler; extract and return that 
InvocationHandler.
  +    * 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);
  +        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 });
  +        // (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
  -     * <tt>static</tt> nor <tt>final</tt>.
  -     * <p>
  -     * Also, if the targetType is not a suitable type, an empty array
  -     * will be returned.  The target type must not contain <tt>protected</tt>
  -     * <tt>abstract</tt> methods, must have a nullary constructor,
  -     * and must not be something silly like
  -     * an array or primitive type, or a <tt>final</tt> class.
  -     */
  +    * 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
  +    * <tt>static</tt> nor <tt>final</tt>.
  +    * <p>
  +    * Also, if the targetType is not a suitable type, an empty array
  +    * will be returned.  The target type must not contain <tt>protected</tt>
  +    * <tt>abstract</tt> methods, must have a nullary constructor,
  +    * 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();
  +        return Impl.getImpl(targetType).copyMethods();
       }
       public static Method[] getMethods(Class targetTypes[]) {
  -     return Impl.getImpl(targetTypes).copyMethods();
  +        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;
  -         }
  -         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
  -             }
  -         }
  -         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) {
  -             ee.printStackTrace();
  -                 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) {
  -    ee.printStackTrace();
  -             throw new RuntimeException("unexpected: "+ee);
  -         }
  -     }
  +        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;
  +            }
  +            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
  +                }
  +            }
  +            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);
  +            }
  +        }
       }
   }
  
  
  
  1.2       +1 -1      jboss/src/main/org/jboss/proxy/Proxy.java
  
  Index: Proxy.java
  ===================================================================
  RCS file: /products/cvs/ejboss/jboss/src/main/org/jboss/proxy/Proxy.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- Proxy.java        2000/05/14 07:26:17     1.1
  +++ Proxy.java        2000/08/18 03:21:09     1.2
  @@ -1,6 +1,6 @@
   package org.jboss.proxy;
   
  -
  +import org.jboss.logging.Logger;
   
   public class Proxy
   
  
  
  
  1.2       +1 -1      jboss/src/main/org/jboss/proxy/ProxyCompiler.java
  
  Index: ProxyCompiler.java
  ===================================================================
  RCS file: /products/cvs/ejboss/jboss/src/main/org/jboss/proxy/ProxyCompiler.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ProxyCompiler.java        2000/05/14 07:26:17     1.1
  +++ ProxyCompiler.java        2000/08/18 03:21:09     1.2
  @@ -153,7 +153,7 @@
                java.io.OutputStream cf = new java.io.FileOutputStream(fname);
                cf.write(code);
                cf.close();
  -             System.out.println("wrote "+fname);
  +             Logger.log("wrote "+fname);
            } catch(java.io.IOException ee) { }
            //* ---- ---- */
   
  
  
  
  1.2       +2 -2      jboss/src/main/org/jboss/proxy/ProxyProxy.java
  
  Index: ProxyProxy.java
  ===================================================================
  RCS file: /products/cvs/ejboss/jboss/src/main/org/jboss/proxy/ProxyProxy.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ProxyProxy.java   2000/05/14 07:26:18     1.1
  +++ ProxyProxy.java   2000/08/18 03:21:09     1.2
  @@ -10,8 +10,8 @@
   
   import javax.ejb.EJBObject;
   
  +import org.jboss.logging.Logger;
   
  -
   public class ProxyProxy implements Serializable, EJBObject
   
   {
  @@ -67,7 +67,7 @@
   
       {
   
  -      e.printStackTrace();
  +      Logger.exception(e);
   
         return null;
   
  
  
  

Reply via email to