/*
 * Copyright 1999-2004 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package com.sun.jndi.toolkit.ctx;

import java.util.Hashtable;
import java.util.Enumeration;

import javax.naming.*;
import javax.naming.spi.Resolver;
import javax.naming.spi.ResolveResult;
import javax.naming.spi.NamingManager;

/**
  * PartialCompositeContext implements Context operations on
  * composite names using implementations of the p_ interfaces
  * defined by its subclasses.
  *
  * The main purpose provided by this class is that it deals with
  * partial resolutions and continuations, so that callers of the
  * Context operation don't have to.
  *
  * Types of clients that will be direct subclasses of
  * PartialCompositeContext may be service providers that implement
  * one of the JNDI protocols, but which do not deal with
  * continuations.  Usually, service providers will be using
  * one of the subclasses of PartialCompositeContext.
  *
  * @author Rosanna Lee
  */


public abstract class PartialCompositeContext implements Context, Resolver {
    protected static final int _PARTIAL = 1;
    protected static final int _COMPONENT = 2;
    protected static final int _ATOMIC = 3;

    protected int _contextType = _PARTIAL;

    static final CompositeName _EMPTY_NAME = new CompositeName();
    static CompositeName _NNS_NAME;

    static {
        try {
            _NNS_NAME = new CompositeName("/");
        } catch (InvalidNameException e) {
            // Should never happen
        }
    }

    protected PartialCompositeContext() {
    }

// ------ Abstract methods whose implementations come from subclasses

    /* Equivalent to method in  Resolver interface */
    protected abstract ResolveResult p_resolveToClass(Name name,
        Class contextType, Continuation cont) throws NamingException;

    /* Equivalent to methods in Context interface */
    protected abstract Object p_lookup(Name name, Continuation cont)
        throws NamingException;
    protected abstract Object p_lookupLink(Name name, Continuation cont)
        throws NamingException;
    protected abstract NamingEnumeration p_list(Name name,
        Continuation cont) throws NamingException;
    protected abstract NamingEnumeration p_listBindings(Name name,
        Continuation cont) throws NamingException;
    protected abstract void p_bind(Name name, Object obj, Continuation cont)
        throws NamingException;
    protected abstract void p_rebind(Name name, Object obj, Continuation cont)
        throws NamingException;
    protected abstract void p_unbind(Name name, Continuation cont)
        throws NamingException;
    protected abstract void p_destroySubcontext(Name name, Continuation cont)
        throws NamingException;
    protected abstract Context p_createSubcontext(Name name, Continuation cont)
        throws NamingException;
    protected abstract void p_rename(Name oldname, Name newname,
                                     Continuation cont)
        throws NamingException;
    protected abstract NameParser p_getNameParser(Name name, Continuation cont)
        throws NamingException;

// ------ should be overridden by subclass;
// ------ not abstract only for backward compatibility

    /**
     * A cheap way of getting the environment.
     * Default implemenation is NOT cheap because it simply calls
     * getEnvironment(), which most implementations clone before returning.
     * Subclass should ALWAYS override this with the cheapest possible way.
     * The toolkit knows to clone when necessary.
     * @return The possibly null environment of the context.
     */
    protected Hashtable p_getEnvironment() throws NamingException {
        return getEnvironment();
    }


// ------ implementations of methods in Resolver and Context
// ------ using corresponding p_ methods provided by subclass

    /* implementations for method in Resolver interface using p_ method */

    public ResolveResult resolveToClass(String name,
                                        Class<? extends Context> contextType)
        throws NamingException
    {
        return resolveToClass(new CompositeName(name), contextType);
    }

