X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fnet%2Fsf%2Fopenrocket%2Futil%2FReflection.java;h=b3c66f62b85d94ee38faa9c45cc8fbb17a7e22d0;hb=10c2e190c2e70564be6768a1acafa232dfff8e5c;hp=26c00beff5362640b3448f396cf92ed60cc87a55;hpb=720d4935bc6bec453e6478ad5227356c626610a2;p=debian%2Fopenrocket diff --git a/src/net/sf/openrocket/util/Reflection.java b/src/net/sf/openrocket/util/Reflection.java index 26c00bef..b3c66f62 100644 --- a/src/net/sf/openrocket/util/Reflection.java +++ b/src/net/sf/openrocket/util/Reflection.java @@ -18,9 +18,14 @@ public class Reflection { */ public static class Method { private final java.lang.reflect.Method method; + public Method(java.lang.reflect.Method m) { + if (m == null) { + throw new IllegalArgumentException("method is null"); + } method = m; } + /** * Same as Method.invoke(), but the possible exceptions are wrapped into * RuntimeExceptions. @@ -29,22 +34,23 @@ public class Reflection { try { return method.invoke(obj, args); } catch (IllegalArgumentException e) { - throw new RuntimeException("Error while invoking method '"+method+"'. "+ - "Please report this as a bug.",e); + throw new BugException("Error while invoking method '" + method + "'. " + + "Please report this as a bug.", e); } catch (IllegalAccessException e) { - throw new RuntimeException("Error while invoking method '"+method+"'. "+ - "Please report this as a bug.",e); + throw new BugException("Error while invoking method '" + method + "'. " + + "Please report this as a bug.", e); } catch (InvocationTargetException e) { - throw new RuntimeException("Error while invoking method '"+method+"'. "+ - "Please report this as a bug.",e); + throw Reflection.handleWrappedException(e); } } + /** * Invoke static method. Equivalent to invoke(null, args...). */ public Object invokeStatic(Object... args) { - return invoke(null,args); + return invoke(null, args); } + /** * Same as Method.toString(). */ @@ -56,36 +62,65 @@ public class Reflection { /** + * Handles an InvocationTargetException gracefully. If the cause is an unchecked + * exception it is thrown, otherwise it is encapsulated in a BugException. + *

+ * This method has a return type of Error in order to allow writing code like: + *

throw Reflection.handleInvocationTargetException(e)
+ * This allows the compiler verifying that the call will never succeed correctly + * and ending that branch of execution. + * + * @param e the InvocationTargetException that occurred (not null). + * @return never returns normally. + */ + public static Error handleWrappedException(Exception e) { + Throwable cause = e.getCause(); + if (cause == null) { + throw new BugException("wrapped exception without cause", e); + } + if (cause instanceof RuntimeException) { + throw (RuntimeException) cause; + } + if (cause instanceof Error) { + throw (Error) cause; + } + throw new BugException("wrapped exception occurred", cause); + } + + + + /** + * Find a method from the rocket component classes. * Throws an exception if method not found. */ - public static Reflection.Method findMethodStatic( + public static Reflection.Method findMethod( Class componentClass, String method, Class... params) { - Reflection.Method m = findMethod(ROCKETCOMPONENT_PACKAGE, componentClass, + Reflection.Method m = findMethod(ROCKETCOMPONENT_PACKAGE, componentClass, "", method, params); if (m == null) { - throw new RuntimeException("Could not find method for componentClass=" - +componentClass+" method="+method); + throw new BugException("Could not find method for componentClass=" + + componentClass + " method=" + method); } return m; } - - public static Reflection.Method findMethod(String pack, RocketComponent component, - String method, Class...params) { - return findMethod(pack,component.getClass(),"",method,params); + + public static Reflection.Method findMethod(String pack, RocketComponent component, + String method, Class... params) { + return findMethod(pack, component.getClass(), "", method, params); } - public static Reflection.Method findMethod(String pack, RocketComponent component, + public static Reflection.Method findMethod(String pack, RocketComponent component, String suffix, String method, Class... params) { return findMethod(pack, component.getClass(), suffix, method, params); } - - public static Reflection.Method findMethod(String pack, - Class componentClass, + + public static Reflection.Method findMethod(String pack, + Class componentClass, String suffix, String method, Class... params) { Class currentclass; String name; @@ -93,18 +128,18 @@ public class Reflection { currentclass = componentClass; while ((currentclass != null) && (currentclass != Object.class)) { name = currentclass.getCanonicalName(); - if (name.lastIndexOf('.')>=0) - name = name.substring(name.lastIndexOf(".")+1); + if (name.lastIndexOf('.') >= 0) + name = name.substring(name.lastIndexOf(".") + 1); name = pack + "." + name + suffix; try { Class c = Class.forName(name); - java.lang.reflect.Method m = c.getMethod(method,params); + java.lang.reflect.Method m = c.getMethod(method, params); return new Reflection.Method(m); } catch (ClassNotFoundException ignore) { } catch (NoSuchMethodException ignore) { } - + currentclass = currentclass.getSuperclass(); } return null; @@ -120,24 +155,24 @@ public class Reflection { currentclass = component.getClass(); while ((currentclass != null) && (currentclass != Object.class)) { name = currentclass.getCanonicalName(); - if (name.lastIndexOf('.')>=0) - name = name.substring(name.lastIndexOf(".")+1); + if (name.lastIndexOf('.') >= 0) + name = name.substring(name.lastIndexOf(".") + 1); name = pack + "." + name + suffix; try { Class c = Class.forName(name); Class[] paramClasses = new Class[params.length]; - for (int i=0; i < params.length; i++) { + for (int i = 0; i < params.length; i++) { paramClasses[i] = params[i].getClass(); } // Constructors must be searched manually. Why?! - main: for (Constructor constructor: c.getConstructors()) { + main: for (Constructor constructor : c.getConstructors()) { Class[] parameterTypes = constructor.getParameterTypes(); if (params.length != parameterTypes.length) continue; - for (int i=0; i < params.length; i++) { - if (!parameterTypes[i].isInstance(params[i])) + for (int i = 0; i < params.length; i++) { + if (!parameterTypes[i].isInstance(params[i])) continue main; } // Matching constructor found @@ -145,18 +180,18 @@ public class Reflection { } } catch (ClassNotFoundException ignore) { } catch (IllegalArgumentException e) { - throw new RuntimeException("Construction of "+name+" failed",e); + throw new BugException("Construction of " + name + " failed", e); } catch (InstantiationException e) { - throw new RuntimeException("Construction of "+name+" failed",e); + throw new BugException("Construction of " + name + " failed", e); } catch (IllegalAccessException e) { - throw new RuntimeException("Construction of "+name+" failed",e); + throw new BugException("Construction of " + name + " failed", e); } catch (InvocationTargetException e) { - throw new RuntimeException("Construction of "+name+" failed",e); + throw Reflection.handleWrappedException(e); } - + currentclass = currentclass.getSuperclass(); } - throw new RuntimeException("Suitable constructor for component "+component+ + throw new BugException("Suitable constructor for component " + component + " not found"); } }