KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > aop > framework > adapter > ThrowsAdviceInterceptor


1 /*
2  * Copyright 2002-2007 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.springframework.aop.framework.adapter;
18
19 import java.lang.reflect.InvocationTargetException JavaDoc;
20 import java.lang.reflect.Method JavaDoc;
21 import java.util.HashMap JavaDoc;
22 import java.util.Map JavaDoc;
23
24 import org.aopalliance.intercept.MethodInterceptor;
25 import org.aopalliance.intercept.MethodInvocation;
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28
29 import org.springframework.aop.AfterAdvice;
30 import org.springframework.util.Assert;
31
32 /**
33  * Interceptor to wrap an after-throwing advice.
34  *
35  * <p>The signatures on handler methods on the <code>ThrowsAdvice</code>
36  * implementation method argument must be of the form:<br>
37  *
38  * <code>void afterThrowing([Method, args, target], ThrowableSubclass);</code>
39  *
40  * <p>Only the last argument is required.
41  *
42  * <p>Some examples of valid methods would be:
43  *
44  * <pre class="code">public void afterThrowing(Exception ex)</pre>
45  * <pre class="code">public void afterThrowing(RemoteException)</pre>
46  * <pre class="code">public void afterThrowing(Method method, Object[] args, Object target, Exception ex)</pre>
47  * <pre class="code">public void afterThrowing(Method method, Object[] args, Object target, ServletException ex)</pre>
48  *
49  * <p>This is a framework class that need not be used directly by Spring users.
50  *
51  * @author Rod Johnson
52  * @author Juergen Hoeller
53  */

54 public class ThrowsAdviceInterceptor implements MethodInterceptor, AfterAdvice {
55
56     private static final String JavaDoc AFTER_THROWING = "afterThrowing";
57
58     private static final Log logger = LogFactory.getLog(ThrowsAdviceInterceptor.class);
59
60
61     private final Object JavaDoc throwsAdvice;
62
63     /** Methods on throws advice, keyed by exception class */
64     private final Map JavaDoc exceptionHandlerMap = new HashMap JavaDoc();
65
66
67     /**
68      * Create a new ThrowsAdviceInterceptor for the given ThrowsAdvice.
69      * @param throwsAdvice the advice object that defines the exception
70      * handler methods (usually a {@link org.springframework.aop.ThrowsAdvice}
71      * implementation)
72      */

73     public ThrowsAdviceInterceptor(Object JavaDoc throwsAdvice) {
74         Assert.notNull(throwsAdvice, "Advice must not be null");
75         this.throwsAdvice = throwsAdvice;
76
77         Method JavaDoc[] methods = throwsAdvice.getClass().getMethods();
78         for (int i = 0; i < methods.length; i++) {
79             Method JavaDoc method = methods[i];
80             if (method.getName().equals(AFTER_THROWING) &&
81                     //m.getReturnType() == null &&
82
(method.getParameterTypes().length == 1 || method.getParameterTypes().length == 4) &&
83                     Throwable JavaDoc.class.isAssignableFrom(method.getParameterTypes()[method.getParameterTypes().length - 1])
84                 ) {
85                 // Have an exception handler
86
this.exceptionHandlerMap.put(method.getParameterTypes()[method.getParameterTypes().length - 1], method);
87                 if (logger.isDebugEnabled()) {
88                     logger.debug("Found exception handler method: " + method);
89                 }
90             }
91         }
92         
93         if (this.exceptionHandlerMap.isEmpty()) {
94             throw new IllegalArgumentException JavaDoc(
95                     "At least one handler method must be found in class [" + throwsAdvice.getClass() + "]");
96         }
97     }
98     
99     public int getHandlerMethodCount() {
100         return this.exceptionHandlerMap.size();
101     }
102
103     /**
104      * Determine the exception handle method. Can return null if not found.
105      * @param exception the exception thrown
106      * @return a handler for the given exception type
107      */

108     private Method JavaDoc getExceptionHandler(Throwable JavaDoc exception) {
109         Class JavaDoc exceptionClass = exception.getClass();
110         if (logger.isTraceEnabled()) {
111             logger.trace("Trying to find handler for exception of type [" + exceptionClass.getName() + "]");
112         }
113         Method JavaDoc handler = (Method JavaDoc) this.exceptionHandlerMap.get(exceptionClass);
114         while (handler == null && !exceptionClass.equals(Throwable JavaDoc.class)) {
115             exceptionClass = exceptionClass.getSuperclass();
116             handler = (Method JavaDoc) this.exceptionHandlerMap.get(exceptionClass);
117         }
118         if (handler != null && logger.isDebugEnabled()) {
119             logger.debug("Found handler for exception of type [" + exceptionClass.getName() + "]: " + handler);
120         }
121         return handler;
122     }
123
124     public Object JavaDoc invoke(MethodInvocation mi) throws Throwable JavaDoc {
125         try {
126             return mi.proceed();
127         }
128         catch (Throwable JavaDoc ex) {
129             Method JavaDoc handlerMethod = getExceptionHandler(ex);
130             if (handlerMethod != null) {
131                 invokeHandlerMethod(mi, ex, handlerMethod);
132             }
133             throw ex;
134         }
135     }
136     
137     private void invokeHandlerMethod(MethodInvocation mi, Throwable JavaDoc ex, Method JavaDoc method) throws Throwable JavaDoc {
138         Object JavaDoc[] handlerArgs;
139         if (method.getParameterTypes().length == 1) {
140             handlerArgs = new Object JavaDoc[] { ex };
141         }
142         else {
143             handlerArgs = new Object JavaDoc[] {mi.getMethod(), mi.getArguments(), mi.getThis(), ex};
144         }
145         try {
146             method.invoke(this.throwsAdvice, handlerArgs);
147         }
148         catch (InvocationTargetException JavaDoc targetEx) {
149             throw targetEx.getTargetException();
150         }
151     }
152
153 }
154
Popular Tags