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