/* 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.util.Hashtable;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.spi.ObjectFactory;

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

public class EnterpriseContextFactory implements ObjectFactory {
    public final static EnterpriseType WEB = new EnterpriseType("web");
    public final static EnterpriseType EJB = new EnterpriseType("ejb");

    public final static String ENC_JNDI_NAME = "java:comp/env";

    /**
     * store current thread runtime type, EJB or WEB
     */
    private static ThreadLocal tl = new ThreadLocal();
    private final static String WEB_ENC_OBJECT_FACTORY_CLASS = "org.jfox.deployment.web.WebEnterpriseContextFactory";
    private final static String EJB_ENC_OBJECT_FACTORY_CLASS = "org.jfox.ejb.naming.EJBEnterpriseContextFactory";

    public static EnterpriseType enterWeb() {
        EnterpriseType type = (EnterpriseType) tl.get();
        tl.set(WEB);
        return type;
    }

    public static EnterpriseType enterEjb() {
        EnterpriseType type = (EnterpriseType) tl.get();
        tl.set(EJB);
        return type;
    }

    public static void enter(EnterpriseType type) {
        tl.set(type);
    }

    public static boolean isEnterpriseContext(Name name) {
        if(name.toString().startsWith(ENC_JNDI_NAME) && name.toString().length() > (ENC_JNDI_NAME.length() + 1)) {
            return true;
        }
        return false;
    }

    public static Name getEnterpriseContextSuffix(Name name) {
        if(isEnterpriseContext(name)) {
            return name.getSuffix(2);
        }
        else {
            return name;
        }
    }

    public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) throws Exception {
        EnterpriseType type = (EnterpriseType) tl.get();
        if(type.equals(WEB)) {
            ObjectFactory of = (ObjectFactory) Thread.currentThread().getContextClassLoader().loadClass(WEB_ENC_OBJECT_FACTORY_CLASS).newInstance();
            return of.getObjectInstance(obj, name, nameCtx, environment);
        }
        else if(type.equals(EJB)) {
            ObjectFactory of = (ObjectFactory) Thread.currentThread().getContextClassLoader().loadClass(EJB_ENC_OBJECT_FACTORY_CLASS).newInstance();
            return of.getObjectInstance(obj, name, nameCtx, environment);
        }
        else {
            throw new RuntimeException("can only use java:comp/env in ejb or web application");
        }

    }

    public static class EnterpriseType {

        private String type = "ejb";

        public EnterpriseType(String type) {
            this.type = type;
        }

        public String getType() {
            return type;
        }

        public boolean equals(Object obj) {
            return type.equals(((EnterpriseType) obj).type);
        }

        public int hashCode() {
            return type.hashCode();
        }
    }

    public static void main(String[] args) {

    }
}
