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 org.mockito.cglib.proxy; 17 18 import java.io.Serializable; 19 import java.lang.reflect.Method; 20 import java.util.List; 21 22 import org.mockito.cglib.core.CodeGenerationException; 23 24 /** 25 * This class is meant to be used as replacement for 26 * <code>java.lang.reflect.Proxy</code> under JDK 1.2. There are some known 27 * subtle differences: 28 * <ul> 29 * <li>The exceptions returned by invoking <code>getExceptionTypes</code> 30 * on the <code>Method</code> passed to the <code>invoke</code> method 31 * <b>are</b> the exact set that can be thrown without resulting in an 32 * <code>UndeclaredThrowableException</code> being thrown. 33 * <li>{@link UndeclaredThrowableException} is used instead 34 * of <code>java.lang.reflect.UndeclaredThrowableException</code>. 35 * </ul> 36 * <p> 37 * @version $Id: Proxy.java,v 1.6 2004/06/24 21:15:19 herbyderby Exp $ 38 */ 39 public class Proxy implements Serializable { 40 protected InvocationHandler h; 41 42 private static final CallbackFilter BAD_OBJECT_METHOD_FILTER = new CallbackFilter() { 43 public int accept(Method method, List<Method> allMethods) { 44 if (method.getDeclaringClass().getName().equals("java.lang.Object")) { 45 String name = method.getName(); 46 if (!(name.equals("hashCode") || 47 name.equals("equals") || 48 name.equals("toString"))) { 49 return 1; 50 } 51 } 52 return 0; 53 } 54 }; 55 Proxy(InvocationHandler h)56 protected Proxy(InvocationHandler h) { 57 Enhancer.registerCallbacks(getClass(), new Callback[]{ h, null }); 58 this.h = h; 59 } 60 61 // private for security of isProxyClass 62 private static class ProxyImpl extends Proxy { ProxyImpl(InvocationHandler h)63 protected ProxyImpl(InvocationHandler h) { 64 super(h); 65 } 66 } 67 getInvocationHandler(Object proxy)68 public static InvocationHandler getInvocationHandler(Object proxy) { 69 if (!(proxy instanceof ProxyImpl)) { 70 throw new IllegalArgumentException("Object is not a proxy"); 71 } 72 return ((Proxy)proxy).h; 73 } 74 getProxyClass(ClassLoader loader, Class[] interfaces)75 public static Class getProxyClass(ClassLoader loader, Class[] interfaces) { 76 Enhancer e = new Enhancer(); 77 e.setSuperclass(ProxyImpl.class); 78 e.setInterfaces(interfaces); 79 e.setCallbackTypes(new Class[]{ 80 InvocationHandler.class, 81 NoOp.class, 82 }); 83 e.setCallbackFilter(BAD_OBJECT_METHOD_FILTER); 84 e.setUseFactory(false); 85 return e.createClass(); 86 } 87 isProxyClass(Class cl)88 public static boolean isProxyClass(Class cl) { 89 return cl.getSuperclass().equals(ProxyImpl.class); 90 } 91 newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)92 public static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h) { 93 try { 94 Class clazz = getProxyClass(loader, interfaces); 95 return clazz.getConstructor(new Class[]{ InvocationHandler.class }).newInstance(new Object[]{ h }); 96 } catch (RuntimeException e) { 97 throw e; 98 } catch (Exception e) { 99 throw new CodeGenerationException(e); 100 } 101 } 102 } 103