/*
 * Copyright 1999-2002 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 javax.naming.*;
import javax.naming.spi.ResolveResult;

/**
  * Clients: deal only with names for its own naming service
  * and deals with single contexts that can be built up into
  * hierarchical naming systems.
  * Direct subclasses of AtomicContext must provide implementations for
  * the abstract a_ Context methods, and c_parseComponent().
  *
  * If the subclass implements the notion of implicit nns,
  * it must override the a_*_nns Context methods as well.
  *
  * @author Rosanna Lee
  *
  */

public abstract class AtomicContext extends ComponentContext {
    private static int debug = 0;

    protected AtomicContext () {
        _contextType = _ATOMIC;
    }

// ------ Abstract methods whose implementation are provided by subclasses


    /* Equivalent to Context methods */
    protected abstract Object a_lookup(String name, Continuation cont)
        throws NamingException;
    protected abstract Object a_lookupLink(String name, Continuation cont)
        throws NamingException;

    protected abstract NamingEnumeration a_list(
        Continuation cont) throws NamingException;
    protected abstract NamingEnumeration a_listBindings(
        Continuation cont) throws NamingException;
    protected abstract void a_bind(String name, Object obj, Continuation cont)
        throws NamingException;
    protected abstract void a_rebind(String name, Object obj, Continuation cont)
        throws NamingException;
    protected abstract void a_unbind(String name, Continuation cont)
        throws NamingException;
    protected abstract void a_destroySubcontext(String name, Continuation cont)
        throws NamingException;
    protected abstract Context a_createSubcontext(String name,
        Continuation cont) throws NamingException;
    protected abstract void a_rename(String oldname, Name newname,
        Continuation cont) throws NamingException;
    protected abstract NameParser a_getNameParser(Continuation cont)
        throws NamingException;

    /* Parsing */
    /**
     * Parse 'inputName' into two parts:
     * head: the first component in this name
     * tail: the rest of the unused name.
     *
     * Subclasses should provide an implementation for this method
     * which parses inputName using its own name syntax.
     */
    protected abstract StringHeadTail c_parseComponent(String inputName,
        Continuation cont) throws NamingException;


// ------ Methods that need to be overridden by subclass

    /* Resolution method for supporting federation */
    /**
      * Resolves the nns for 'name' when the named context is acting
      * as an intermediate context.
      *
      * For a system that supports junctions, this would be equilvalent to
      *         a_lookup(name, cont);
      * because for junctions, an intermediate slash simply signifies
      * a syntactic separator.
      *
      * For a system that supports implicit nns, this would be equivalent to
      *         a_lookup_nns(name, cont);
      * because for implicit nns, a slash always signifies the implicit nns,
      * regardless of whether it is intermediate or trailing.
      *
      * By default this method supports junctions, and also allows for an
      * implicit nns to be dynamically determined through the use of the
      * "nns" reference (see a_processJunction_nns()).
      * Contexts that implement implicit nns directly should provide an
      * appropriate override.
      */
    protected Object a_resolveIntermediate_nns(String name, Continuation cont)
        throws NamingException {
            try {
                final Object obj = a_lookup(name, cont);

                // Do not append "" to Continuation 'cont' even if set
                // because the intention is to ignore the nns

                //
                if (obj != null && getClass().isInstance(obj)) {
                    // If "obj" is in the same type as this object, it must
                    // not be a junction. Continue the lookup with "/".

                    cont.setContinueNNS(obj, name, this);
                    return null;

                } else if (obj != null && !(obj instanceof Context)) {
                    // obj is not even a context, so try to find its nns
                    // dynamically by constructing a Reference containing obj.
                    RefAddr addr = new RefAddr("nns") {
                        public Object getContent() {
                            return obj;
                        }
                        private static final long serialVersionUID =
                            -3399518522645918499L;
                    };
                    Reference ref = new Reference("java.lang.Object", addr);

                    // Resolved name has trailing slash to indicate nns
                    CompositeName resName = new CompositeName();
                    resName.add(name);
                    resName.add(""); // add trailing slash

                    // Set continuation leave it to
                    // PartialCompositeContext.getPCContext() to throw CPE.
                    // Do not use setContinueNNS() because we've already
                    // consumed "/" (i.e., moved it to resName).

                    cont.setContinue(ref, resName, this);
                    return null;

                } else {
                    return obj;
                }

            } catch (NamingException e) {
                e.appendRemainingComponent(""); // add nns back
                throw e;
            }
        }

