/* JFox, the OpenSource J2EE Application Server
 *
 * Distributable under GNU LGPL license by gun.org
 * more details please visit http://www.huihoo.org/jfox
 */
package org.jfox.jndi.enc;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import javax.naming.Context;
import javax.naming.LinkRef;
import javax.naming.OperationNotSupportedException;
import javax.naming.Reference;

import org.jfox.jndi.InitialContextHelper;

/**
 * @author <a href="mailto:young_yy@hotmail.com">Young Yang</a>
 */

public class EnterpriseContextInvocationHandler implements InvocationHandler {

    private static Context initCtx = InitialContextHelper.getInitialContext();

    private Context enterpriseContext = null;

    public EnterpriseContextInvocationHandler(Context enterpriseContext) {
        this.enterpriseContext = enterpriseContext;
    }

    // hold other methed except lookup
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        String methodName = method.getName();
        if(methodName.equals("toString")) {
            return enterpriseContext.toString();
        }
        if(!methodName.equals("lookup")) {
            throw new OperationNotSupportedException(methodName + " is not supported in EnterpriseContext, except only lookup!");
        }

        Object obj = method.invoke(enterpriseContext, args);
        if(obj instanceof Reference) {
            return lookupReference((Reference) obj);
        }
        else {
            return obj;
        }

    }

    public Context getEnterpriseContext() {
        return enterpriseContext;
    }

    public Context getInitialContext() {
        return initCtx;
    }

    /**
     * @param ref
     * @return
     * @throws Exception
     */
    protected Object lookupReference(Reference ref) throws Exception {
        //TODO: must bind EJB env reference as LinkRef
        if(ref instanceof LinkRef) {
            return getInitialContext().lookup(((LinkRef) ref).getLinkName());
        }
        else {
            Object refAddr = ref.get(0).getContent();
            return getInitialContext().lookup(refAddr.toString());
        }
    }
}

