KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > logicalcobwebs > cglib > proxy > MethodProxy


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 org.logicalcobwebs.cglib.proxy;
55
56 import java.lang.reflect.*;
57 import java.util.Arrays JavaDoc;
58 import java.util.List JavaDoc;
59 import org.logicalcobwebs.cglib.core.CodeGenerationException;
60 import org.logicalcobwebs.cglib.core.ReflectUtils;
61 import org.logicalcobwebs.cglib.core.Signature;
62 import org.logicalcobwebs.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.1 2003/12/12 19:28:11 billhorsman Exp $
70  */

71 public class MethodProxy {
72     private Signature sig;
73     private String JavaDoc 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 org.logicalcobwebs.cglib.reflect.FastMethod} class
81      * for similar functionality.
82      */

83     public static MethodProxy create(ClassLoader JavaDoc loader, Class JavaDoc c1, Class JavaDoc c2, String JavaDoc desc, String JavaDoc name1, String JavaDoc 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 JavaDoc invoke(Object JavaDoc obj, Object JavaDoc[] args) throws Throwable JavaDoc {
95                     throw new IllegalArgumentException JavaDoc("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 JavaDoc loader, Class JavaDoc 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 JavaDoc getSuperName() {
135         return superName;
136     }
137
138     /**
139      * Return the {@link org.logicalcobwebs.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 JavaDoc 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 JavaDoc[]{ sig });
162         } catch (NoSuchMethodException JavaDoc e) {
163             throw new IllegalArgumentException JavaDoc("Class " + type + " does not use a MethodInterceptor");
164         } catch (IllegalAccessException JavaDoc 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 JavaDoc invoke(Object JavaDoc obj, Object JavaDoc[] args) throws Throwable JavaDoc {
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 JavaDoc invokeSuper(Object JavaDoc obj, Object JavaDoc[] args) throws Throwable JavaDoc {
200         try {
201             return f2.invoke(i2, obj, args);
202         } catch (InvocationTargetException e) {
203             throw e.getTargetException();
204         }
205     }
206 }
207
Popular Tags