//
//  ========================================================================
//  Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

package org.eclipse.jetty.jndi;


import java.io.IOException;
import java.util.Hashtable;
import java.util.Map;
import java.util.WeakHashMap;

import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NameParser;
import javax.naming.Reference;
import javax.naming.StringRefAddr;
import javax.naming.spi.ObjectFactory;

import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.log.Logger;



/**
 * ContextFactory.java
 *
 * This is an object factory that produces a jndi naming
 * context based on a classloader.
 *
 *  It is used for the java:comp context.
 *
 *  This object factory is bound at java:comp. When a
 *  lookup arrives for java:comp,  this object factory
 *  is invoked and will return a context specific to
 *  the caller's environment (so producing the java:comp/env
 *  specific to a webapp).
 *
 *  The context selected is based on classloaders. First
 *  we try looking at the thread context classloader if it is set, and walk its
 *  hierarchy, creating a context if none is found. If the thread context classloader
 *  is not set, then we use the classloader associated with the current Context.
 *  
 *  If there is no current context, or no classloader, we return null.
 *
 * Created: Fri Jun 27 09:26:40 2003
 *
 *
 *
 */
public class ContextFactory implements ObjectFactory
{
    private static Logger __log = NamingUtil.__log;

    /**
     * Map of classloaders to contexts.
     */
    private static final WeakHashMap __contextMap = new WeakHashMap();

    /**
     * Threadlocal for injecting a context to use
     * instead of looking up the map.
     */
    private static final ThreadLocal<Context> __threadContext = new ThreadLocal<Context>();
    
    /**
     * Threadlocal for setting a classloader which must be used 
     * when finding the comp context.
     */
    private static final ThreadLocal<ClassLoader> __threadClassLoader = new ThreadLocal<ClassLoader>();
    


    /**
     * Find or create a context which pertains to a classloader.
     *
     * If the thread context classloader is set, we try to find an already-created naming context
     * for it. If one does not exist, we walk its classloader hierarchy until one is found, or we 
     * run out of parent classloaders. In the latter case, we will create a new naming context associated
     * with the original thread context classloader.
     * 
     * If the thread context classloader is not set, we obtain the classloader from the current 
     * jetty Context, and look for an already-created naming context. 
     * 
     * If there is no current jetty Context, or it has no associated classloader, we 
     * return null.
     * @see javax.naming.spi.ObjectFactory#getObjectInstance(java.lang.Object, javax.naming.Name, javax.naming.Context, java.util.Hashtable)
     */
    public Object getObjectInstance (Object obj,
                                     Name name,
                                     Context nameCtx,
                                     Hashtable env)
        throws Exception
    {
        //First, see if we have had a context injected into us to use.
        Context ctx = (Context)__threadContext.get();
        if (ctx != null)
        {
            if(__log.isDebugEnabled()) __log.debug("Using the Context that is bound on the thread");
            return ctx;
        }

        //See if there is a classloader to use for finding the comp context
        //Don't use its parent hierarchy if set.
        ClassLoader loader = (ClassLoader)__threadClassLoader.get();
        if (loader != null)
        {
            if (__log.isDebugEnabled() && loader != null) __log.debug("Using threadlocal classloader");
            ctx = getContextForClassLoader(loader);
            if (ctx == null)
            {
                ctx = newNamingContext(obj, loader, env, name, nameCtx);
                __contextMap.put (loader, ctx);
                if(__log.isDebugEnabled())__log.debug("Made context "+name.get(0)+" for classloader: "+loader);
            }
            return ctx;
        }
       
        //If the thread context classloader is set, then try its hierarchy to find a matching context
        ClassLoader tccl = Thread.currentThread().getContextClassLoader();
        loader = tccl;      
        if (loader != null)
        {
            if (__log.isDebugEnabled() && loader != null) __log.debug("Trying thread context classloader");
            while (ctx == null && loader != null)
            {
                ctx = getContextForClassLoader(loader);
                if (ctx == null && loader != null)
                    loader = loader.getParent();
            }

            if (ctx == null)
            {
                ctx = newNamingContext(obj, tccl, env, name, nameCtx);
                __contextMap.put (tccl, ctx);
                if(__log.isDebugEnabled())__log.debug("Made context "+name.get(0)+" for classloader: "+tccl);
            }
            return ctx;
        }


        //If trying thread context classloader hierarchy failed, try the
        //classloader associated with the current context
        if (ContextHandler.getCurrentContext() != null)
        {
            
            if (__log.isDebugEnabled() && loader != null) __log.debug("Trying classloader of current org.eclipse.jetty.server.handler.ContextHandler");
            loader = ContextHandler.getCurrentContext().getContextHandler().getClassLoader();
            ctx = (Context)__contextMap.get(loader);    

            if (ctx == null && loader != null)
            {
                ctx = newNamingContext(obj, loader, env, name, nameCtx);
                __contextMap.put (loader, ctx);
                if(__log.isDebugEnabled())__log.debug("Made context "+name.get(0)+" for classloader: "+loader);
            }

            return ctx;
        }
        return null;
    }


    /**
     * Create a new NamingContext.
     * @param obj
     * @param loader
     * @param env
     * @param name
     * @param parentCtx
     * @throws Exception
     */
    public NamingContext newNamingContext(Object obj, ClassLoader loader, Hashtable env, Name name, Context parentCtx)
    throws Exception
    {
        Reference ref = (Reference)obj;
        StringRefAddr parserAddr = (StringRefAddr)ref.get("parser");
        String parserClassName = (parserAddr==null?null:(String)parserAddr.getContent());
        NameParser parser = (NameParser)(parserClassName==null?null:loader.loadClass(parserClassName).newInstance());

        return new NamingContext (env,
                                  name.get(0),
                                  (NamingContext)parentCtx,
                                  parser);
    }

  
    /**
     * Find the naming Context for the given classloader
     * @param loader
     */
    public Context getContextForClassLoader(ClassLoader loader)
    {
        if (loader == null)
            return null;
        
        return (Context)__contextMap.get(loader);
    }

    /**
     * Associate the given Context with the current thread.
     * disassociate method should be called to reset the context.
     * @param ctx the context to associate to the current thread.
     * @return the previous context associated on the thread (can be null)
     */
    public static Context associateContext(final Context ctx)
    {
        Context previous = (Context)__threadContext.get();
        __threadContext.set(ctx);
        return previous;
    }

    public static void disassociateContext(final Context ctx)
    {
        __threadContext.set(null);
    }
    
    public static ClassLoader associateClassLoader(final ClassLoader loader)
    {
        ClassLoader prev = (ClassLoader)__threadClassLoader.get();
        __threadClassLoader.set(loader);
        return prev;
    }
    
    public static void disassociateClassLoader ()
    {
        __threadClassLoader.set(null);
    }

    public static void dump(Appendable out, String indent) throws IOException
    {
        out.append("o.e.j.jndi.ContextFactory@").append(Long.toHexString(__contextMap.hashCode())).append("\n");
        int size=__contextMap.size();
        int i=0;
        for (Map.Entry<ClassLoader,NamingContext> entry : ((Map<ClassLoader,NamingContext>)__contextMap).entrySet())
        {
            boolean last=++i==size;
            ClassLoader loader=entry.getKey();
            out.append(indent).append(" +- ").append(loader.getClass().getSimpleName()).append("@").append(Long.toHexString(loader.hashCode())).append(": ");

            NamingContext context = entry.getValue();
            context.dump(out,indent+(last?"    ":" |  "));
        }
    }
}
