01: package org.sape.carbon.core.component.proxy;
02:
03: import java.lang.reflect.InvocationHandler;
04: import java.lang.reflect.Method;
05: import java.lang.reflect.Proxy;
06:
07: /**
08: * This is the abstract interceptor that can provide basic tracking
09: * and next interceptor calling for subclassed interceptors. This
10: * implementation will also shortcut calls to DynamicProxy classes
11: * acting as interceptors by skipping their proxy classes and directly
12: * calling the
13: *
14: * Copyright 2003 Sapient
15: * @since carbon 2.1
16: * @author Greg Hinkle, October 2003
17: * @version $Revision: 1.1 $($Author: ghinkl $ / $Date: 2003/10/15 01:03:26 $)
18: */
19: public abstract class AbstractInterceptor implements Interceptor {
20:
21: /**
22: * The next interceptor in the chain after this one.
23: */
24: protected Interceptor nextInterceptor;
25:
26: /**
27: * True if the next interceptor is a dynamic proxy.
28: */
29: protected boolean nextInterceptorIsProxy;
30:
31: /**
32: * If the next interceptor is a dynamic proxy, this will
33: * hold a reference to its invocation handler.
34: */
35: protected InvocationHandler nextInvocationHandler;
36:
37: /**
38: * The interceptor method object for the "invoke" method.
39: */
40: private Method interceptorMethod;
41:
42: /**
43: * Prepares the interceptor chain by setting the next interceptor
44: * that this one will forward to. It will also prepare for calls
45: * to DynamicProxies.
46: *
47: * @param interceptor the next interceptor in the chain
48: */
49: public void setNextInterceptor(Interceptor interceptor) {
50: this .nextInterceptor = interceptor;
51: this .nextInterceptorIsProxy = Proxy.isProxyClass(interceptor
52: .getClass());
53:
54: // If the next interceptor is a Proxy itself,
55: if (this .nextInterceptorIsProxy) {
56: this .nextInvocationHandler = Proxy
57: .getInvocationHandler(interceptor);
58: try {
59: this .interceptorMethod = Interceptor.class.getMethod(
60: "invoke", new Class[] { Invocation.class });
61: } catch (NoSuchMethodException nsme) {
62: // This should never happen
63: }
64: }
65: }
66:
67: /**
68: * Will forward on an interceptor call to the next interceptor
69: * in the chain.
70: * @param invocation the invocation in progress
71: * @return the return value of the component invocation
72: * @throws Throwable the exception caused by the invocation
73: */
74: protected Object callNextInterceptor(Invocation invocation)
75: throws Throwable {
76: if (this .nextInterceptorIsProxy) {
77: return this .nextInvocationHandler.invoke(
78: this .nextInterceptor, this .interceptorMethod,
79: new Object[] { invocation });
80: } else {
81: return this.nextInterceptor.invoke(invocation);
82:
83: }
84: }
85:
86: }
|