15d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao/*
25d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Copyright (C) 2008 The Android Open Source Project
35d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao *
45d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Licensed under the Apache License, Version 2.0 (the "License");
55d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * you may not use this file except in compliance with the License.
65d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * You may obtain a copy of the License at
75d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao *
85d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao *      http://www.apache.org/licenses/LICENSE-2.0
95d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao *
105d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Unless required by applicable law or agreed to in writing, software
115d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * distributed under the License is distributed on an "AS IS" BASIS,
125d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * See the License for the specific language governing permissions and
145d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * limitations under the License.
155d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao */
165d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
175d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoimport java.lang.annotation.Annotation;
185d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoimport java.lang.reflect.InvocationHandler;
195d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoimport java.lang.reflect.InvocationTargetException;
205d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoimport java.lang.reflect.Constructor;
215d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoimport java.lang.reflect.Field;
225d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoimport java.lang.reflect.Method;
235d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoimport java.lang.reflect.Proxy;
245d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoimport java.util.Arrays;
25466bb25416b88fabd5d4387b7c7e5cc1ece78b8cIan Rogersimport java.util.Comparator;
265d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
275d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao/**
285d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Do some basic tests.
295d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao */
305d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaopublic class BasicTest {
315d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
325d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public static void main(String[] args) {
335d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Mix proxyMe = new Mix();
345d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Object proxy = createProxy(proxyMe);
355d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
365d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        if (!Proxy.isProxyClass(proxy.getClass()))
375d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("not a proxy class?");
385d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        if (Proxy.getInvocationHandler(proxy) == null)
395d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("ERROR: Proxy.getInvocationHandler is null");
405d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
415d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* take it for a spin; verifies instanceof constraint */
425d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Shapes shapes = (Shapes) proxy;
435d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        shapes.circle(3);
445d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        shapes.rectangle(10, 20);
455d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        shapes.blob();
465d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Quads quads = (Quads) proxy;
475d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        quads.rectangle(15, 25);
485d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        quads.trapezoid(6, 81.18, 4);
495d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Colors colors = (Colors) proxy;
505d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        colors.red(1.0f);
515d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        colors.blue(777);
525d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        colors.mauve("sorry");
535d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        colors.blob();
543addc29228cb3a2d263e1d91a0b7d4e0fe26e246Jeff Hao        Trace trace = (Trace) proxy;
553addc29228cb3a2d263e1d91a0b7d4e0fe26e246Jeff Hao        trace.getTrace();
565d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
575d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
585d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            shapes.upChuck();
595d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("Didn't get expected exception");
605d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (IndexOutOfBoundsException ioobe) {
615d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("Got expected ioobe");
625d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
635d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
645d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            shapes.upCheck();
655d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("Didn't get expected exception");
665d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (InterruptedException ie) {
675d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("Got expected ie");
685d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
695d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
705d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /*
715d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * Exercise annotations on Proxy classes.  This is mostly to ensure
725d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * that annotation calls work correctly on generated classes.
735d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         */
745d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("");
755d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Method[] methods = proxy.getClass().getDeclaredMethods();
76466bb25416b88fabd5d4387b7c7e5cc1ece78b8cIan Rogers        Arrays.sort(methods, new Comparator<Method>() {
77466bb25416b88fabd5d4387b7c7e5cc1ece78b8cIan Rogers          public int compare(Method o1, Method o2) {
78ecbce8f17a80ddc8e5d80b075a8e334f1c2daf3cJesse Wilson            int result = o1.getName().compareTo(o2.getName());
79ecbce8f17a80ddc8e5d80b075a8e334f1c2daf3cJesse Wilson            if (result != 0) {
80ecbce8f17a80ddc8e5d80b075a8e334f1c2daf3cJesse Wilson                return result;
81ecbce8f17a80ddc8e5d80b075a8e334f1c2daf3cJesse Wilson            }
82ecbce8f17a80ddc8e5d80b075a8e334f1c2daf3cJesse Wilson            return o1.getReturnType().getName().compareTo(o2.getReturnType().getName());
83466bb25416b88fabd5d4387b7c7e5cc1ece78b8cIan Rogers          }
84466bb25416b88fabd5d4387b7c7e5cc1ece78b8cIan Rogers        });
852ed52c4419dd537c98cd7898bc8bdcf8826b8940Elliott Hughes        System.out.println("Proxy interfaces: " +
862ed52c4419dd537c98cd7898bc8bdcf8826b8940Elliott Hughes            Arrays.deepToString(proxy.getClass().getInterfaces()));
875d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("Proxy methods: " + Arrays.deepToString(methods));
885d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Method meth = methods[methods.length -1];
895d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("Decl annos: " + Arrays.deepToString(meth.getDeclaredAnnotations()));
905d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Annotation[][] paramAnnos = meth.getParameterAnnotations();
915d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("Param annos (" + paramAnnos.length + ") : "
925d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            + Arrays.deepToString(paramAnnos));
935d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
945d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
955d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    static Object createProxy(Object proxyMe) {
965d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* declare an object that will handle the method calls */
975d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        InvocationHandler handler = new MyInvocationHandler(proxyMe);
985d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
995d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* create the proxy class */
1005d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Class proxyClass = Proxy.getProxyClass(Shapes.class.getClassLoader(),
1013addc29228cb3a2d263e1d91a0b7d4e0fe26e246Jeff Hao                            new Class[] { Quads.class, Colors.class, Trace.class });
1025d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1035d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* create a proxy object, passing the handler object in */
1045d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Object proxy = null;
1055d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
1065d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            Constructor<Class> cons;
1075d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            cons = proxyClass.getConstructor(
1085d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                            new Class[] { InvocationHandler.class });
1095d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            //System.out.println("Constructor is " + cons);
1105d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            proxy = cons.newInstance(new Object[] { handler });
1115d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (NoSuchMethodException nsme) {
1125d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("failed: " + nsme);
1135d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (InstantiationException ie) {
1145d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("failed: " + ie);
1155d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (IllegalAccessException ie) {
1165d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("failed: " + ie);
1175d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (InvocationTargetException ite) {
1185d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("failed: " + ite);
1195d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
1205d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1215d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        return proxy;
1225d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
1235d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao}
1245d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1255d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao/*
1265d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Some interfaces.
1275d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao */
1285d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaointerface Shapes {
1295d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public void circle(int r);
1305d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public int rectangle(int x, int y);
1315d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1325d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public String blob();
1335d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1345d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public R0base checkMe();
1355d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public void upChuck();
1365d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public void upCheck() throws InterruptedException;
1375d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao}
1385d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1395d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaointerface Quads extends Shapes {
1405d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public int rectangle(int x, int y);
1415d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public int square(int x, int y);
1425d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public int trapezoid(int x, double off, int y);
1435d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1445d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public R0a checkMe();
1455d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao}
1465d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1475d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao/*
1485d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * More interfaces.
1495d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao */
1505d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaointerface Colors {
1515d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public int red(float howRed);
1525d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public int green(double howGreen);
1535d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public double blue(int howBlue);
1545d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public int mauve(String apology);
1555d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1565d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public String blob();
1575d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1585d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public R0aa checkMe();
1595d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao}
1605d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1613addc29228cb3a2d263e1d91a0b7d4e0fe26e246Jeff Haointerface Trace {
1623addc29228cb3a2d263e1d91a0b7d4e0fe26e246Jeff Hao    public void getTrace();
1633addc29228cb3a2d263e1d91a0b7d4e0fe26e246Jeff Hao}
1643addc29228cb3a2d263e1d91a0b7d4e0fe26e246Jeff Hao
1655d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao/*
1665d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Some return types.
1675d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao */
1685d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoclass R0base { int mBlah;  }
1695d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoclass R0a extends R0base { int mBlah_a;  }
1705d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoclass R0aa extends R0a { int mBlah_aa;  }
1715d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1725d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1735d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao/*
1745d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * A class that implements them all.
1755d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao */
1765d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoclass Mix implements Quads, Colors {
1775d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public void circle(int r) {
1785d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("--- circle " + r);
1795d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
1805d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public int rectangle(int x, int y) {
1815d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("--- rectangle " + x + "," + y);
1825d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        return 4;
1835d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
1845d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public int square(int x, int y) {
1855d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("--- square " + x + "," + y);
1865d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        return 4;
1875d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
1885d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public int trapezoid(int x, double off, int y) {
1895d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("--- trap " + x + "," + y + "," + off);
1905d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        return 8;
1915d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
1925d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public String blob() {
1935d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("--- blob");
1945d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        return "mix";
1955d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
1965d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1975d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public int red(float howRed) {
1985d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("--- red " + howRed);
1995d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        return 0;
2005d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
2015d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public int green(double howGreen) {
2025d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("--- green " + howGreen);
2035d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        return 1;
2045d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
2055d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public double blue(int howBlue) {
2065d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("--- blue " + howBlue);
2075d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        return 2.54;
2085d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
2095d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public int mauve(String apology) {
2105d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("--- mauve " + apology);
2115d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        return 3;
2125d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
2135d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2145d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public R0aa checkMe() {
2155d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        return null;
2165d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
2175d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public void upChuck() {
2185d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        throw new IndexOutOfBoundsException("upchuck");
2195d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
2205d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public void upCheck() throws InterruptedException {
2215d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        throw new InterruptedException("upcheck");
2225d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
2235d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao}
2245d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2255d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao/*
2265d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Invocation handler, defining the implementation of the proxy functions.
2275d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao */
2285d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoclass MyInvocationHandler implements InvocationHandler {
2295d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    Object mObj;
2305d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2315d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public MyInvocationHandler(Object obj) {
2325d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        mObj = obj;
2335d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
2345d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2355d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    /*
2365d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * This is called when anything gets invoked in the proxy object.
2375d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     */
2385d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public Object invoke(Object proxy, Method method, Object[] args)
2395d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        throws Throwable {
2405d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2415d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Object result = null;
2425d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2435d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        // Trap Object calls.  This is important here to avoid a recursive
2445d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        // invocation of toString() in the print statements below.
2455d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        if (method.getDeclaringClass() == java.lang.Object.class) {
2465d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            //System.out.println("!!! object " + method.getName());
2475d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            if (method.getName().equals("toString"))
2485d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                return super.toString();
2495d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            else if (method.getName().equals("hashCode"))
2505d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                return Integer.valueOf(super.hashCode());
2515d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            else if (method.getName().equals("equals"))
2525d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                return Boolean.valueOf(super.equals(args[0]));
2535d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            else
2545d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                throw new RuntimeException("huh?");
2555d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
2565d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2573addc29228cb3a2d263e1d91a0b7d4e0fe26e246Jeff Hao        if (method.getDeclaringClass() == Trace.class) {
2583addc29228cb3a2d263e1d91a0b7d4e0fe26e246Jeff Hao          if (method.getName().equals("getTrace")) {
2593addc29228cb3a2d263e1d91a0b7d4e0fe26e246Jeff Hao            StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
2603addc29228cb3a2d263e1d91a0b7d4e0fe26e246Jeff Hao            for (int i = 0; i < stackTrace.length; i++) {
2613addc29228cb3a2d263e1d91a0b7d4e0fe26e246Jeff Hao                StackTraceElement ste = stackTrace[i];
2623addc29228cb3a2d263e1d91a0b7d4e0fe26e246Jeff Hao                if (ste.getMethodName().equals("getTrace")) {
2633addc29228cb3a2d263e1d91a0b7d4e0fe26e246Jeff Hao                  System.out.println(ste.getClassName() + "." + ste.getMethodName() + " " +
2643addc29228cb3a2d263e1d91a0b7d4e0fe26e246Jeff Hao                                     ste.getFileName() + ":" + ste.getLineNumber());
2653addc29228cb3a2d263e1d91a0b7d4e0fe26e246Jeff Hao                }
2663addc29228cb3a2d263e1d91a0b7d4e0fe26e246Jeff Hao            }
2673addc29228cb3a2d263e1d91a0b7d4e0fe26e246Jeff Hao            return null;
2683addc29228cb3a2d263e1d91a0b7d4e0fe26e246Jeff Hao          }
2693addc29228cb3a2d263e1d91a0b7d4e0fe26e246Jeff Hao        }
2703addc29228cb3a2d263e1d91a0b7d4e0fe26e246Jeff Hao
2715d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("Invoke " + method);
2725d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        if (args == null || args.length == 0) {
2735d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println(" (no args)");
2745d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } else {
2755d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            for (int i = 0; i < args.length; i++)
2765d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                System.out.println(" " + i + ": " + args[i]);
2775d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
2785d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2795d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
2805d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            if (true)
2815d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                result = method.invoke(mObj, args);
2825d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            else
2835d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                result = -1;
2845d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("Success: method " + method.getName()
2855d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                + " res=" + result);
2865d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (InvocationTargetException ite) {
2875d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            throw ite.getTargetException();
2885d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (IllegalAccessException iae) {
2895d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            throw new RuntimeException(iae);
2905d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
2915d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        return result;
2925d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
2935d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao}
294