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