    public ResolveResult resolveToClass(Name name,
                                        Class<? extends Context> contextType)
        throws NamingException
    {
        PartialCompositeContext ctx = this;
        Hashtable env = p_getEnvironment();
        Continuation cont = new Continuation(name, env);
        ResolveResult answer;
        Name nm = name;

        try {
            answer = ctx.p_resolveToClass(nm, contextType, cont);
            while (cont.isContinue()) {
                nm = cont.getRemainingName();
                ctx = getPCContext(cont);
                answer = ctx.p_resolveToClass(nm, contextType, cont);
            }
        } catch (CannotProceedException e) {
            Context cctx = NamingManager.getContinuationContext(e);
            if (!(cctx instanceof Resolver)) {
                throw e;
            }
            answer = ((Resolver)cctx).resolveToClass(e.getRemainingName(),
                                                     contextType);
        }
        return answer;
    }

    /* implementations for methods in Context interface using p_ methods */

    public Object lookup(String name) throws NamingException {
        return lookup(new CompositeName(name));
    }

    public Object lookup(Name name) throws NamingException {
        PartialCompositeContext ctx = this;
        Hashtable env = p_getEnvironment();
        Continuation cont = new Continuation(name, env);
        Object answer;
        Name nm = name;

        try {
            answer = ctx.p_lookup(nm, cont);
            while (cont.isContinue()) {
                nm = cont.getRemainingName();
                ctx = getPCContext(cont);
                answer = ctx.p_lookup(nm, cont);
            }
        } catch (CannotProceedException e) {
            Context cctx = NamingManager.getContinuationContext(e);
            answer = cctx.lookup(e.getRemainingName());
        }
        return answer;
    }

    public void bind(String name, Object newObj) throws NamingException {
        bind(new CompositeName(name), newObj);
    }

    public void bind(Name name, Object newObj) throws NamingException {
        PartialCompositeContext ctx = this;
        Name nm = name;
        Hashtable env = p_getEnvironment();
        Continuation cont = new Continuation(name, env);

        try {
            ctx.p_bind(nm, newObj, cont);
            while (cont.isContinue()) {
                nm = cont.getRemainingName();
                ctx = getPCContext(cont);
                ctx.p_bind(nm, newObj, cont);
            }
        } catch (CannotProceedException e) {
            Context cctx = NamingManager.getContinuationContext(e);
            cctx.bind(e.getRemainingName(), newObj);
        }
    }

    public void rebind(String name, Object newObj) throws NamingException {
        rebind(new CompositeName(name), newObj);
    }
    public void rebind(Name name, Object newObj) throws NamingException {
        PartialCompositeContext ctx = this;
        Name nm = name;
        Hashtable env = p_getEnvironment();
        Continuation cont = new Continuation(name, env);

        try {
            ctx.p_rebind(nm, newObj, cont);
            while (cont.isContinue()) {
                nm = cont.getRemainingName();
                ctx = getPCContext(cont);
                ctx.p_rebind(nm, newObj, cont);
            }
        } catch (CannotProceedException e) {
            Context cctx = NamingManager.getContinuationContext(e);
            cctx.rebind(e.getRemainingName(), newObj);
        }
    }

    public void unbind(String name) throws NamingException {
        unbind(new CompositeName(name));
    }
    public void unbind(Name name) throws NamingException {
        PartialCompositeContext ctx = this;
        Name nm = name;
        Hashtable env = p_getEnvironment();
        Continuation cont = new Continuation(name, env);

        try {
            ctx.p_unbind(nm, cont);
            while (cont.isContinue()) {
                nm = cont.getRemainingName();
                ctx = getPCContext(cont);
                ctx.p_unbind(nm, cont);
            }
        } catch (CannotProceedException e) {
            Context cctx = NamingManager.getContinuationContext(e);
            cctx.unbind(e.getRemainingName());
        }
    }