    /* Equivalent of Context Methods for supporting nns */

    // The following methods are called when the DirContext methods
    // are invoked with a name that has a trailing slash.
    // For naming systems that support implicit nns,
    // the trailing slash signifies the implicit nns.
    // For such naming systems, override these a_*_nns methods.
    //
    // For naming systems that support junctions (explicit nns),
    // the trailing slash is meaningless because a junction does not
    // have an implicit nns.  The default implementation here
    // throws a NameNotFoundException for such names.
    // If a context wants to accept a trailing slash as having
    // the same meaning as the same name without a trailing slash,
    // then it should override these a_*_nns methods.


    protected Object a_lookup_nns(String name, Continuation cont)
        throws NamingException {
            a_processJunction_nns(name, cont);
            return null;
        }

    protected Object a_lookupLink_nns(String name, Continuation cont)
        throws NamingException {
            a_processJunction_nns(name, cont);
            return null;
        }

    protected NamingEnumeration a_list_nns(Continuation cont)
        throws NamingException {
            a_processJunction_nns(cont);
            return null;
        }
    protected NamingEnumeration a_listBindings_nns(Continuation cont)
        throws NamingException {
            a_processJunction_nns(cont);
            return null;
        }

    protected void a_bind_nns(String name, Object obj, Continuation cont)
        throws NamingException {
            a_processJunction_nns(name, cont);
        }

    protected void a_rebind_nns(String name, Object obj, Continuation cont)
        throws NamingException {
            a_processJunction_nns(name, cont);
        }

    protected void a_unbind_nns(String name, Continuation cont)
        throws NamingException {
            a_processJunction_nns(name, cont);
        }

    protected Context a_createSubcontext_nns(String name, Continuation cont)
        throws NamingException {
            a_processJunction_nns(name, cont);
            return null;
        }

    protected void a_destroySubcontext_nns(String name, Continuation cont)
        throws NamingException {
            a_processJunction_nns(name, cont);
        }

    protected void a_rename_nns(String oldname, Name newname, Continuation cont)
        throws NamingException {
            a_processJunction_nns(oldname, cont);
        }

    protected NameParser a_getNameParser_nns(Continuation cont)
        throws NamingException {
            a_processJunction_nns(cont);
            return null;
        }



    protected boolean isEmpty(String name) {
        return name == null || name.equals("");
    }

// ------ implementations of c_  and c_*_nns methods using
// ------ the corresponding a_ and a_*_nns methods

    /* Equivalent to methods in  Context interface */

    protected Object c_lookup(Name name, Continuation cont)
        throws NamingException {
            Object ret = null;
            if (resolve_to_penultimate_context(name, cont)) {
                ret = a_lookup(name.toString(), cont);
                if (ret != null && ret instanceof LinkRef) {
                    cont.setContinue(ret, name, this);
                    ret = null;
                }
            }
            return ret;
        }

    protected Object c_lookupLink(Name name, Continuation cont)
        throws NamingException {
            if (resolve_to_penultimate_context(name, cont)) {
                return a_lookupLink(name.toString(), cont);
            }
            return null;
        }

    protected NamingEnumeration c_list(Name name,
        Continuation cont) throws NamingException {
            if (resolve_to_context(name, cont)) {
                return a_list(cont);
            }
            return null;
        }

    protected NamingEnumeration c_listBindings(Name name,
        Continuation cont) throws NamingException {
            if (resolve_to_context(name, cont)) {
                return a_listBindings(cont);
            }
            return null;
        }

    protected void c_bind(Name name, Object obj, Continuation cont)
        throws NamingException {
            if (resolve_to_penultimate_context(name, cont))
                a_bind(name.toString(), obj, cont);
        }

    protected void c_rebind(Name name, Object obj, Continuation cont)
        throws NamingException {
            if (resolve_to_penultimate_context(name, cont))
                a_rebind(name.toString(), obj, cont);
        }

