1 8 9 package mx4j.tools.remote.soap; 10 11 import java.io.IOException ; 12 import java.lang.reflect.Constructor ; 13 import java.lang.reflect.InvocationHandler ; 14 import java.lang.reflect.InvocationTargetException ; 15 import java.lang.reflect.Method ; 16 import java.lang.reflect.Proxy ; 17 import javax.management.MBeanException ; 18 import javax.management.RuntimeMBeanException ; 19 20 import mx4j.log.Log; 21 import mx4j.log.Logger; 22 import mx4j.tools.remote.http.HTTPConnection; 23 import org.apache.axis.AxisFault; 24 25 33 class ClientExceptionCatcher implements InvocationHandler 34 { 35 public static HTTPConnection newInstance(HTTPConnection target) 36 { 37 ClientExceptionCatcher handler = new ClientExceptionCatcher(target); 38 return (HTTPConnection)Proxy.newProxyInstance(handler.getClass().getClassLoader(), new Class []{HTTPConnection.class}, handler); 39 } 40 41 private final HTTPConnection target; 42 43 private ClientExceptionCatcher(HTTPConnection target) 44 { 45 this.target = target; 46 } 47 48 public Object invoke(Object proxy, Method method, Object [] args) throws Throwable 49 { 50 try 51 { 52 try 53 { 54 return method.invoke(target, args); 55 } 56 catch (InvocationTargetException x) 57 { 58 throw x.getTargetException(); 59 } 60 } 61 catch (Throwable x) 62 { 63 throw handleException(x, method.getExceptionTypes()); 64 } 65 } 66 67 private Throwable handleException(Throwable x, Class [] declared) 68 { 69 if (x instanceof Error ) return x; 70 if (x instanceof AxisFault) x = extractThrowable((AxisFault)x); 71 if (isDeclaredOrRuntime(x, declared)) return x; 72 return new IOException (x.toString()); 73 } 74 75 private Throwable extractThrowable(AxisFault fault) 76 { 77 String name = fault.getFaultString(); 78 if (name == null) return fault; 79 80 int colon = name.indexOf(':'); 84 String className = colon < 0 ? name : name.substring(0, colon).trim(); 85 String message = colon < 0 ? null : name.substring(colon + 1).trim(); 86 87 Class cls = null; 88 try 89 { 90 cls = getClass().getClassLoader().loadClass(className); 93 } 94 catch (ClassNotFoundException x) 95 { 96 Logger logger = getLogger(); 97 if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Cannot load Throwable class " + className, x); 98 } 99 100 if (cls == null) return fault; 101 102 Object exception = null; 103 if (message != null) 104 { 105 try 106 { 107 Constructor ctor = cls.getConstructor(new Class []{String .class}); 109 exception = ctor.newInstance(new Object []{message}); 110 } 111 catch (Throwable x) 112 { 113 Logger logger = getLogger(); 114 if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Cannot find constructor " + className + "(String message)", x); 115 } 116 } 117 118 if (exception == null) 119 { 120 try 121 { 122 exception = cls.newInstance(); 123 } 124 catch (Throwable x) 125 { 126 Logger logger = getLogger(); 127 if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Cannot find constructor " + className + "()", x); 128 } 129 } 130 131 if (MBeanException .class.getName().equals(className)) 133 { 134 exception = new MBeanException (null, message); 135 } 136 else if (RuntimeMBeanException .class.getName().equals(className)) 137 { 138 exception = new RuntimeMBeanException (null, message); 139 } 140 141 if (!(exception instanceof Throwable )) 142 { 143 Logger logger = getLogger(); 144 if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Could not recreate exception thrown on server side: " + className); 145 return fault; 146 } 147 148 return (Throwable )exception; 149 } 150 151 private boolean isDeclaredOrRuntime(Throwable x, Class [] declared) 152 { 153 if (x instanceof RuntimeException ) return true; 154 155 for (int i = 0; i < declared.length; ++i) 156 { 157 Class exception = declared[i]; 158 if (exception.isInstance(x)) return true; 159 } 160 return false; 161 } 162 163 private Logger getLogger() 164 { 165 return Log.getLogger(getClass().getName()); 166 } 167 } 168 | Popular Tags |