• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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