    public void rename(String oldName, String newName) throws NamingException {
        rename(new CompositeName(oldName), new CompositeName(newName));
    }
    public void rename(Name oldName, Name newName)
        throws NamingException
    {
        PartialCompositeContext ctx = this;
        Name nm = oldName;
        Hashtable env = p_getEnvironment();
        Continuation cont = new Continuation(oldName, env);

        try {
            ctx.p_rename(nm, newName, cont);
            while (cont.isContinue()) {
                nm = cont.getRemainingName();
                ctx = getPCContext(cont);
                ctx.p_rename(nm, newName, cont);
            }
        } catch (CannotProceedException e) {
            Context cctx = NamingManager.getContinuationContext(e);
            if (e.getRemainingNewName() != null) {
                // %%% e.getRemainingNewName() should never be null
                newName = e.getRemainingNewName();
            }
            cctx.rename(e.getRemainingName(), newName);
        }
    }

    public NamingEnumeration<NameClassPair> list(String name)
        throws NamingException
    {
        return list(new CompositeName(name));
    }

    public NamingEnumeration<NameClassPair> list(Name name)
        throws NamingException
    {
        PartialCompositeContext ctx = this;
        Name nm = name;
        NamingEnumeration answer;
        Hashtable env = p_getEnvironment();
        Continuation cont = new Continuation(name, env);

        try {
            answer = ctx.p_list(nm, cont);
            while (cont.isContinue()) {
                nm = cont.getRemainingName();
                ctx = getPCContext(cont);
                answer = ctx.p_list(nm, cont);
            }
        } catch (CannotProceedException e) {
            Context cctx = NamingManager.getContinuationContext(e);
            answer = cctx.list(e.getRemainingName());
        }
        return answer;
    }

    public NamingEnumeration<Binding> listBindings(String name)
        throws NamingException
    {
        return listBindings(new CompositeName(name));
    }

    public NamingEnumeration<Binding> listBindings(Name name)
        throws NamingException
    {
        PartialCompositeContext ctx = this;
        Name nm = name;
        NamingEnumeration answer;
        Hashtable env = p_getEnvironment();
        Continuation cont = new Continuation(name, env);

        try {
            answer = ctx.p_listBindings(nm, cont);
            while (cont.isContinue()) {
                nm = cont.getRemainingName();
                ctx = getPCContext(cont);
                answer = ctx.p_listBindings(nm, cont);
            }
        } catch (CannotProceedException e) {
            Context cctx = NamingManager.getContinuationContext(e);
            answer = cctx.listBindings(e.getRemainingName());
        }
        return answer;
    }

    public void destroySubcontext(String name) throws NamingException {
        destroySubcontext(new CompositeName(name));
    }

    public void destroySubcontext(Name name) throws NamingException {
        PartialCompositeContext ctx = this;
        Name nm = name;
        Hashtable env = p_getEnvironment();
        Continuation cont = new Continuation(name, env);

        try {
            ctx.p_destroySubcontext(nm, cont);
            while (cont.isContinue()) {
                nm = cont.getRemainingName();
                ctx = getPCContext(cont);
                ctx.p_destroySubcontext(nm, cont);
            }
        } catch (CannotProceedException e) {
            Context cctx = NamingManager.getContinuationContext(e);
            cctx.destroySubcontext(e.getRemainingName());
        }
    }

    public Context createSubcontext(String name) throws NamingException {
        return createSubcontext(new CompositeName(name));
    }

    public Context createSubcontext(Name name) throws NamingException {
        PartialCompositeContext ctx = this;
        Name nm = name;
        Context answer;
        Hashtable env = p_getEnvironment();
        Continuation cont = new Continuation(name, env);

        try {
            answer = ctx.p_createSubcontext(nm, cont);
            while (cont.isContinue()) {
                nm = cont.getRemainingName();
                ctx = getPCContext(cont);
                answer = ctx.p_createSubcontext(nm, cont);
            }
        } catch (CannotProceedException e) {
            Context cctx = NamingManager.getContinuationContext(e);
            answer = cctx.createSubcontext(e.getRemainingName());
        }
        return answer;
    }

    public Object lookupLink(String name) throws NamingException {
        return lookupLink(new CompositeName(name));
    }

