• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 The Android Open Source Project
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 
17 import java.lang.annotation.Annotation;
18 import java.lang.reflect.InvocationHandler;
19 import java.lang.reflect.InvocationTargetException;
20 import java.lang.reflect.Constructor;
21 import java.lang.reflect.Field;
22 import java.lang.reflect.Method;
23 import java.lang.reflect.Proxy;
24 import java.util.Arrays;
25 import java.util.Comparator;
26 
27 /**
28  * Do some basic tests.
29  */
30 public class BasicTest {
31 
main(String[] args)32     public static void main(String[] args) {
33         Mix proxyMe = new Mix();
34         Object proxy = createProxy(proxyMe);
35 
36         if (!Proxy.isProxyClass(proxy.getClass()))
37             System.err.println("not a proxy class?");
38         if (Proxy.getInvocationHandler(proxy) == null)
39             System.err.println("ERROR: Proxy.getInvocationHandler is null");
40 
41         /* take it for a spin; verifies instanceof constraint */
42         Shapes shapes = (Shapes) proxy;
43         shapes.circle(3);
44         shapes.rectangle(10, 20);
45         shapes.blob();
46         Quads quads = (Quads) proxy;
47         quads.rectangle(15, 25);
48         quads.trapezoid(6, 81.18, 4);
49         Colors colors = (Colors) proxy;
50         colors.red(1.0f);
51         colors.blue(777);
52         colors.mauve("sorry");
53         colors.blob();
54         Trace trace = (Trace) proxy;
55         trace.getTrace();
56 
57         try {
58             shapes.upChuck();
59             System.out.println("Didn't get expected exception");
60         } catch (IndexOutOfBoundsException ioobe) {
61             System.out.println("Got expected ioobe");
62         }
63         try {
64             shapes.upCheck();
65             System.out.println("Didn't get expected exception");
66         } catch (InterruptedException ie) {
67             System.out.println("Got expected ie");
68         }
69 
70         /*
71          * Exercise annotations on Proxy classes.  This is mostly to ensure
72          * that annotation calls work correctly on generated classes.
73          */
74         System.out.println("");
75         Method[] methods = proxy.getClass().getDeclaredMethods();
76         Arrays.sort(methods, new Comparator<Method>() {
77           public int compare(Method o1, Method o2) {
78             int result = o1.getName().compareTo(o2.getName());
79             if (result != 0) {
80                 return result;
81             }
82             return o1.getReturnType().getName().compareTo(o2.getReturnType().getName());
83           }
84         });
85         System.out.println("Proxy interfaces: " +
86             Arrays.deepToString(proxy.getClass().getInterfaces()));
87         System.out.println("Proxy methods: " +
88             Main.replaceProxyClassNamesForOutput(Arrays.deepToString(methods)));
89         Method meth = methods[methods.length -1];
90         System.out.println("Decl annos: " + Arrays.deepToString(meth.getDeclaredAnnotations()));
91         Annotation[][] paramAnnos = meth.getParameterAnnotations();
92         System.out.println("Param annos (" + paramAnnos.length + ") : "
93             + Arrays.deepToString(paramAnnos));
94         System.out.println("Modifiers: " + meth.getModifiers());
95     }
96 
createProxy(Object proxyMe)97     static Object createProxy(Object proxyMe) {
98         /* declare an object that will handle the method calls */
99         InvocationHandler handler = new MyInvocationHandler(proxyMe);
100 
101         /* create the proxy class */
102         Class proxyClass = Proxy.getProxyClass(Shapes.class.getClassLoader(),
103                             new Class[] { Quads.class, Colors.class, Trace.class });
104         Main.registerProxyClassName(proxyClass.getCanonicalName());
105 
106         /* create a proxy object, passing the handler object in */
107         Object proxy = null;
108         try {
109             Constructor<Class> cons;
110             cons = proxyClass.getConstructor(
111                             new Class[] { InvocationHandler.class });
112             //System.out.println("Constructor is " + cons);
113             proxy = cons.newInstance(new Object[] { handler });
114         } catch (NoSuchMethodException nsme) {
115             System.err.println("failed: " + nsme);
116         } catch (InstantiationException ie) {
117             System.err.println("failed: " + ie);
118         } catch (IllegalAccessException ie) {
119             System.err.println("failed: " + ie);
120         } catch (InvocationTargetException ite) {
121             System.err.println("failed: " + ite);
122         }
123 
124         return proxy;
125     }
126 }
127 
128 /*
129  * Some interfaces.
130  */
131 interface Shapes {
circle(int r)132     public void circle(int r);
rectangle(int x, int y)133     public int rectangle(int x, int y);
134 
blob()135     public String blob();
136 
checkMe()137     public R0base checkMe();
upChuck()138     public void upChuck();
upCheck()139     public void upCheck() throws InterruptedException;
140 }
141 
142 interface Quads extends Shapes {
rectangle(int x, int y)143     public int rectangle(int x, int y);
square(int x, int y)144     public int square(int x, int y);
trapezoid(int x, double off, int y)145     public int trapezoid(int x, double off, int y);
146 
checkMe()147     public R0a checkMe();
148 }
149 
150 /*
151  * More interfaces.
152  */
153 interface Colors {
red(float howRed)154     public int red(float howRed);
green(double howGreen)155     public int green(double howGreen);
blue(int howBlue)156     public double blue(int howBlue);
mauve(String apology)157     public int mauve(String apology);
158 
blob()159     public String blob();
160 
checkMe()161     public R0aa checkMe();
162 }
163 
164 interface Trace {
getTrace()165     public void getTrace();
166 }
167 
168 /*
169  * Some return types.
170  */
171 class R0base { int mBlah;  }
172 class R0a extends R0base { int mBlah_a;  }
173 class R0aa extends R0a { int mBlah_aa;  }
174 
175 
176 /*
177  * A class that implements them all.
178  */
179 class Mix implements Quads, Colors {
circle(int r)180     public void circle(int r) {
181         System.out.println("--- circle " + r);
182     }
rectangle(int x, int y)183     public int rectangle(int x, int y) {
184         System.out.println("--- rectangle " + x + "," + y);
185         return 4;
186     }
square(int x, int y)187     public int square(int x, int y) {
188         System.out.println("--- square " + x + "," + y);
189         return 4;
190     }
trapezoid(int x, double off, int y)191     public int trapezoid(int x, double off, int y) {
192         System.out.println("--- trap " + x + "," + y + "," + off);
193         return 8;
194     }
blob()195     public String blob() {
196         System.out.println("--- blob");
197         return "mix";
198     }
199 
red(float howRed)200     public int red(float howRed) {
201         System.out.println("--- red " + howRed);
202         return 0;
203     }
green(double howGreen)204     public int green(double howGreen) {
205         System.out.println("--- green " + howGreen);
206         return 1;
207     }
blue(int howBlue)208     public double blue(int howBlue) {
209         System.out.println("--- blue " + howBlue);
210         return 2.54;
211     }
mauve(String apology)212     public int mauve(String apology) {
213         System.out.println("--- mauve " + apology);
214         return 3;
215     }
216 
checkMe()217     public R0aa checkMe() {
218         return null;
219     }
upChuck()220     public void upChuck() {
221         throw new IndexOutOfBoundsException("upchuck");
222     }
upCheck()223     public void upCheck() throws InterruptedException {
224         throw new InterruptedException("upcheck");
225     }
226 }
227 
228 /*
229  * Invocation handler, defining the implementation of the proxy functions.
230  */
231 class MyInvocationHandler implements InvocationHandler {
232     Object mObj;
233 
MyInvocationHandler(Object obj)234     public MyInvocationHandler(Object obj) {
235         mObj = obj;
236     }
237 
238     /*
239      * This is called when anything gets invoked in the proxy object.
240      */
invoke(Object proxy, Method method, Object[] args)241     public Object invoke(Object proxy, Method method, Object[] args)
242         throws Throwable {
243 
244         Object result = null;
245 
246         // Trap Object calls.  This is important here to avoid a recursive
247         // invocation of toString() in the print statements below.
248         if (method.getDeclaringClass() == java.lang.Object.class) {
249             //System.out.println("!!! object " + method.getName());
250             if (method.getName().equals("toString")) {
251                 return super.toString();
252             } else if (method.getName().equals("hashCode")) {
253                 return Integer.valueOf(super.hashCode());
254             } else if (method.getName().equals("equals")) {
255                 return Boolean.valueOf(super.equals(args[0]));
256             } else {
257                 throw new RuntimeException("huh?");
258             }
259         }
260 
261         if (method.getDeclaringClass() == Trace.class) {
262           if (method.getName().equals("getTrace")) {
263             StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
264             for (int i = 0; i < stackTrace.length; i++) {
265                 StackTraceElement ste = stackTrace[i];
266                 if (ste.getMethodName().equals("getTrace")) {
267                   String outputClassName = Main.replaceProxyClassNamesForOutput(ste.getClassName());
268                   System.out.println(outputClassName + "." + ste.getMethodName() + " " +
269                                      ste.getFileName() + ":" + ste.getLineNumber());
270                 }
271             }
272             return null;
273           }
274         }
275 
276         if (method.getDeclaringClass() == Trace.class) {
277           if (method.getName().equals("getTrace")) {
278             StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
279             for (int i = 0; i < stackTrace.length; i++) {
280                 StackTraceElement ste = stackTrace[i];
281                 if (ste.getMethodName().equals("getTrace")) {
282                   String outputClassName = Main.replaceProxyClassNamesForOutput(ste.getClassName());
283                   System.out.println(outputClassName + "." + ste.getMethodName() + " " +
284                                      ste.getFileName() + ":" + ste.getLineNumber());
285                 }
286             }
287             return null;
288           }
289         }
290 
291         System.out.println("Invoke " + method);
292         if (args == null || args.length == 0) {
293             System.out.println(" (no args)");
294         } else {
295             for (int i = 0; i < args.length; i++)
296                 System.out.println(" " + i + ": " + args[i]);
297         }
298 
299         try {
300             if (true) {
301                 result = method.invoke(mObj, args);
302             } else {
303                 result = -1;
304             }
305             System.out.println("Success: method " + method.getName()
306                 + " res=" + result);
307         } catch (InvocationTargetException ite) {
308             throw ite.getTargetException();
309         } catch (IllegalAccessException iae) {
310             throw new RuntimeException(iae);
311         }
312         return result;
313     }
314 }
315