KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > groovy > lang > ProxyMetaClass


1 package groovy.lang;
2
3 import org.codehaus.groovy.runtime.InvokerHelper;
4
5 import java.beans.IntrospectionException JavaDoc;
6
7 /**
8  * As subclass of MetaClass, ProxyMetaClass manages calls from Groovy Objects to POJOs.
9  * It enriches MetaClass with the feature of making method invokations interceptable by
10  * an Interceptor. To this end, it acts as a decorator (decorator pattern) allowing
11  * to add or withdraw this feature at runtime.
12  * See groovy/lang/InterceptorTest.groovy for details.
13  * @author Dierk Koenig
14  */

15 public class ProxyMetaClass extends MetaClass {
16
17     protected MetaClass adaptee = null;
18     protected Interceptor interceptor = null;
19
20     /**
21      * convenience factory method for the most usual case.
22      */

23     public static ProxyMetaClass getInstance(Class JavaDoc theClass) throws IntrospectionException JavaDoc {
24         MetaClassRegistry metaRegistry = InvokerHelper.getInstance().getMetaRegistry();
25         MetaClass meta = metaRegistry.getMetaClass(theClass);
26         return new ProxyMetaClass(metaRegistry, theClass, meta);
27     }
28     /**
29      * @param adaptee the MetaClass to decorate with interceptability
30      */

31     public ProxyMetaClass(MetaClassRegistry registry, Class JavaDoc theClass, MetaClass adaptee) throws IntrospectionException JavaDoc {
32         super(registry, theClass);
33         this.adaptee = adaptee;
34         if (null == adaptee) throw new IllegalArgumentException JavaDoc("adaptee must not be null");
35     }
36
37     /**
38      * Make this ProxyMetaClass the funnel for all method calls, thus enabling interceptions.
39      */

40     public void register() {
41         registry.setMetaClass(theClass, this);
42     }
43
44     /**
45      * Reset to using the decorated adaptee, disable interception.
46      */

47     public void unRegister() {
48         registry.setMetaClass(theClass, adaptee);
49     }
50
51     /**
52      * @return the interceptor in use or null if no interceptor is used
53      */

54     public Interceptor getInterceptor() {
55         return interceptor;
56     }
57
58     /**
59      * @param interceptor may be null to reset any interception
60      */

61     public void setInterceptor(Interceptor interceptor) {
62         this.interceptor = interceptor;
63     }
64
65     /**
66      * Call invokeMethod on adaptee with logic like in MetaClass unless we have an Interceptor.
67      * With Interceptor the call is nested in its beforeInvoke and afterInvoke methods.
68      * The method call is suppressed if Interceptor.doInvoke() returns false.
69      * See Interceptor for details.
70      */

71     public Object JavaDoc invokeMethod(final Object JavaDoc object, final String JavaDoc methodName, final Object JavaDoc[] arguments) {
72         return doCall(object, methodName, arguments, new Callable(){
73             public Object JavaDoc call() {
74                 return adaptee.invokeMethod(object, methodName, arguments);
75             }
76         });
77     }
78     /**
79      * Call invokeStaticMethod on adaptee with logic like in MetaClass unless we have an Interceptor.
80      * With Interceptor the call is nested in its beforeInvoke and afterInvoke methods.
81      * The method call is suppressed if Interceptor.doInvoke() returns false.
82      * See Interceptor for details.
83      */

84     public Object JavaDoc invokeStaticMethod(final Object JavaDoc object, final String JavaDoc methodName, final Object JavaDoc[] arguments) {
85         return doCall(object, methodName, arguments, new Callable(){
86             public Object JavaDoc call() {
87                 return adaptee.invokeStaticMethod(object, methodName, arguments);
88             }
89         });
90     }
91
92     /**
93      * Call invokeConstructor on adaptee with logic like in MetaClass unless we have an Interceptor.
94      * With Interceptor the call is nested in its beforeInvoke and afterInvoke methods.
95      * The method call is suppressed if Interceptor.doInvoke() returns false.
96      * See Interceptor for details.
97      */

98     public Object JavaDoc invokeConstructor(final Object JavaDoc[] arguments) {
99         return doCall(theClass, "ctor", arguments, new Callable(){
100             public Object JavaDoc call() {
101                 return adaptee.invokeConstructor(arguments);
102             }
103         });
104     }
105
106     // since Java has no Closures...
107
private interface Callable{
108         Object JavaDoc call();
109     }
110     private Object JavaDoc doCall(Object JavaDoc object, String JavaDoc methodName, Object JavaDoc[] arguments, Callable howToInvoke) {
111         if (null == interceptor) {
112             return howToInvoke.call();
113         }
114         Object JavaDoc result = interceptor.beforeInvoke(object, methodName, arguments);
115         if (interceptor.doInvoke()) {
116             result = howToInvoke.call();
117         }
118         result = interceptor.afterInvoke(object, methodName, arguments, result);
119         return result;
120     }
121 }
122
Popular Tags