    public Object lookupLink(Name name) throws NamingException {
        PartialCompositeContext ctx = this;
        Hashtable env = p_getEnvironment();
        Continuation cont = new Continuation(name, env);
        Object answer;
        Name nm = name;

        try {
            answer = ctx.p_lookupLink(nm, cont);
            while (cont.isContinue()) {
                nm = cont.getRemainingName();
                ctx = getPCContext(cont);
                answer = ctx.p_lookupLink(nm, cont);
            }
        } catch (CannotProceedException e) {
            Context cctx = NamingManager.getContinuationContext(e);
            answer = cctx.lookupLink(e.getRemainingName());
        }
        return answer;
    }

    public NameParser getNameParser(String name) throws NamingException {
        return getNameParser(new CompositeName(name));
    }

    public NameParser getNameParser(Name name) throws NamingException {
        PartialCompositeContext ctx = this;
        Name nm = name;
        NameParser answer;
        Hashtable env = p_getEnvironment();
        Continuation cont = new Continuation(name, env);

        try {
            answer = ctx.p_getNameParser(nm, cont);
            while (cont.isContinue()) {
                nm = cont.getRemainingName();
                ctx = getPCContext(cont);
                answer = ctx.p_getNameParser(nm, cont);
            }
        } catch (CannotProceedException e) {
            Context cctx = NamingManager.getContinuationContext(e);
            answer = cctx.getNameParser(e.getRemainingName());
        }
        return answer;
    }

    public String composeName(String name, String prefix)
            throws NamingException {
        Name fullName = composeName(new CompositeName(name),
                                    new CompositeName(prefix));
        return fullName.toString();
    }

    /**
     * This default implementation simply concatenates the two names.
     * There's one twist when the "java.naming.provider.compose.elideEmpty"
     * environment setting is set to "true":  if each name contains a
     * nonempty component, and if 'prefix' ends with an empty component or
     * 'name' starts with one, then one empty component is dropped.
     * For example:
     * <pre>
     *                            elideEmpty=false     elideEmpty=true
     * {"a"} + {"b"}          =>  {"a", "b"}           {"a", "b"}
     * {"a"} + {""}           =>  {"a", ""}            {"a", ""}
     * {"a"} + {"", "b"}      =>  {"a", "", "b"}       {"a", "b"}
     * {"a", ""} + {"b", ""}  =>  {"a", "", "b", ""}   {"a", "b", ""}
     * {"a", ""} + {"", "b"}  =>  {"a", "", "", "b"}   {"a", "", "b"}
     * </pre>
     */
    public Name composeName(Name name, Name prefix) throws NamingException {
        Name res = (Name)prefix.clone();
        if (name == null) {
            return res;
        }
        res.addAll(name);

        String elide = (String)
            p_getEnvironment().get("java.naming.provider.compose.elideEmpty");
        if (elide == null || !elide.equalsIgnoreCase("true")) {
            return res;
        }

        int len = prefix.size();

        if (!allEmpty(prefix) && !allEmpty(name)) {
            if (res.get(len - 1).equals("")) {
                res.remove(len - 1);
            } else if (res.get(len).equals("")) {
                res.remove(len);
            }
        }
        return res;
    }


// ------ internal methods used by PartialCompositeContext

    /**
     * Tests whether a name contains a nonempty component.
     */
    protected static boolean allEmpty(Name name) {
        Enumeration enum_ = name.getAll();
        while (enum_.hasMoreElements()) {
            if (!enum_.equals("")) {
                return false;
            }
        }
        return true;
    }

    /**
     * Retrieves a PartialCompositeContext for the resolved object in
     * cont.  Throws CannotProceedException if not successful.
     */
    protected static PartialCompositeContext getPCContext(Continuation cont)
            throws NamingException {

        Object obj = cont.getResolvedObj();
        PartialCompositeContext pctx = null;

        if (obj instanceof PartialCompositeContext) {
            // Just cast if octx already is PartialCompositeContext
            // %%% ignoring environment for now
            return (PartialCompositeContext)obj;
        } else {
            throw cont.fillInException(new CannotProceedException());
        }
    }
};
