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 }