/*
 * Copyright (c) 1999, 2002, Oracle and/or its affiliates. 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.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);
        }
    }
}