    protected void c_unbind(Name name, Continuation cont)
        throws NamingException {
            if (resolve_to_penultimate_context(name, cont))
                a_unbind(name.toString(), cont);
        }

    protected void c_destroySubcontext(Name name, Continuation cont)
        throws NamingException {
            if (resolve_to_penultimate_context(name, cont))
                a_destroySubcontext(name.toString(), cont);
        }

    protected Context c_createSubcontext(Name name,
        Continuation cont) throws NamingException {
            if (resolve_to_penultimate_context(name, cont))
                return a_createSubcontext(name.toString(), cont);
            else
                return null;
        }

    protected void c_rename(Name oldname, Name newname,
        Continuation cont) throws NamingException {
            if (resolve_to_penultimate_context(oldname, cont))
                 a_rename(oldname.toString(), newname, cont);
        }

    protected NameParser c_getNameParser(Name name,
        Continuation cont) throws NamingException {
            if (resolve_to_context(name, cont))
                return a_getNameParser(cont);
            return null;
        }

    /* The following are overridden only for AtomicContexts.
     * AtomicContext is used by PartialCompositeDirContext and ComponentDirContext
     * in the inheritance tree to make use of methods in
     * PartialCompositeContext and ComponentContext. We only want to use the
     * atomic forms when we're actually an atomic context.
     */

    /* From ComponentContext */

    protected Object c_resolveIntermediate_nns(Name name, Continuation cont)
        throws NamingException {
            if (_contextType == _ATOMIC) {
                Object ret = null;
                if (resolve_to_penultimate_context_nns(name, cont)) {
                    ret = a_resolveIntermediate_nns(name.toString(), cont);
                    if (ret != null && ret instanceof LinkRef) {
                        cont.setContinue(ret, name, this);
                        ret = null;
                    }
                }
                return ret;
            } else {
                // use ComponentContext
                return super.c_resolveIntermediate_nns(name, cont);
            }
        }

    /* Equivalent to methods in Context interface for nns */

    protected Object c_lookup_nns(Name name, Continuation cont)
        throws NamingException {
            if (_contextType == _ATOMIC) {
                Object ret = null;
                if (resolve_to_penultimate_context_nns(name, cont)) {
                    ret = a_lookup_nns(name.toString(), cont);
                    if (ret != null && ret instanceof LinkRef) {
                        cont.setContinue(ret, name, this);
                        ret = null;
                    }
                }
                return ret;
            } else {
                return super.c_lookup_nns(name, cont);
            }
        }

    protected Object c_lookupLink_nns(Name name, Continuation cont)
        throws NamingException {
            if (_contextType == _ATOMIC) {
                // %%% check logic
                resolve_to_nns_and_continue(name, cont);
                return null;
            } else {
                // use ComponentContext
                return super.c_lookupLink_nns(name, cont);
            }
        }

    protected NamingEnumeration c_list_nns(Name name,
        Continuation cont) throws NamingException {
            if (_contextType == _ATOMIC) {
                resolve_to_nns_and_continue(name, cont);
                return null;
            } else {
                // use ComponentContext
                return super.c_list_nns(name, cont);
            }
        }

    protected NamingEnumeration c_listBindings_nns(Name name,
        Continuation cont) throws NamingException {
            if (_contextType == _ATOMIC) {
                resolve_to_nns_and_continue(name, cont);
                return null;
            } else {
                // use ComponentContext
                return super.c_list_nns(name, cont);
            }
        }

    protected void c_bind_nns(Name name, Object obj, Continuation cont)
        throws NamingException {
            if (_contextType == _ATOMIC) {
                if (resolve_to_penultimate_context_nns(name, cont))
                    a_bind_nns(name.toString(), obj, cont);
            } else {
                // use ComponentContext
                super.c_bind_nns(name, obj, cont);
            }
        }

    protected void c_rebind_nns(Name name, Object obj, Continuation cont)
        throws NamingException {
            if (_contextType == _ATOMIC) {
                if (resolve_to_penultimate_context_nns(name, cont))
                    a_rebind_nns(name.toString(), obj, cont);
            } else {
                // use ComponentContext
                super.c_rebind_nns(name, obj, cont);
            }
        }

