KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > dynaop > DispatchInterceptor


1 package dynaop;
2
3 import java.io.Serializable JavaDoc;
4 import java.lang.reflect.Method JavaDoc;
5 import java.lang.reflect.UndeclaredThrowableException JavaDoc;
6
7 import dynaop.util.*;
8 import dynaop.util.Classes;
9
10 /**
11  * Dispatches to method in interceptor with the same signature
12  * as the intercepted method. If none exists, simply proceeds with invocation.
13  * The dispatch methods may throw <code>Throwable</code> even when the
14  * intercepted method does not. For example:
15  *
16  * <pre>
17  * public class SetIdInterceptor extends DispatchInterceptor {
18  *
19  * public void setId(long id) throws Throwable {
20  * proceed();
21  * Log.log("ID changed to " + id + ".");
22  * }
23  * }
24  * </pre>
25  *
26  * @author Bob Lee (crazybob@crazybob.org)
27  */

28 public abstract class DispatchInterceptor implements Interceptor,
29         Serializable JavaDoc {
30
31     static long serialVersionUID = 0;
32     
33     ThreadLocal JavaDoc localInvocation = new ThreadLocal JavaDoc();
34     
35     Cache cache = new Cache() {
36         protected Object JavaDoc create(Object JavaDoc key) {
37             try {
38                 Method JavaDoc method = (Method JavaDoc) key;
39                 return DispatchInterceptor.this.getClass().getMethod(
40                         method.getName(), method.getParameterTypes());
41             }
42             catch (NoSuchMethodException JavaDoc e) {
43                 return null;
44             }
45         }
46     };
47     
48     /**
49      * Gets the invocation object.
50      */

51     protected Invocation getInvocation() {
52         return (Invocation) localInvocation.get();
53     }
54     
55     void setInvocation(Invocation invocation) {
56         localInvocation.set(invocation);
57     }
58     
59     /**
60      * Proceeds with invocation.
61      */

62     protected Object JavaDoc proceed() throws Throwable JavaDoc {
63         return getInvocation().proceed();
64     }
65     
66     static boolean isInterceptMethod(Method JavaDoc method) {
67         Class JavaDoc[] types = method.getParameterTypes();
68         return (method.getName().equals("intercept") && types != null &&
69             types.length == 1 && types[0].equals(Invocation.class));
70     }
71
72     Method JavaDoc getDispatchMethod(Method JavaDoc method) {
73         return (Method JavaDoc) this.cache.get(method);
74     }
75     
76     public final Object JavaDoc intercept(Invocation invocation) throws Throwable JavaDoc {
77         Method JavaDoc dispatch = getDispatchMethod(invocation.getMethod());
78         if (dispatch == null)
79             return invocation.proceed();
80
81         Invocation old = getInvocation();
82         try {
83             setInvocation(invocation);
84             return Classes.invoke(this, dispatch, invocation.getArguments());
85         }
86         finally {
87             setInvocation(old);
88         }
89     }
90     
91     public int hashCode() {
92         try {
93             return ((Integer JavaDoc) proceed()).intValue();
94         }
95         catch (Throwable JavaDoc t) {
96             throw new UndeclaredThrowableException JavaDoc(t);
97         }
98     }
99
100     public String JavaDoc toString() {
101         try {
102             return (String JavaDoc) proceed();
103         }
104         catch (Throwable JavaDoc t) {
105             throw new UndeclaredThrowableException JavaDoc(t);
106         }
107     }
108
109     public boolean equals(Object JavaDoc o) {
110         try {
111             return ((Boolean JavaDoc) proceed()).booleanValue();
112         }
113         catch (Throwable JavaDoc t) {
114             throw new UndeclaredThrowableException JavaDoc(t);
115         }
116     }
117     
118     /**
119      * Creates a method pointcut for the given <code>DispatchInterceptor</code>
120      * class. The pointcut picks methods implemented by the interceptor.
121      */

122     public static MethodPointcut methodPointcut(final Class JavaDoc interceptorClass) {
123         if (!DispatchInterceptor.class.isAssignableFrom(interceptorClass))
124             throw new ConfigurationException(interceptorClass.getName() +
125                 " does not extend " +
126                 DispatchInterceptor.class.getName() + ".");
127         
128         return new MethodPointcut() {
129             public boolean picks(Method JavaDoc picked) {
130                 try {
131                     Method JavaDoc method = interceptorClass.getMethod(
132                         picked.getName(), picked.getParameterTypes());
133
134                     if (method.getDeclaringClass().equals(
135                             DispatchInterceptor.class))
136                         return false;
137                     
138                     return true;
139                 }
140                 catch (NoSuchMethodException JavaDoc e) {
141                     return false;
142                 }
143             }
144         };
145     }
146 }
147
Popular Tags