BasicTest.java revision 3addc29228cb3a2d263e1d91a0b7d4e0fe26e246
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 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; 25import java.util.Comparator; 26 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 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: " + Arrays.deepToString(methods)); 88 Method meth = methods[methods.length -1]; 89 System.out.println("Decl annos: " + Arrays.deepToString(meth.getDeclaredAnnotations())); 90 Annotation[][] paramAnnos = meth.getParameterAnnotations(); 91 System.out.println("Param annos (" + paramAnnos.length + ") : " 92 + Arrays.deepToString(paramAnnos)); 93 } 94 95 static Object createProxy(Object proxyMe) { 96 /* declare an object that will handle the method calls */ 97 InvocationHandler handler = new MyInvocationHandler(proxyMe); 98 99 /* create the proxy class */ 100 Class proxyClass = Proxy.getProxyClass(Shapes.class.getClassLoader(), 101 new Class[] { Quads.class, Colors.class, Trace.class }); 102 103 /* create a proxy object, passing the handler object in */ 104 Object proxy = null; 105 try { 106 Constructor<Class> cons; 107 cons = proxyClass.getConstructor( 108 new Class[] { InvocationHandler.class }); 109 //System.out.println("Constructor is " + cons); 110 proxy = cons.newInstance(new Object[] { handler }); 111 } catch (NoSuchMethodException nsme) { 112 System.err.println("failed: " + nsme); 113 } catch (InstantiationException ie) { 114 System.err.println("failed: " + ie); 115 } catch (IllegalAccessException ie) { 116 System.err.println("failed: " + ie); 117 } catch (InvocationTargetException ite) { 118 System.err.println("failed: " + ite); 119 } 120 121 return proxy; 122 } 123} 124 125/* 126 * Some interfaces. 127 */ 128interface Shapes { 129 public void circle(int r); 130 public int rectangle(int x, int y); 131 132 public String blob(); 133 134 public R0base checkMe(); 135 public void upChuck(); 136 public void upCheck() throws InterruptedException; 137} 138 139interface Quads extends Shapes { 140 public int rectangle(int x, int y); 141 public int square(int x, int y); 142 public int trapezoid(int x, double off, int y); 143 144 public R0a checkMe(); 145} 146 147/* 148 * More interfaces. 149 */ 150interface Colors { 151 public int red(float howRed); 152 public int green(double howGreen); 153 public double blue(int howBlue); 154 public int mauve(String apology); 155 156 public String blob(); 157 158 public R0aa checkMe(); 159} 160 161interface Trace { 162 public void getTrace(); 163} 164 165/* 166 * Some return types. 167 */ 168class R0base { int mBlah; } 169class R0a extends R0base { int mBlah_a; } 170class R0aa extends R0a { int mBlah_aa; } 171 172 173/* 174 * A class that implements them all. 175 */ 176class Mix implements Quads, Colors { 177 public void circle(int r) { 178 System.out.println("--- circle " + r); 179 } 180 public int rectangle(int x, int y) { 181 System.out.println("--- rectangle " + x + "," + y); 182 return 4; 183 } 184 public int square(int x, int y) { 185 System.out.println("--- square " + x + "," + y); 186 return 4; 187 } 188 public int trapezoid(int x, double off, int y) { 189 System.out.println("--- trap " + x + "," + y + "," + off); 190 return 8; 191 } 192 public String blob() { 193 System.out.println("--- blob"); 194 return "mix"; 195 } 196 197 public int red(float howRed) { 198 System.out.println("--- red " + howRed); 199 return 0; 200 } 201 public int green(double howGreen) { 202 System.out.println("--- green " + howGreen); 203 return 1; 204 } 205 public double blue(int howBlue) { 206 System.out.println("--- blue " + howBlue); 207 return 2.54; 208 } 209 public int mauve(String apology) { 210 System.out.println("--- mauve " + apology); 211 return 3; 212 } 213 214 public R0aa checkMe() { 215 return null; 216 } 217 public void upChuck() { 218 throw new IndexOutOfBoundsException("upchuck"); 219 } 220 public void upCheck() throws InterruptedException { 221 throw new InterruptedException("upcheck"); 222 } 223} 224 225/* 226 * Invocation handler, defining the implementation of the proxy functions. 227 */ 228class MyInvocationHandler implements InvocationHandler { 229 Object mObj; 230 231 public MyInvocationHandler(Object obj) { 232 mObj = obj; 233 } 234 235 /* 236 * This is called when anything gets invoked in the proxy object. 237 */ 238 public Object invoke(Object proxy, Method method, Object[] args) 239 throws Throwable { 240 241 Object result = null; 242 243 // Trap Object calls. This is important here to avoid a recursive 244 // invocation of toString() in the print statements below. 245 if (method.getDeclaringClass() == java.lang.Object.class) { 246 //System.out.println("!!! object " + method.getName()); 247 if (method.getName().equals("toString")) 248 return super.toString(); 249 else if (method.getName().equals("hashCode")) 250 return Integer.valueOf(super.hashCode()); 251 else if (method.getName().equals("equals")) 252 return Boolean.valueOf(super.equals(args[0])); 253 else 254 throw new RuntimeException("huh?"); 255 } 256 257 if (method.getDeclaringClass() == Trace.class) { 258 if (method.getName().equals("getTrace")) { 259 StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); 260 for (int i = 0; i < stackTrace.length; i++) { 261 StackTraceElement ste = stackTrace[i]; 262 if (ste.getMethodName().equals("getTrace")) { 263 System.out.println(ste.getClassName() + "." + ste.getMethodName() + " " + 264 ste.getFileName() + ":" + ste.getLineNumber()); 265 } 266 } 267 return null; 268 } 269 } 270 271 System.out.println("Invoke " + method); 272 if (args == null || args.length == 0) { 273 System.out.println(" (no args)"); 274 } else { 275 for (int i = 0; i < args.length; i++) 276 System.out.println(" " + i + ": " + args[i]); 277 } 278 279 try { 280 if (true) 281 result = method.invoke(mObj, args); 282 else 283 result = -1; 284 System.out.println("Success: method " + method.getName() 285 + " res=" + result); 286 } catch (InvocationTargetException ite) { 287 throw ite.getTargetException(); 288 } catch (IllegalAccessException iae) { 289 throw new RuntimeException(iae); 290 } 291 return result; 292 } 293} 294