package com.twelvemonkeys.lang; import java.io.FileNotFoundException; import java.io.IOException; import java.lang.reflect.UndeclaredThrowableException; import java.sql.SQLException; /** * ExceptionUtil * * @author Harald Kuhr * @author last modified by $Author: haku $ * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/lang/ExceptionUtil.java#2 $ */ public final class ExceptionUtil { /*public*/ static void launder(final Throwable pThrowable, Class... pExpectedTypes) { if (pThrowable instanceof Error) { throw (Error) pThrowable; } if (pThrowable instanceof RuntimeException) { throw (RuntimeException) pThrowable; } for (Class expectedType : pExpectedTypes) { if (expectedType.isInstance(pThrowable)) { throw new RuntimeException(pThrowable); } } throw new UndeclaredThrowableException(pThrowable); } @SuppressWarnings({"unchecked", "UnusedDeclaration"}) static void throwAs(final Class pType, final Throwable pThrowable) throws T { throw (T) pThrowable; } public static void throwUnchecked(final Throwable pThrowable) { throwAs(RuntimeException.class, pThrowable); } /*public*/ static void handle(final Throwable pThrowable, final ThrowableHandler... pHandler) { handleImpl(pThrowable, pHandler); } @SuppressWarnings({"unchecked"}) private static void handleImpl(final Throwable pThrowable, final ThrowableHandler... pHandler) { // TODO: Sort more specific throwable handlers before less specific? for (ThrowableHandler handler : pHandler) { if (handler.handles(pThrowable)) { handler.handle((T) pThrowable); return; } } throwUnchecked(pThrowable); } public static abstract class ThrowableHandler { private Class[] mThrowables; protected ThrowableHandler(final Class... pThrowables) { // TODO: Assert not null mThrowables = pThrowables.clone(); } final public boolean handles(final Throwable pThrowable) { for (Class throwable : mThrowables) { if (throwable.isAssignableFrom(pThrowable.getClass())) { return true; } } return false; } public abstract void handle(T pThrowable); } @SuppressWarnings({"InfiniteLoopStatement"}) public static void main(String[] pArgs) { while (true) { foo(); } } private static void foo() { try { bar(); } catch (Throwable t) { handle(t, new ThrowableHandler(IOException.class) { public void handle(final IOException pThrowable) { System.out.println("IOException: " + pThrowable + " handled"); } }, new ThrowableHandler(SQLException.class, NumberFormatException.class) { public void handle(final Exception pThrowable) { System.out.println("Exception: " + pThrowable + " handled"); } }, new ThrowableHandler(Throwable.class) { public void handle(final Throwable pThrowable) { System.err.println("Generic throwable: " + pThrowable + " NOT handled"); throwUnchecked(pThrowable); } } ); } } private static void bar() { baz(); } @SuppressWarnings({"ThrowableInstanceNeverThrown"}) private static void baz() { double random = Math.random(); if (random < (1.0 / 3.0)) { throwUnchecked(new FileNotFoundException("FNF Boo")); } if (random < (2.0 / 3.0)) { throwUnchecked(new SQLException("SQL Boo")); } else { throwUnchecked(new Exception("Some Boo")); } } }