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

Reply via email to