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