Home | History | Annotate | Download | only in src
      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.io.IOException;
     18 import java.lang.reflect.InvocationHandler;
     19 import java.lang.reflect.InvocationTargetException;
     20 import java.lang.reflect.Method;
     21 import java.lang.reflect.Proxy;
     22 import java.lang.reflect.UndeclaredThrowableException;
     23 
     24 /*
     25  * Create a Proxy class that blah.
     26  */
     27 public class WrappedThrow {
     28     public static void main(String[] args) {
     29         WTMix mix = new WTMix();
     30         InvocationHandler handler = new WTInvocationHandler(mix);
     31         Object proxy;
     32 
     33         try {
     34             proxy = Proxy.newProxyInstance(WrappedThrow.class.getClassLoader(),
     35                 new Class<?>[] { InterfaceW1.class, InterfaceW2.class },
     36                 handler);
     37         } catch (IllegalArgumentException iae) {
     38             System.out.println("WT init failed");
     39             return;
     40         }
     41 
     42         InterfaceW1 if1 = (InterfaceW1) proxy;
     43         InterfaceW2 if2 = (InterfaceW2) proxy;
     44         try {
     45             if1.throwFunky();
     46             System.out.println("No exception thrown");
     47         } catch (UndeclaredThrowableException ute) {
     48             System.out.println("Got expected UTE");
     49         } catch (Throwable t) {
     50             System.out.println("Got unexpected exception: " + t);
     51         }
     52 
     53         try {
     54             if1.throwFunky2();
     55             System.out.println("No exception thrown");
     56         } catch (IOException ioe) {
     57             System.out.println("Got expected IOE");
     58         } catch (Throwable t) {
     59             System.out.println("Got unexpected exception: " + t);
     60         }
     61 
     62         try {
     63             if2.throwFunky2();
     64             System.out.println("No exception thrown");
     65         } catch (IOException ioe) {
     66             System.out.println("Got expected IOE");
     67         } catch (Throwable t) {
     68             System.out.println("Got unexpected exception: " + t);
     69         }
     70 
     71         /*
     72          * Throw exceptions, walking down the hierarchy.
     73          */
     74         try {
     75             if1.throwException();
     76             System.out.println("No exception thrown");
     77         } catch (UndeclaredThrowableException ute) {
     78             System.out.println("Got expected UTE");
     79         } catch (Throwable t) {
     80             System.out.println("Got unexpected exception: " + t);
     81         }
     82 
     83         try {
     84             if1.throwBase();
     85             System.out.println("No exception thrown");
     86         } catch (UndeclaredThrowableException ute) {
     87             System.out.println("Got expected UTE");
     88         } catch (Throwable t) {
     89             System.out.println("Got unexpected exception: " + t);
     90         }
     91 
     92         try {
     93             if2.throwSub();
     94             System.out.println("No exception thrown");
     95         } catch (SubException se) {
     96             System.out.println("Got expected exception");
     97         } catch (Throwable t) {
     98             System.out.println("Got unexpected exception: " + t);
     99         }
    100 
    101         try {
    102             if2.throwSubSub();
    103             System.out.println("No exception thrown");
    104         } catch (SubException se) {
    105             System.out.println("Got expected exception");
    106         } catch (Throwable t) {
    107             System.out.println("Got unexpected exception: " + t);
    108         }
    109 
    110         /*
    111          * Make sure that, if the class explicitly allows the base
    112          * class of an exception, that we still allow it.
    113          */
    114         try {
    115             if1.bothThrowBase();
    116             System.out.println("No exception thrown");
    117         } catch (BaseException se) {
    118             System.out.println("Got expected exception");
    119         } catch (Throwable t) {
    120             System.out.println("Got unexpected exception: " + t);
    121         }
    122     }
    123 }
    124 
    125 class BaseException extends Exception {}
    126 class SubException extends BaseException {}
    127 class SubSubException extends SubException {}
    128 
    129 interface InterfaceW1 {
    130     public void throwFunky();
    131 
    132     public void throwFunky2() throws BaseException,
    133            NoSuchMethodException, IOException;
    134 
    135     public void throwException() throws BaseException;
    136     public void throwBase() throws BaseException;
    137     public void throwSub() throws BaseException;
    138     public void throwSubSub() throws BaseException;
    139 
    140     public void bothThrowBase() throws BaseException, SubException, SubSubException;
    141 }
    142 
    143 interface InterfaceW2 {
    144     public void throwFunky2() throws InterruptedException,
    145            NoSuchMethodException, IOException;
    146 
    147     public void throwException() throws SubException;
    148     public void throwBase() throws SubException;
    149     public void throwSub() throws SubException;
    150     public void throwSubSub() throws SubException;
    151 
    152     public void bothThrowBase() throws SubException, BaseException, SubSubException;
    153 }
    154 
    155 /**
    156  * Implement all of the proxied interfaces.
    157  */
    158 class WTMix implements InterfaceW1, InterfaceW2 {
    159     public int dastardlyDeed() throws SubException {
    160         System.out.println("Throwing SubException");
    161         throw new SubException();
    162     }
    163 
    164     /* these don't actually get called; they just cause exceptions */
    165     public void throwFunky() {}
    166     public void throwFunky2() {}
    167     public void throwException() throws SubException {}
    168     public void throwBase() throws SubException {}
    169     public void throwSub() throws SubException {}
    170     public void throwSubSub() throws SubException {}
    171 
    172     public void bothThrowBase() throws BaseException, SubException {}
    173 }
    174 
    175 /**
    176  * Invocation handler for our proxy class.
    177  */
    178 class WTInvocationHandler implements InvocationHandler {
    179     private Object mObj;
    180 
    181     public WTInvocationHandler(Object obj) {
    182         mObj = obj;
    183     }
    184 
    185     /*
    186      * This is called when anything gets invoked in the proxy object.
    187      */
    188     public Object invoke(Object proxy, Method method, Object[] args)
    189         throws Throwable {
    190 
    191         Object result = null;
    192 
    193         // Trap Object calls.  This is important here to avoid a recursive
    194         // invocation of toString() in the print statements below.
    195         if (method.getDeclaringClass() == java.lang.Object.class) {
    196             //System.out.println("!!! object " + method.getName());
    197             if (method.getName().equals("toString"))
    198                 return super.toString();
    199             else if (method.getName().equals("hashCode"))
    200                 return Integer.valueOf(super.hashCode());
    201             else if (method.getName().equals("equals"))
    202                 return Boolean.valueOf(super.equals(args[0]));
    203             else
    204                 throw new RuntimeException("huh?");
    205         }
    206 
    207         System.out.println("Invoke " + method);
    208         if (args == null || args.length == 0) {
    209             System.out.println(" (no args)");
    210         } else {
    211             for (int i = 0; i < args.length; i++)
    212                 System.out.println(" " + i + ": " + args[i]);
    213         }
    214 
    215         try {
    216             if (method.getName().equals("throwFunky"))
    217                 throw new InterruptedException("fake");
    218             if (method.getName().equals("throwFunky2"))
    219                 throw new IOException("fake2");
    220             if (method.getName().equals("throwException"))
    221                 throw new Exception();
    222             if (method.getName().equals("throwBase"))
    223                 throw new BaseException();
    224             if (method.getName().equals("throwSub"))
    225                 throw new SubException();
    226             if (method.getName().equals("throwSubSub"))
    227                 throw new SubSubException();
    228             if (method.getName().equals("bothThrowBase"))
    229                 throw new BaseException();
    230 
    231             if (true)
    232                 result = method.invoke(mObj, args);
    233             else
    234                 result = -1;
    235             System.out.println("Success: method " + method.getName()
    236                 + " res=" + result);
    237         } catch (InvocationTargetException ite) {
    238             throw ite.getTargetException();
    239         } catch (IllegalAccessException iae) {
    240             throw new RuntimeException(iae);
    241         }
    242         return result;
    243     }
    244 }
    245