    protected void c_unbind_nns(Name name, Continuation cont)
        throws NamingException {
            if (_contextType == _ATOMIC) {
                if (resolve_to_penultimate_context_nns(name, cont))
                    a_unbind_nns(name.toString(), cont);
            } else {
                // use ComponentContext
                super.c_unbind_nns(name, cont);
            }
        }

    protected Context c_createSubcontext_nns(Name name,
        Continuation cont) throws NamingException {
            if (_contextType == _ATOMIC) {
                if (resolve_to_penultimate_context_nns(name, cont))
                    return a_createSubcontext_nns(name.toString(), cont);
                else
                    return null;
            } else {
                // use ComponentContext
                return super.c_createSubcontext_nns(name, cont);
            }
        }

    protected void c_destroySubcontext_nns(Name name, Continuation cont)
        throws NamingException {
            if (_contextType == _ATOMIC) {
                if (resolve_to_penultimate_context_nns(name, cont))
                    a_destroySubcontext_nns(name.toString(), cont);
            } else {
                // use ComponentContext
                super.c_destroySubcontext_nns(name, cont);
            }
        }

    protected void c_rename_nns(Name oldname, Name newname, Continuation cont)
        throws NamingException {
            if (_contextType == _ATOMIC) {
                if (resolve_to_penultimate_context_nns(oldname, cont))
                    a_rename_nns(oldname.toString(), newname, cont);
            } else {
                // use ComponentContext
                super.c_rename_nns(oldname, newname, cont);
            }
        }

    protected NameParser c_getNameParser_nns(Name name, Continuation cont)
        throws NamingException {
            if (_contextType == _ATOMIC) {
                resolve_to_nns_and_continue(name, cont);
                return null;
            } else {
                // use COmponentContext
                return super.c_getNameParser_nns(name, cont);
            }
        }

// --------------    internal methods used by this class

    /* Handles nns for junctions */
    /**
      * This function is used when implementing a naming system that
      * supports junctions.  For example, when the a_bind_nns(name, newobj)
      * method is invoked, that means the caller is attempting to bind the
      * object 'newobj' to the nns of 'name'.  For context that supports
      * junctions, 'name' names a junction and is pointing to the root
      * of another naming system, which in turn might have an nns.
      * This means that a_bind_nns() should first resolve 'name' and attempt to
      * continue the operation in the context named by 'name'.  (i.e. bind
      * to the nns of the context named by 'name').
      * If name is already empty, then throw NameNotFoundException because
      * this context by default does not have any nns.
      */
    protected void a_processJunction_nns(String name, Continuation cont)
        throws NamingException {
            if (name.equals("")) {
                NameNotFoundException e = new NameNotFoundException();
                cont.setErrorNNS(this, name);
                throw cont.fillInException(e);
            }
            try {
                // lookup name to continue operation in nns
                Object target = a_lookup(name, cont);
                if (cont.isContinue())
                    cont.appendRemainingComponent("");  // add nns back
                else {
                    cont.setContinueNNS(target, name, this);
                }
            } catch (NamingException e) {
                e.appendRemainingComponent(""); // add nns back
                throw e;
            }
        }

    /**
      * This function is used when implementing a naming system that
      * supports junctions.  For example, when the a_list_nns(newobj)
      * method is invoked, that means the caller is attempting to list the
      * the nns context of of this context.  For a context that supports
      * junctions, it by default does not have any nns.  Consequently,
      * a NameNotFoundException is thrown.
      */
    protected void a_processJunction_nns(Continuation cont) throws NamingException {

        // Construct a new Reference that contains this context.
        RefAddr addr = new RefAddr("nns") {
            public Object getContent() {
                return AtomicContext.this;
            }
            private static final long serialVersionUID = 3449785852664978312L;
        };
        Reference ref = new Reference("java.lang.Object", addr);

        // Set continuation leave it to PartialCompositeContext.getPCContext()
        // to throw the exception.
        // Do not use setContinueNNS() because we've are
        // setting relativeResolvedName to "/".
        cont.setContinue(ref, _NNS_NAME, this);
    }

