/*
 * Copyright 2003-2007 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.codehaus.groovy.runtime;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * This class is a general adapter to map a call to an Java interface 
 * to a given delegate.
 * <p>
 * @author Ben Yu
 * @author <a href="mailto:blackdrag@gmx.org">Jochen Theodorou</a>
 */
public abstract class ConversionHandler implements InvocationHandler {
    private Object delegate;
    
    /**
     * Creates a ConversionHandler with an deleagte.
     * @param delegate the delegate
     * @throws IllegalArgumentException if the given delegate is null
     */
    public ConversionHandler(Object delegate) {
        if (delegate==null) throw new IllegalArgumentException("delegate must not be null");
        this.delegate = delegate;
    }
    
    /**
     * gets the delegate.
     * @return the delegate
     */
    public Object getDelegate(){
        return delegate;
    }
    
    /**
     * This method is a default implementation for the invoke method
     * given in Invocationhandler. Any call to an method with an
     * declaring class that is not Object is redirected to invokeCustom. 
     * Methods like tostring, equals and hashcode are called on the class
     * itself instead of the delegate. It is better to overwrite the 
     * invokeCustom method where the Object related methods are filtered out.
     * 
     * @see #invokeCustom(Object, Method, Object[])
     * @see InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
     * 
     * @param proxy the proxy
     * @param method the method
     * @param args the arguments
     * @return the result of the invocation by method or delegate
     * @throws Throwable any exception caused by the delegate or the method
     */
    public Object invoke(Object proxy, Method method, Object[] args)
    throws Throwable {
        if(!isObjectMethod(method)){
            return invokeCustom(proxy,method,args);
        }
        try {
            return method.invoke(this, args);
        } catch (InvocationTargetException ite) {
            throw ite.getTargetException();
        }  
    }
    
    /**
     * This method is called for all Methods not defined on Object. 
     * The delegate should be called here.
     * 
     * @param proxy the proxy
     * @param method the method
     * @param args the arguments
     * @return the result of the invocation of the delegate
     * @throws Throwable any exception causes by the delegate
     * @see #invoke(Object, Method, Object[])
     * @see InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
     * 
     */
    public abstract Object invokeCustom(Object proxy, Method method, Object[] args) throws Throwable;
    
    /**
     * Indicates whether some other object is "equal to" this one.
     * The delegate is used if the class of the parameter and the
     * current class are equal. In other cases the method will return 
     * false. The exact class is here used, if inheritance is needed,
     * this method must be overwritten. 
     *        
     * @see java.lang.Object#equals(java.lang.Object)
     */
    public boolean equals(Object obj) {
        if (obj instanceof Proxy){
            obj = Proxy.getInvocationHandler(obj);
        }
        
        if (obj instanceof ConversionHandler){
            return (((ConversionHandler)obj).getDelegate()).equals(delegate);
        } else {
            return false;
        }
    }

    /**
     * Returns a hash code value for the delegate. 
     * @see java.lang.Object#hashCode()
     */
    public int hashCode() {
        return delegate.hashCode();
    }
    
    /**
     * Returns a String version of the delegate.
     * @see java.lang.Object#toString()
     */
    public String toString() {
        return delegate.toString();
    }
    
    private static boolean isObjectMethod(Method mtd){
        return mtd.getDeclaringClass().equals(Object.class);
    }
}
