/*
 * Enhydra Java Application Server Project
 *
 * The contents of this file are subject to the Enhydra Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License on
 * the Enhydra web site ( http://www.enhydra.org/ ).
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 * the License for the specific terms governing rights and limitations
 * under the License.
 *
 * The Initial Developer of the Enhydra Application Server is Lutris
 * Technologies, Inc. The Enhydra Application Server and portions created
 * by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
 * All Rights Reserved.
 *
 * Contributor(s):
 *
 * $Id$
 */
package org.objectweb.jonas_lib.naming;

import javax.naming.Context;
import javax.naming.NamingException;
import java.util.Hashtable;
import javax.naming.InitialContext;

/**
 * Provide naming services for Web and EJB containers. Containers use this
 * interface for binding the environment entries, remote object references,
 * resource factories and for managing the naming context of the current
 * thread.
 *
 * @author Lutris
  */
public interface ContainerNaming {

    /**
     * Create context for application and component environments.
     * Called by Web Container for each Web Application (as defined in
     * web.xml). Called by EJB Container for each ejb component (as defined
     * in ejb-jar.xml).  The returned context provides an independent
     * namespace for each components environment values, and resources.
     *
     * @param namespace Subcontext name(s) to create under Server Root.
     * Usually consists of application name + component name.
     * <pre>
     * Examples:
     * "App1/WebWar1" for Web Application
     * "App1/EJBJar1/EJBName" for ejb in Enterprise Application.
     * </pre>
     * @return Naming context for component environment
     * @throws NamingException If exception encountered creating namespace.
     *
     */
    Context createEnvironmentContext(String namespace) throws NamingException;

    /**
     * Create immutable context for application and component environments.
     * Called by Web Container for each Web Application (as defined in
     * web.xml). Called by EJB Container for each ejb component (as defined
     * in ejb-jar.xml).  The returned context provides an independent
     * namespace for each components environment values, and resources.  This
     * context must exist in the underlying name service. It must be
     * previously created by an earlier deployment.
     *
     * @param namespace Subcontext name(s) to create under Server Root.
     * Usually consists of application name + component name.
     * <pre>
     * Examples:
     * "App1/WebWar1" for Web Application
     * "App1/EJBJar1/EJBName" for ejb in Enterprise Application.
     * </pre>
     * @return Naming context for component environment
     * @throws NamingException If context namespace does not exist.
     *
     */
    Context createImmutableEnvironmentContext(String namespace)
        throws NamingException;

    /**
     * Return the Context associated with the current thread.
     *
     * @return Context for current thread.
     * @throws NamingException If context namespace does not exist.
     */
    Context getComponentContext() throws NamingException;

    /**
     * Aassociate this Context with the current thread.
     * This method should be called in preinvoke/postinvoke
     * and when we build the bean environment.
     *
     * @param ctx Context to associate with the current thread.
     * @return Previous context setting for current thread.
     */
    Context setComponentContext(Context ctx);

    /**
     * Set back the context with the given value.
     * Don't return the previous context, use setComponentContext() method for this.
     * @param ctx the context to associate to the current thread.
     */
    void resetComponentContext(Context ctx);

    /**
     * Associate the specified CompNamingContext with the given classloader.
     * @param ctx the context to associate to the classloader.
     * @param cl the classloader which is bind to the context.
     */
    void setComponentContext(Context ctx, ClassLoader cl);

    /**
     * Set the context used by client container (per JVM instead of per thread)
     * @param ctx the context to set
     */
    void setClientContainerComponentContext(Context ctx);

    /**
     * Return the CompNamingContext associated with the given classloader.
     * @param cl the classloader which is bind to the context.
     * @return the CompNamingContext associated with the given classloader.
     */
    Context getComponentContext(ClassLoader cl);

    /**
     * Remove the CompNamingContext associated with the given classloader.
     * @param cl the classloader which is bind to the context.
     */
    void unSetComponentContext(ClassLoader cl);

    /**
     * Gets the initial context
     * @return the initial context
     */
    InitialContext getInitialContext();

    /**
     * @return the environment associated to this initial context
     */
    Hashtable getEnv();
}
