KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > cglib > proxy > MethodProxy


1 /*
2  * Copyright 2003,2004 The Apache Software Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package net.sf.cglib.proxy;
17
18 import java.lang.reflect.*;
19 import java.util.Arrays JavaDoc;
20 import java.util.List JavaDoc;
21 import net.sf.cglib.core.*;
22 import net.sf.cglib.reflect.*;
23
24 /**
25  * Classes generated by {@link Enhancer} pass this object to the
26  * registered {@link MethodInterceptor} objects when an intercepted method is invoked. It can
27  * be used to either invoke the original method, or call the same method on a different
28  * object of the same type.
29  * @version $Id: MethodProxy.java,v 1.13 2006/01/11 21:47:43 herbyderby Exp $
30  */

31 public class MethodProxy {
32     private Signature sig1;
33     private Signature sig2;
34     private CreateInfo createInfo;
35     private FastClass f1;
36     private FastClass f2;
37     private int i1;
38     private int i2;
39
40     /**
41      * For internal use by {@link Enhancer} only; see the {@link net.sf.cglib.reflect.FastMethod} class
42      * for similar functionality.
43      */

44     public static MethodProxy create(Class JavaDoc c1, Class JavaDoc c2, String JavaDoc desc, String JavaDoc name1, String JavaDoc name2) {
45         MethodProxy proxy = new MethodProxy();
46         proxy.sig1 = new Signature(name1, desc);
47         proxy.sig2 = new Signature(name2, desc);
48         proxy.createInfo = new CreateInfo(c1, c2);
49         return proxy;
50     }
51
52     private void init()
53     {
54         CreateInfo ci = createInfo;
55         if (ci != null) {
56             f1 = helper(ci, ci.c1);
57             f2 = helper(ci, ci.c2);
58             i1 = f1.getIndex(sig1);
59             i2 = f2.getIndex(sig2);
60             createInfo = null;
61         }
62     }
63
64     private static class CreateInfo
65     {
66         Class JavaDoc c1;
67         Class JavaDoc c2;
68         NamingPolicy namingPolicy;
69         GeneratorStrategy strategy;
70         boolean attemptLoad;
71         
72         public CreateInfo(Class JavaDoc c1, Class JavaDoc c2)
73         {
74             this.c1 = c1;
75             this.c2 = c2;
76             AbstractClassGenerator fromEnhancer = AbstractClassGenerator.getCurrent();
77             if (fromEnhancer != null) {
78                 namingPolicy = fromEnhancer.getNamingPolicy();
79                 strategy = fromEnhancer.getStrategy();
80                 attemptLoad = fromEnhancer.getAttemptLoad();
81             }
82         }
83     }
84
85     private static FastClass helper(CreateInfo ci, Class JavaDoc type) {
86         FastClass.Generator g = new FastClass.Generator();
87         g.setType(type);
88         g.setClassLoader(ci.c2.getClassLoader());
89         g.setNamingPolicy(ci.namingPolicy);
90         g.setStrategy(ci.strategy);
91         g.setAttemptLoad(ci.attemptLoad);
92         return g.create();
93     }
94
95     private MethodProxy() {
96     }
97
98     /**
99      * Return the signature of the proxied method.
100      */

101     public Signature getSignature() {
102         return sig1;
103     }
104
105     /**
106      * Return the name of the synthetic method created by CGLIB which is
107      * used by {@link #invokeSuper} to invoke the superclass
108      * (non-intercepted) method implementation. The parameter types are
109      * the same as the proxied method.
110      */

111     public String JavaDoc getSuperName() {
112         return sig2.getName();
113     }
114
115     /**
116      * Return the {@link net.sf.cglib.reflect.FastClass} method index
117      * for the method used by {@link #invokeSuper}. This index uniquely
118      * identifies the method within the generated proxy, and therefore
119      * can be useful to reference external metadata.
120      * @see #getSuperName
121      */

122     public int getSuperIndex() {
123         init();
124         return i2;
125     }
126
127     /**
128      * Return the <code>MethodProxy</code> used when intercepting the method
129      * matching the given signature.
130      * @param type the class generated by Enhancer
131      * @param sig the signature to match
132      * @return the MethodProxy instance, or null if no applicable matching method is found
133      * @throws IllegalArgumentException if the Class was not created by Enhancer or does not use a MethodInterceptor
134      */

135     public static MethodProxy find(Class JavaDoc type, Signature sig) {
136         try {
137             Method m = type.getDeclaredMethod(MethodInterceptorGenerator.FIND_PROXY_NAME,
138                                               MethodInterceptorGenerator.FIND_PROXY_TYPES);
139             return (MethodProxy)m.invoke(null, new Object JavaDoc[]{ sig });
140         } catch (NoSuchMethodException JavaDoc e) {
141             throw new IllegalArgumentException JavaDoc("Class " + type + " does not use a MethodInterceptor");
142         } catch (IllegalAccessException JavaDoc e) {
143             throw new CodeGenerationException(e);
144         } catch (InvocationTargetException e) {
145             throw new CodeGenerationException(e);
146         }
147     }
148
149     /**
150      * Invoke the original method, on a different object of the same type.
151      * @param obj the compatible object; recursion will result if you use the object passed as the first
152      * argument to the MethodInterceptor (usually not what you want)
153      * @param args the arguments passed to the intercepted method; you may substitute a different
154      * argument array as long as the types are compatible
155      * @see MethodInterceptor#intercept
156      * @throws Throwable the bare exceptions thrown by the called method are passed through
157      * without wrapping in an <code>InvocationTargetException</code>
158      */

159     public Object JavaDoc invoke(Object JavaDoc obj, Object JavaDoc[] args) throws Throwable JavaDoc {
160         try {
161             if (f1 == null)
162                 init();
163             return f1.invoke(i1, obj, args);
164         } catch (InvocationTargetException e) {
165             throw e.getTargetException();
166         } catch (IllegalArgumentException JavaDoc e) {
167             if (i1 < 0)
168                 throw new IllegalArgumentException JavaDoc("Protected method: " + sig1);
169             throw e;
170         }
171     }
172
173     /**
174      * Invoke the original (super) method on the specified object.
175      * @param obj the enhanced object, must be the object passed as the first
176      * argument to the MethodInterceptor
177      * @param args the arguments passed to the intercepted method; you may substitute a different
178      * argument array as long as the types are compatible
179      * @see MethodInterceptor#intercept
180      * @throws Throwable the bare exceptions thrown by the called method are passed through
181      * without wrapping in an <code>InvocationTargetException</code>
182      */

183     public Object JavaDoc invokeSuper(Object JavaDoc obj, Object JavaDoc[] args) throws Throwable JavaDoc {
184         try {
185             if (f2 == null)
186                 init();
187             return f2.invoke(i2, obj, args);
188         } catch (InvocationTargetException e) {
189             throw e.getTargetException();
190         }
191     }
192 }
193
Popular Tags