View Javadoc

1   package org.codehaus.groovy.runtime;
2   
3   import java.lang.reflect.InvocationHandler;
4   import java.lang.reflect.InvocationTargetException;
5   import java.lang.reflect.Method;
6   
7   /***
8    * This class is a general adapter to map a call to an Java interface 
9    * to a given delegate.
10   * <p>
11   * @author Ben Yu
12   * @author <a href="mailto:blackdrag@gmx.org">Jochen Theodorou</a>
13   */
14  public abstract class ConversionHandler implements InvocationHandler {
15      private Object delegate;
16      
17      /***
18       * Creates a ConversionHandler with an deleagte.
19       * @param delegate the delegate
20       * @throws IllegalArgumentException if the given delegate is null
21       */
22      public ConversionHandler(Object delegate) {
23          if (delegate==null) throw new IllegalArgumentException("delegate must not be null");
24          this.delegate = delegate;
25      }
26      
27      /***
28       * gets the delegate.
29       * @return the delegate
30       */
31      public Object getDelegate(){
32          return delegate;
33      }
34      
35      /***
36       * This method is a default implementation for the invoke method
37       * given in Invocationhandler. Any call to an method with an
38       * declaring class that is not Object is redirected to invokeCustom. 
39       * Methods like tostring, equals and hashcode are called on the class
40       * itself instead of the delegate. It is better to overwrite the 
41       * invokeCustom method where the Object related methods are filtered out.
42       * 
43       * @see #invokeCustom(Object, Method, Object[])
44       * @see InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
45       * 
46       * @param proxy the proxy
47       * @param method the method
48       * @param args the arguments
49       * @return the result of the invocation by method or delegate
50       * @throws Throwable any exception caused by the delegate or the method
51       */
52      public Object invoke(Object proxy, Method method, Object[] args)
53      throws Throwable {
54          if(!isObjectMethod(method)){
55              return invokeCustom(proxy,method,args);
56          }
57          try {
58              return method.invoke(this, args);
59          } catch (InvocationTargetException ite) {
60              throw ite.getTargetException();
61          }  
62      }
63      
64      /***
65       * This method is called for all Methods not defined on Object. 
66       * The delegate should be called here.
67       * 
68       * @param proxy the proxy
69       * @param method the method
70       * @param args the arguments
71       * @return the result of the invocation of the delegate
72       * @throws Throwable any exception causes by the delegate
73       * @see #invoke(Object, Method, Object[])
74       * @see InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
75       * 
76       */
77      public abstract Object invokeCustom(Object proxy, Method method, Object[] args) throws Throwable;
78      
79      /***
80       * Indicates whether some other object is "equal to" this one.
81       * The delegate is used if the class of the parameter and the
82       * current class are equal. In other cases the method will return 
83       * false. The exact class is here used, if inheritance is needed,
84       * this method must be overwritten. 
85       *        
86       * @see java.lang.Object#equals(java.lang.Object)
87       */
88      public boolean equals(Object obj) {
89          if (obj!=null && obj.getClass()==this.getClass()){
90              return (((ConversionHandler)obj).getDelegate()).equals(obj);
91          } else {
92              return false;
93          }
94      }
95  
96      /***
97       * Returns a hash code value for the delegate. 
98       * @see java.lang.Object#hashCode()
99       */
100     public int hashCode() {
101         return delegate.hashCode();
102     }
103     
104     /***
105      * Returns a String version of the delegate.
106      * @see java.lang.Object#toString()
107      */
108     public String toString() {
109         return delegate.toString();
110     }
111     
112     private static boolean isObjectMethod(Method mtd){
113         return mtd.getDeclaringClass().equals(Object.class);
114     }
115 }