1   /*
2    * The Apache Software License, Version 1.1
3    *
4    * Copyright (c) 2002 The Apache Software Foundation.  All rights
5    * reserved.
6    *
7    * Redistribution and use in source and binary forms, with or without
8    * modification, are permitted provided that the following conditions
9    * are met:
10   *
11   * 1. Redistributions of source code must retain the above copyright
12   *    notice, this list of conditions and the following disclaimer.
13   *
14   * 2. Redistributions in binary form must reproduce the above copyright
15   *    notice, this list of conditions and the following disclaimer in
16   *    the documentation and/or other materials provided with the
17   *    distribution.
18   *
19   * 3. The end-user documentation included with the redistribution,
20   *    if any, must include the following acknowledgment:
21   *       "This product includes software developed by the
22   *        Apache Software Foundation (http://www.apache.org/)."
23   *    Alternately, this acknowledgment may appear in the software itself,
24   *    if and wherever such third-party acknowledgments normally appear.
25   *
26   * 4. The names "Apache" and "Apache Software Foundation" must
27   *    not be used to endorse or promote products derived from this
28   *    software without prior written permission. For written
29   *    permission, please contact apache@apache.org.
30   *
31   * 5. Products derived from this software may not be called "Apache",
32   *    nor may "Apache" appear in their name, without prior written
33   *    permission of the Apache Software Foundation.
34   *
35   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
36   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
37   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
39   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
42   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
44   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
45   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46   * SUCH DAMAGE.
47   * ====================================================================
48   *
49   * This software consists of voluntary contributions made by many
50   * individuals on behalf of the Apache Software Foundation.  For more
51   * information on the Apache Software Foundation, please see
52   * <http://www.apache.org/>.
53   */
54  package net.sf.cglib.proxy;
55  
56  import java.lang.reflect.*;
57  import java.util.Arrays;
58  import java.util.List;
59  import net.sf.cglib.core.CodeGenerationException;
60  import net.sf.cglib.core.ReflectUtils;
61  import net.sf.cglib.core.Signature;
62  import net.sf.cglib.reflect.*;
63  
64  /***
65   * Classes generated by {@link Enhancer} pass this object to the
66   * registered {@link MethodInterceptor} objects when an intercepted method is invoked. It can
67   * be used to either invoke the original method, or call the same method on a different
68   * object of the same type.
69   * @version $Id: MethodProxy.java,v 1.9 2003/12/07 00:54:36 herbyderby Exp $
70   */
71  public class MethodProxy {
72      private Signature sig;
73      private String superName;
74      private FastClass f1;
75      private FastClass f2;
76      private int i1;
77      private int i2;
78  
79      /***
80       * For internal use by {@link Enhancer} only; see the {@link net.sf.cglib.reflect.FastMethod} class
81       * for similar functionality.
82       */
83      public static MethodProxy create(ClassLoader loader, Class c1, Class c2, String desc, String name1, String name2) {
84          final Signature sig1 = new Signature(name1, desc);
85          Signature sig2 = new Signature(name2, desc);
86          FastClass f1 = helper(loader, c1);
87          FastClass f2 = helper(loader, c2);
88          int i1 = f1.getIndex(sig1);
89          int i2 = f2.getIndex(sig2);
90  
91          MethodProxy proxy;
92          if (i1 < 0) {
93              proxy = new MethodProxy() {
94                  public Object invoke(Object obj, Object[] args) throws Throwable {
95                      throw new IllegalArgumentException("Protected method: " + sig1);
96                  }
97              };
98          } else {
99              proxy = new MethodProxy();
100         }
101 
102         proxy.f1 = f1;
103         proxy.f2 = f2;
104         proxy.i1 = i1;
105         proxy.i2 = i2;
106         proxy.sig = sig1;
107         proxy.superName = name2;
108         return proxy;
109     }
110 
111     private static FastClass helper(ClassLoader loader, Class type) {
112         FastClass.Generator g = new FastClass.Generator();
113         g.setType(type);
114         g.setClassLoader(loader);
115         return g.create();
116     }
117 
118     private MethodProxy() {
119     }
120 
121     /***
122      * Return the signature of the proxied method.
123      */
124     public Signature getSignature() {
125         return sig;
126     }
127 
128     /***
129      * Return the name of the synthetic method created by CGLIB which is
130      * used by {@link #invokeSuper} to invoke the superclass
131      * (non-intercepted) method implementation. The parameter types are
132      * the same as the proxied method.
133      */
134     public String getSuperName() {
135         return superName;
136     }
137 
138     /***
139      * Return the {@link net.sf.cglib.reflect.FastClass} method index
140      * for the method used by {@link #invokeSuper}. This index uniquely
141      * identifies the method within the generated proxy, and therefore
142      * can be useful to reference external metadata.
143      * @see #getSuperName
144      */
145     public int getSuperIndex() {
146         return i2;
147     }
148 
149     /***
150      * Return the <code>MethodProxy</code> used when intercepting the method
151      * matching the given signature.
152      * @param type the class generated by Enhancer
153      * @param sig the signature to match
154      * @return the MethodProxy instance, or null if no applicable matching method is found
155      * @throws IllegalArgumentException if the Class was not created by Enhancer or does not use a MethodInterceptor
156      */
157     public static MethodProxy find(Class type, Signature sig) {
158         try {
159             Method m = type.getDeclaredMethod(MethodInterceptorGenerator.FIND_PROXY_NAME,
160                                               MethodInterceptorGenerator.FIND_PROXY_TYPES);
161             return (MethodProxy)m.invoke(null, new Object[]{ sig });
162         } catch (NoSuchMethodException e) {
163             throw new IllegalArgumentException("Class " + type + " does not use a MethodInterceptor");
164         } catch (IllegalAccessException e) {
165             throw new CodeGenerationException(e);
166         } catch (InvocationTargetException e) {
167             throw new CodeGenerationException(e);
168         }
169     }
170 
171     /***
172      * Invoke the original method, on a different object of the same type.
173      * @param obj the compatible object; recursion will result if you use the object passed as the first
174      * argument to the MethodInterceptor (usually not what you want)
175      * @param args the arguments passed to the intercepted method; you may substitute a different
176      * argument array as long as the types are compatible
177      * @see MethodInterceptor#intercept
178      * @throws Throwable the bare exceptions thrown by the called method are passed through
179      * without wrapping in an <code>InvocationTargetException</code>
180      */
181     public Object invoke(Object obj, Object[] args) throws Throwable {
182         try {
183             return f1.invoke(i1, obj, args);
184         } catch (InvocationTargetException e) {
185             throw e.getTargetException();
186         }
187     }
188 
189     /***
190      * Invoke the original (super) method on the specified object.
191      * @param obj the enhanced object, must be the object passed as the first
192      * argument to the MethodInterceptor
193      * @param args the arguments passed to the intercepted method; you may substitute a different
194      * argument array as long as the types are compatible
195      * @see MethodInterceptor#intercept
196      * @throws Throwable the bare exceptions thrown by the called method are passed through
197      * without wrapping in an <code>InvocationTargetException</code>
198      */
199     public Object invokeSuper(Object obj, Object[] args) throws Throwable {
200         try {
201             return f2.invoke(i2, obj, args);
202         } catch (InvocationTargetException e) {
203             throw e.getTargetException();
204         }
205     }
206 }
This page was automatically generated by Maven