View Javadoc
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