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; 55 56 import java.lang.reflect.*; 57 import java.util.*; 58 import net.sf.cglib.core.*; 59 import org.objectweb.asm.Label; 60 import org.objectweb.asm.Type; 61 62 class MethodInterceptorGenerator 63 implements CallbackGenerator 64 { 65 public static final MethodInterceptorGenerator INSTANCE = new MethodInterceptorGenerator(); 66 67 private static final Type ABSTRACT_METHOD_ERROR = 68 TypeUtils.parseType("AbstractMethodError"); 69 private static final Type METHOD = 70 TypeUtils.parseType("java.lang.reflect.Method"); 71 private static final Type METHOD_PROXY = 72 TypeUtils.parseType("net.sf.cglib.MethodProxy"); 73 private static final Type METHOD_INTERCEPTOR = 74 TypeUtils.parseType("net.sf.cglib.MethodInterceptor"); 75 private static final Signature GET_DECLARING_CLASS = 76 TypeUtils.parseSignature("Class getDeclaringClass()"); 77 private static final Signature GET_CLASS_LOADER = 78 TypeUtils.parseSignature("ClassLoader getClassLoader()"); 79 private static final Signature MAKE_PROXY = 80 TypeUtils.parseSignature("net.sf.cglib.MethodProxy create(ClassLoader ,Class, String, Class, String)"); 81 private static final Signature INTERCEPT = 82 TypeUtils.parseSignature("Object intercept(Object, java.lang.reflect.Method, Object[], net.sf.cglib.MethodProxy)"); 83 84 public void generate(ClassEmitter ce, Context context) { 85 for (Iterator it = context.getMethods(); it.hasNext();) { 86 Method method = (Method)it.next(); 87 String accessName = getAccessName(context, method); 88 String fieldName = getFieldName(context, method); 89 90 ce.declare_field(Constants.PRIVATE_FINAL_STATIC, fieldName, METHOD, null); 91 ce.declare_field(Constants.PRIVATE_FINAL_STATIC, accessName, METHOD_PROXY, null); 92 CodeEmitter e; 93 94 // access method 95 e = ce.begin_method(Constants.ACC_FINAL, 96 new Signature(getAccessName(context, method), 97 ReflectUtils.getSignature(method).getDescriptor()), 98 ReflectUtils.getExceptionTypes(method)); 99 if (Modifier.isAbstract(method.getModifiers())) { 100 e.throw_exception(ABSTRACT_METHOD_ERROR, method.toString() + " is abstract" ); 101 } else { 102 e.load_this(); 103 e.load_args(); 104 e.super_invoke(ReflectUtils.getSignature(method)); 105 } 106 e.return_value(); 107 e.end_method(); 108 109 // around method 110 e = ce.begin_method(context.getModifiers(method), 111 ReflectUtils.getSignature(method), 112 ReflectUtils.getExceptionTypes(method)); 113 Label nullInterceptor = e.make_label(); 114 context.emitCallback(e); 115 e.dup(); 116 e.ifnull(nullInterceptor); 117 118 e.load_this(); 119 e.getfield(fieldName); 120 e.create_arg_array(); 121 e.getfield(accessName); 122 e.invoke_interface(METHOD_INTERCEPTOR, INTERCEPT); 123 e.unbox_or_zero(Type.getType(method.getReturnType())); 124 e.return_value(); 125 126 e.mark(nullInterceptor); 127 e.load_this(); 128 e.load_args(); 129 e.super_invoke(ReflectUtils.getSignature(method)); 130 e.return_value(); 131 e.end_method(); 132 } 133 } 134 135 private String getFieldName(Context context, Method method) { 136 return "CGLIB$$METHOD_" + context.getUniqueName(method); 137 } 138 139 private String getAccessName(Context context, Method method) { 140 return "CGLIB$$ACCESS_" + context.getUniqueName(method); 141 } 142 143 public void generateStatic(CodeEmitter e, final Context context) { 144 /* generates: 145 static { 146 Class cls = findClass("java.lang.Object"); 147 METHOD_1 = cls.getDeclaredMethod("toString", new Class[0]); 148 149 Class thisClass = findClass("NameOfThisClass"); 150 CGLIB$ACCESS_0 = MethodProxy.create(thisClass.getClassLoader(), 151 cls, "toString()Ljava.lang.String;", 152 thisClass, "CGLIB$ACCESS_0()Ljava.lang.String;"); 153 } 154 */ 155 156 Local thisclass = e.make_local(); 157 ComplexOps.load_class_this(e); 158 e.dup(); 159 e.store_local(thisclass); 160 e.invoke_virtual(Constants.TYPE_CLASS, GET_CLASS_LOADER); 161 162 for (Iterator it = context.getMethods(); it.hasNext();) { 163 e.dup(); 164 Method method = (Method)it.next(); 165 ComplexOps.load_method(e, method); 166 e.dup(); 167 e.putfield(getFieldName(context, method)); 168 169 String accessName = getAccessName(context, method); 170 Signature sig = ReflectUtils.getSignature(method); 171 e.invoke_virtual(METHOD, GET_DECLARING_CLASS); 172 e.push(method.getName() + sig.getDescriptor()); 173 174 e.load_local(thisclass); 175 e.push(accessName + sig.getDescriptor()); 176 e.invoke_static(METHOD_PROXY, MAKE_PROXY); 177 e.putfield(accessName); 178 } 179 } 180 }

This page was automatically generated by Maven