/* * Copyright 2004-2015 the Seasar Foundation and the Others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ package org.seasar.framework.aop.interceptors; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.seasar.framework.beans.MethodNotFoundRuntimeException; import org.seasar.framework.util.MethodUtil; /** * 例外処理用の{@link MethodInterceptor}です。 * * @author higa * */ public abstract class ThrowsInterceptor extends AbstractInterceptor { private static final long serialVersionUID = 1L; /** * {@link ThrowsInterceptor}の実装クラスが実装しなければいけないメソッド名です。 */ public static final String METHOD_NAME = "handleThrowable"; private Map methodMap = new HashMap(); /** * {@link ThrowsInterceptor}を作成します。 */ public ThrowsInterceptor() { Method[] methods = getClass().getMethods(); for (int i = 0; i < methods.length; ++i) { Method m = methods[i]; if (MethodUtil.isBridgeMethod(m) || MethodUtil.isSyntheticMethod(m)) { continue; } if (isHandleThrowable(m)) { methodMap.put(m.getParameterTypes()[0], m); } } if (methodMap.size() == 0) { throw new MethodNotFoundRuntimeException(getClass(), METHOD_NAME, new Class[] { Throwable.class, MethodInvocation.class }); } } private boolean isHandleThrowable(Method method) { return METHOD_NAME.equals(method.getName()) && method.getParameterTypes().length == 2 && Throwable.class .isAssignableFrom(method.getParameterTypes()[0]) && MethodInvocation.class.isAssignableFrom(method .getParameterTypes()[1]); } /** * @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation) */ public Object invoke(MethodInvocation invocation) throws Throwable { try { return invocation.proceed(); } catch (Throwable t) { Method method = getMethod(t); if (method != null) { try { return method.invoke(this, new Object[] { t, invocation }); } catch (InvocationTargetException ite) { throw ite.getTargetException(); } } throw t; } } private Method getMethod(Throwable t) { Class clazz = t.getClass(); Method method = (Method) methodMap.get(clazz); while (method == null && !clazz.equals(Throwable.class)) { clazz = clazz.getSuperclass(); method = (Method) methodMap.get(clazz); } return method; } }