    /* *********** core resolution routines ******************* */

    /** Resolve to context named by 'name'.
      * Returns true if at named context (i.e. 'name' is empty name).
      * Returns false otherwise, and sets Continuation on parts of 'name'
      * not yet resolved.
      */
    protected boolean resolve_to_context(Name name, Continuation cont)
    throws NamingException {
        String target = name.toString();


        StringHeadTail ht = c_parseComponent(target, cont);
        String tail = ht.getTail();
        String head = ht.getHead();

        if (debug > 0)
            System.out.println("RESOLVE TO CONTEXT(" + target + ") = {" +
                               head + ", " + tail + "}");

        if (head == null) {
            // something is wrong; no name at all
            InvalidNameException e = new InvalidNameException();
            throw cont.fillInException(e);
        }
        if (!isEmpty(head)) {
            // if there is head is a non-empty name
            // this means more resolution to be done
            try {
                Object headCtx = a_lookup(head, cont);
//              System.out.println("answer " + headCtx);
                if (headCtx != null)
                    cont.setContinue(headCtx, head, this, (tail == null ? "" : tail));
                else if (cont.isContinue())
                    cont.appendRemainingComponent(tail);
            } catch (NamingException e) {
                e.appendRemainingComponent(tail);
                throw e;
            }
        } else {
            cont.setSuccess();  // clear
            return true;
        }
        return false;
    }

    /**
      * Resolves to penultimate context named by 'name'.
      * Returns true if penultimate context has been reached (i.e. name
      * only has one atomic component left).
      * Returns false otherwise, and sets Continuation to parts of name
      * not yet resolved.
      */
    protected boolean resolve_to_penultimate_context(Name name, Continuation cont)
    throws NamingException {
        String target = name.toString();

        if (debug > 0)
            System.out.println("RESOLVE TO PENULTIMATE" + target);

        StringHeadTail ht = c_parseComponent(target, cont);
        String tail = ht.getTail();
        String head = ht.getHead();
        if (head == null) {
            // something is wrong; no name at all
            InvalidNameException e = new InvalidNameException();
            throw cont.fillInException(e);
        }

        if (!isEmpty(tail)) {
            // more components; hence not at penultimate context yet
            try {
                Object headCtx = a_lookup(head, cont);
                if (headCtx != null)
                    cont.setContinue(headCtx, head, this, tail);
                else if (cont.isContinue())
                    cont.appendRemainingComponent(tail);
            } catch (NamingException e) {
                e.appendRemainingComponent(tail);
                throw e;
            }
        } else {
            // already at penultimate context
            cont.setSuccess();  // clear
            return true;
        }
        return false;
    }

    /**
      * This function is similar to resolve_to_penultimate_context()
      * except it should only be called by the nns() functions.
      * This function fixes any exception or continuations so that
      * it will have the proper nns name.
      */
    protected boolean resolve_to_penultimate_context_nns(Name name,
                                                         Continuation cont)
        throws NamingException {
            try {
        if (debug > 0)
            System.out.println("RESOLVE TO PENULTIMATE NNS" + name.toString());
                boolean answer = resolve_to_penultimate_context(name, cont);

                // resolve_to_penultimate_context() only calls a_lookup().
                // Any continuation it sets is lacking the nns, so
                // we need to add it back
                if (cont.isContinue())
                    cont.appendRemainingComponent("");

                return answer;
            } catch (NamingException e) {
                // resolve_to_penultimate_context() only calls a_lookup().
                // Any exceptions it throws is lacking the nns, so
                // we need to add it back.
                e.appendRemainingComponent("");
                throw e;
            }
        }

    /**
      * Resolves to nns associated with 'name' and set Continuation
      * to the result.
      */
    protected void resolve_to_nns_and_continue(Name name, Continuation cont)
        throws NamingException {
        if (debug > 0)
            System.out.println("RESOLVE TO NNS AND CONTINUE" + name.toString());

        if (resolve_to_penultimate_context_nns(name, cont)) {
            Object nns = a_lookup_nns(name.toString(), cont);
            if (nns != null)
                cont.setContinue(nns, name, this);
        }
    }
}
