public Object handle(InvocationContext ic) throws Exception {
Method m = ic.getMethod();
Object targetObject = ic.getTarget();
Class<?> targetClass = targetObject == null ? m.getDeclaringClass()
: targetObject.getClass();
CatchHandler exceptionHandlerAnnotation = AnnotationUtils
.findAnnotation(m, targetClass, CatchHandler.class);
Exception unexpectedException = null;
if (exceptionHandlerAnnotation == null) {
throw new IllegalStateException(
"The interceptor annotation can not be determined!");
}
CatchHandling[] exceptionHandlingAnnotations = exceptionHandlerAnnotation
.value();
Class<? extends Throwable>[] unwrap = exceptionHandlerAnnotation
.unwrap();
try {
return ic.proceed();
} catch (Exception ex) {
if (!contains(unwrap, InvocationTargetException.class)) {
unwrap = Arrays.copyOf(unwrap, unwrap.length + 1);
unwrap[unwrap.length - 1] = InvocationTargetException.class;
}
// Unwrap Exception if ex is instanceof InvocationTargetException
Throwable t = ExceptionUtils.unwrap(ex,
InvocationTargetException.class);
boolean exceptionHandled = false;
boolean cleanupInvoked = false;
if (exceptionHandlingAnnotations.length > 0) {
for (CatchHandling handling : exceptionHandlingAnnotations) {
if (handling.exception().isInstance(t)) {
try {
handleThrowable(t);
exceptionHandled = true;
} catch (Exception unexpected) {
unexpectedException = unexpected;
}
// Only invoke cleanup declared at handling level
if (!handling.cleanup().equals(Object.class)) {
cleanupInvoked = invokeCleanups(targetClass, targetObject,
handling.cleanup(), t);
}
break;
}
}
}
// Handle the default exception type if no handlings are
// declared or the handling did not handle the exception
if (!exceptionHandled) {
if (exceptionHandlerAnnotation.exception().isInstance(t)) {
try {
handleThrowable(t);
exceptionHandled = true;
} catch (Exception unexpected) {
unexpectedException = unexpected;
}
if (!exceptionHandlerAnnotation.cleanup().equals(
Object.class) && !cleanupInvoked) {
if(!cleanupInvoked) {
invokeCleanups(targetClass, targetObject,
exceptionHandlerAnnotation.cleanup(), t);
}
}
}
}