/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights 
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:  
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written 
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, Lotus
 * Development Corporation., http://www.lotus.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
package org.apache.xml.utils;

import java.util.EmptyStackException;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

/**
 * Encapsulate Namespace tracking logic for use by SAX drivers.
 *
 * <p>This class is an attempt to rewrite the SAX NamespaceSupport
 * "helper" class for improved efficiency. It can be used to track the
 * namespace declarations currently in scope, providing lookup
 * routines to map prefixes to URIs and vice versa.</p>
 *
 * <p>ISSUE: For testing purposes, I've extended NamespaceSupport even
 * though I'm completely reasserting all behaviors and fields.
 * Wasteful.... But SAX did not put an interface under that object and
 * we seem to have written that SAX class into our APIs... and I don't
 * want to argue with it right now. </p>
 *
 * @see org.xml.sax.helpers.NamespaceSupport
 * */
public class NamespaceSupport2
    extends org.xml.sax.helpers.NamespaceSupport
{
    ////////////////////////////////////////////////////////////////////
    // Internal state.
    ////////////////////////////////////////////////////////////////////

    private Context2 currentContext; // Current point on the double-linked stack


    ////////////////////////////////////////////////////////////////////
    // Constants.
    ////////////////////////////////////////////////////////////////////


    /**
     * The XML Namespace as a constant.
     *
     * <p>This is the Namespace URI that is automatically mapped
     * to the "xml" prefix.</p>
     */
    public final static String XMLNS =
        "http://www.w3.org/XML/1998/namespace";


    ////////////////////////////////////////////////////////////////////
    // Constructor.
    ////////////////////////////////////////////////////////////////////


    /**
     * Create a new Namespace support object.
     */
    public NamespaceSupport2 ()
    {
        reset();
    }


    ////////////////////////////////////////////////////////////////////
    // Context management.
    ////////////////////////////////////////////////////////////////////


    /**
     * Reset this Namespace support object for reuse.
     *
     * <p>It is necessary to invoke this method before reusing the
     * Namespace support object for a new session.</p>
     */
    public void reset ()
    {
        // Discarding the whole stack doesn't save us a lot versus
        // creating a new NamespaceSupport. Do we care, or should we
        // change this to just reset the root context?
        currentContext = new Context2(null);
        currentContext.declarePrefix("xml", XMLNS);
    }


    /**
     * Start a new Namespace context.
     *
     * <p>Normally, you should push a new context at the beginning
     * of each XML element: the new context will automatically inherit
     * the declarations of its parent context, but it will also keep
     * track of which declarations were made within this context.</p>
     *
     * <p>The Namespace support object always starts with a base context
     * already in force: in this context, only the "xml" prefix is
     * declared.</p>
     *
     * @see #popContext
     */
    public void pushContext ()
    {
        // JJK: Context has a parent pointer.
        // That means we don't need a stack to pop.
        // We may want to retain for reuse, but that can be done via
        // a child pointer.

        Context2 parentContext=currentContext;
        currentContext = parentContext.getChild();
        if (currentContext == null){
                currentContext = new Context2(parentContext);
            }
        else{
            // JJK: This will wipe out any leftover data
            // if we're reusing a previously allocated Context.
            currentContext.setParent(parentContext);
        }
    }


    /**
     * Revert to the previous Namespace context.
     *
     * <p>Normally, you should pop the context at the end of each
     * XML element.  After popping the context, all Namespace prefix
     * mappings that were previously in force are restored.</p>
     *
     * <p>You must not attempt to declare additional Namespace
     * prefixes after popping a context, unless you push another
     * context first.</p>
     *
     * @see #pushContext
     */
    public void popContext ()
    {
        Context2 parentContext=currentContext.getParent();
        if(parentContext==null)
            throw new EmptyStackException();
        else
            currentContext = parentContext;
    }



    ////////////////////////////////////////////////////////////////////
    // Operations within a context.
    ////////////////////////////////////////////////////////////////////


    /**
     * Declare a Namespace prefix.
     *
     * <p>This method declares a prefix in the current Namespace
     * context; the prefix will remain in force until this context
     * is popped, unless it is shadowed in a descendant context.</p>
     *
     * <p>To declare a default Namespace, use the empty string.  The
     * prefix must not be "xml" or "xmlns".</p>
     *
     * <p>Note that you must <em>not</em> declare a prefix after
     * you've pushed and popped another Namespace.</p>
     *
     * <p>Note that there is an asymmetry in this library: while {@link
     * #getPrefix getPrefix} will not return the default "" prefix,
     * even if you have declared one; to check for a default prefix,
     * you have to look it up explicitly using {@link #getURI getURI}.
     * This asymmetry exists to make it easier to look up prefixes
     * for attribute names, where the default prefix is not allowed.</p>
     *
     * @param prefix The prefix to declare, or null for the empty
     *        string.
     * @param uri The Namespace URI to associate with the prefix.
     * @return true if the prefix was legal, false otherwise
     * @see #processName
     * @see #getURI
     * @see #getPrefix
     */
    public boolean declarePrefix (String prefix, String uri)
    {
        if (prefix.equals("xml") || prefix.equals("xmlns")) {
            return false;
        } else {
            currentContext.declarePrefix(prefix, uri);
            return true;
        }
    }


    /**
     * Process a raw XML 1.0 name.
     *
     * <p>This method processes a raw XML 1.0 name in the current
     * context by removing the prefix and looking it up among the
     * prefixes currently declared.  The return value will be the
     * array supplied by the caller, filled in as follows:</p>
     *
     * <dl>
     * <dt>parts[0]</dt>
     * <dd>The Namespace URI, or an empty string if none is
     *  in use.</dd>
     * <dt>parts[1]</dt>
     * <dd>The local name (without prefix).</dd>
     * <dt>parts[2]</dt>
     * <dd>The original raw name.</dd>
     * </dl>
     *
     * <p>All of the strings in the array will be internalized.  If
     * the raw name has a prefix that has not been declared, then
     * the return value will be null.</p>
     *
     * <p>Note that attribute names are processed differently than
     * element names: an unprefixed element name will received the
     * default Namespace (if any), while an unprefixed element name
     * will not.</p>
     *
     * @param qName The raw XML 1.0 name to be processed.
     * @param parts A string array supplied by the caller, capable of
     *        holding at least three members.
     * @param isAttribute A flag indicating whether this is an
     *        attribute name (true) or an element name (false).
     * @return The supplied array holding three internalized strings 
     *        representing the Namespace URI (or empty string), the
     *        local name, and the raw XML 1.0 name; or null if there
     *        is an undeclared prefix.
     * @see #declarePrefix
     * @see java.lang.String#intern */
    public String [] processName (String qName, String[] parts,
                                  boolean isAttribute)
    {
        String[] name=currentContext.processName(qName, isAttribute);
        if(name==null)
            return null;

        // JJK: This recopying is required because processName may return
        // a cached result. I Don't Like It. *****
        System.arraycopy(name,0,parts,0,3);
        return parts;
    }


    /**
     * Look up a prefix and get the currently-mapped Namespace URI.
     *
     * <p>This method looks up the prefix in the current context.
     * Use the empty string ("") for the default Namespace.</p>
     *
     * @param prefix The prefix to look up.
     * @return The associated Namespace URI, or null if the prefix
     *         is undeclared in this context.
     * @see #getPrefix
     * @see #getPrefixes
     */
    public String getURI (String prefix)
    {
        return currentContext.getURI(prefix);
    }


    /**
     * Return an enumeration of all prefixes currently declared.
     *
     * <p><strong>Note:</strong> if there is a default prefix, it will not be
     * returned in this enumeration; check for the default prefix
     * using the {@link #getURI getURI} with an argument of "".</p>
     *
     * @return An enumeration of all prefixes declared in the
     *         current context except for the empty (default)
     *         prefix.
     * @see #getDeclaredPrefixes
     * @see #getURI
     */
    public Enumeration getPrefixes ()
    {
        return currentContext.getPrefixes();
    }


    /**
     * Return one of the prefixes mapped to a Namespace URI.
     *
     * <p>If more than one prefix is currently mapped to the same
     * URI, this method will make an arbitrary selection; if you
     * want all of the prefixes, use the {@link #getPrefixes}
     * method instead.</p>
     *
     * <p><strong>Note:</strong> this will never return the empty
     * (default) prefix; to check for a default prefix, use the {@link
     * #getURI getURI} method with an argument of "".</p>
     *
     * @param uri The Namespace URI.
     * @return One of the prefixes currently mapped to the URI supplied,
     *         or null if none is mapped or if the URI is assigned to
     *         the default Namespace.
     * @see #getPrefixes(java.lang.String)
     * @see #getURI */
    public String getPrefix (String uri)
    {
        return currentContext.getPrefix(uri);
    }


    /**
     * Return an enumeration of all prefixes currently declared for a URI.
     *
     * <p>This method returns prefixes mapped to a specific Namespace
     * URI.  The xml: prefix will be included.  If you want only one
     * prefix that's mapped to the Namespace URI, and you don't care 
     * which one you get, use the {@link #getPrefix getPrefix}
     *  method instead.</p>
     *
     * <p><strong>Note:</strong> the empty (default) prefix is
     * <em>never</em> included in this enumeration; to check for the
     * presence of a default Namespace, use the {@link #getURI getURI}
     * method with an argument of "".</p>
     *
     * @param uri The Namespace URI.
     * @return An enumeration of all prefixes declared in the
     *         current context.
     * @see #getPrefix
     * @see #getDeclaredPrefixes
     * @see #getURI */
    public Enumeration getPrefixes (String uri)
    {
        // JJK: The old code involved creating a vector, filling it
        // with all the matching prefixes, and then getting its
        // elements enumerator. Wastes storage, wastes cycles if we
        // don't actually need them all. Better to either implement
        // a specific enumerator for these prefixes... or a filter
        // around the all-prefixes enumerator, which comes out to
        // roughly the same thing.
        //
        // **** Currently a filter. That may not be most efficient
        // when I'm done restructuring storage!
        return new PrefixForUriEnumerator(this,uri,getPrefixes());       
    }
    

    /**
     * Return an enumeration of all prefixes declared in this context.
     *
     * <p>The empty (default) prefix will be included in this 
     * enumeration; note that this behaviour differs from that of
     * {@link #getPrefix} and {@link #getPrefixes}.</p>
     *
     * @return An enumeration of all prefixes declared in this
     *         context.
     * @see #getPrefixes
     * @see #getURI
     */
    public Enumeration getDeclaredPrefixes ()
    {
        return currentContext.getDeclaredPrefixes();
    }



}

////////////////////////////////////////////////////////////////////
// Local classes.
// These were _internal_ classes... but in fact they don't have to be,
// and may be more efficient if they aren't. 
////////////////////////////////////////////////////////////////////

/**
 * Implementation of Enumeration filter, wrapped
 * aroung the get-all-prefixes version of the operation. This is NOT
 * necessarily the most efficient approach; finding the URI and then asking
 * what prefixes apply to it might make much more sense.
 */
class PrefixForUriEnumerator implements Enumeration
{
    private Enumeration allPrefixes;
    private String uri;
    private String lookahead=null;
    private NamespaceSupport2 nsup;
     
    // Kluge: Since one can't do a constructor on an
    // anonymous class (as far as I know)...
    PrefixForUriEnumerator(NamespaceSupport2 nsup,String uri, Enumeration allPrefixes)
    {
	this.nsup=nsup;
        this.uri=uri;
        this.allPrefixes=allPrefixes;
    }
        
    public boolean hasMoreElements()
    {
        if(lookahead!=null)
            return true;
            
        while(allPrefixes.hasMoreElements())
            {
                String prefix=(String)allPrefixes.nextElement();
                if(uri.equals(nsup.getURI(prefix)))
                    {
                        lookahead=prefix;
                        return true;
                    }
            }
        return false;
    }
        
    public Object nextElement()
    {
        if(hasMoreElements())
            {
                String tmp=lookahead;
                lookahead=null;
                return tmp;
            }
        else
            throw new java.util.NoSuchElementException();
    }
}

/**
 * Internal class for a single Namespace context.
 *
 * <p>This module caches and reuses Namespace contexts, so the number allocated
 * will be equal to the element depth of the document, not to the total
 * number of elements (i.e. 5-10 rather than tens of thousands).</p>
 */
final class Context2 {

    ////////////////////////////////////////////////////////////////
    // Manefest Constants
    ////////////////////////////////////////////////////////////////
        
    /**
     * An empty enumeration.
     */
    private final static Enumeration EMPTY_ENUMERATION =
        new Vector().elements();

    ////////////////////////////////////////////////////////////////
    // Protected state.
    ////////////////////////////////////////////////////////////////
        
    Hashtable prefixTable;
    Hashtable uriTable;
    Hashtable elementNameTable;
    Hashtable attributeNameTable;
    String defaultNS = null;

    ////////////////////////////////////////////////////////////////
    // Internal state.
    ////////////////////////////////////////////////////////////////
        
    private Vector declarations = null;
    private boolean tablesDirty = false;
    private Context2 parent = null;
    private Context2 child = null;

    /**
     * Create a new Namespace context.
     */
    Context2 (Context2 parent)
    {
        if(parent==null)
            {
                prefixTable = new Hashtable();
                uriTable = new Hashtable();
                elementNameTable=null; 
                attributeNameTable=null; 
            }
        else
            setParent(parent);
    }

        
    /**
     * @returns The child Namespace context object, or null if this
     * is the last currently on the chain.
     */
    Context2 getChild()
    {
        return child;
    }
        
    /**
     * @returns The parent Namespace context object, or null if this
     * is the root.
     */
    Context2 getParent()
    {
        return parent;
    }
        
    /**
     * (Re)set the parent of this Namespace context.
     * This is separate from the c'tor because it's re-applied
     * when a Context2 is reused by push-after-pop.
     *
     * @param context The parent Namespace context object.
     */
    void setParent (Context2 parent)
    {
        this.parent = parent;
        parent.child = this;        // JJK: Doubly-linked
        declarations = null;
        prefixTable = parent.prefixTable;
        uriTable = parent.uriTable;
        elementNameTable = parent.elementNameTable;
        attributeNameTable = parent.attributeNameTable;
        defaultNS = parent.defaultNS;
        tablesDirty = false;
    }
        
        
    /**
     * Declare a Namespace prefix for this context.
     *
     * @param prefix The prefix to declare.
     * @param uri The associated Namespace URI.
     * @see org.xml.sax.helpers.NamespaceSupport2#declarePrefix
     */
    void declarePrefix (String prefix, String uri)
    {
                                // Lazy processing...
        if (!tablesDirty) {
            copyTables();
        }
        if (declarations == null) {
            declarations = new Vector();
        }
            
        prefix = prefix.intern();
        uri = uri.intern();
        if ("".equals(prefix)) {
            if ("".equals(uri)) {
                defaultNS = null;
            } else {
                defaultNS = uri;
            }
        } else {
            prefixTable.put(prefix, uri);
            uriTable.put(uri, prefix); // may wipe out another prefix
        }
        declarations.addElement(prefix);
    }


    /**
     * Process a raw XML 1.0 name in this context.
     *
     * @param qName The raw XML 1.0 name.
     * @param isAttribute true if this is an attribute name.
     * @return An array of three strings containing the
     *         URI part (or empty string), the local part,
     *         and the raw name, all internalized, or null
     *         if there is an undeclared prefix.
     * @see org.xml.sax.helpers.NamespaceSupport2#processName
     */
    String [] processName (String qName, boolean isAttribute)
    {
        String name[];
        Hashtable table;
            
                                // Select the appropriate table.
        if (isAttribute) {
            if(elementNameTable==null)
                elementNameTable=new Hashtable();
            table = elementNameTable;
        } else {
            if(attributeNameTable==null)
                attributeNameTable=new Hashtable();
            table = attributeNameTable;
        }
            
                                // Start by looking in the cache, and
                                // return immediately if the name
                                // is already known in this content
        name = (String[])table.get(qName);
        if (name != null) {
            return name;
        }
            
                                // We haven't seen this name in this
                                // context before.
        name = new String[3];
        int index = qName.indexOf(':');
            
            
                                // No prefix.
        if (index == -1) {
            if (isAttribute || defaultNS == null) {
                name[0] = "";
            } else {
                name[0] = defaultNS;
            }
            name[1] = qName.intern();
            name[2] = name[1];
        }
            
                                // Prefix
        else {
            String prefix = qName.substring(0, index);
            String local = qName.substring(index+1);
            String uri;
            if ("".equals(prefix)) {
                uri = defaultNS;
            } else {
                uri = (String)prefixTable.get(prefix);
            }
            if (uri == null) {
                return null;
            }
            name[0] = uri;
            name[1] = local.intern();
            name[2] = qName.intern();
        }
            
                                // Save in the cache for future use.
        table.put(name[2], name);
        tablesDirty = true;
        return name;
    }
        

    /**
     * Look up the URI associated with a prefix in this context.
     *
     * @param prefix The prefix to look up.
     * @return The associated Namespace URI, or null if none is
     *         declared.    
     * @see org.xml.sax.helpers.NamespaceSupport2#getURI
     */
    String getURI (String prefix)
    {
        if ("".equals(prefix)) {
            return defaultNS;
        } else if (prefixTable == null) {
            return null;
        } else {
            return (String)prefixTable.get(prefix);
        }
    }


    /**
     * Look up one of the prefixes associated with a URI in this context.
     *
     * <p>Since many prefixes may be mapped to the same URI,
     * the return value may be unreliable.</p>
     *
     * @param uri The URI to look up.
     * @return The associated prefix, or null if none is declared.
     * @see org.xml.sax.helpers.NamespaceSupport2#getPrefix
     */
    String getPrefix (String uri)
    {
        if (uriTable == null) {
            return null;
        } else {
            return (String)uriTable.get(uri);
        }
    }
        
        
    /**
     * Return an enumeration of prefixes declared in this context.
     *
     * @return An enumeration of prefixes (possibly empty).
     * @see org.xml.sax.helpers.NamespaceSupport2#getDeclaredPrefixes
     */
    Enumeration getDeclaredPrefixes ()
    {
        if (declarations == null) {
            return EMPTY_ENUMERATION;
        } else {
            return declarations.elements();
        }
    }
        
        
    /**
     * Return an enumeration of all prefixes currently in force.
     *
     * <p>The default prefix, if in force, is <em>not</em>
     * returned, and will have to be checked for separately.</p>
     *
     * @return An enumeration of prefixes (never empty).
     * @see org.xml.sax.helpers.NamespaceSupport2#getPrefixes
     */
    Enumeration getPrefixes ()
    {
        if (prefixTable == null) {
            return EMPTY_ENUMERATION;
        } else {
            return prefixTable.keys();
        }
    }
        
    ////////////////////////////////////////////////////////////////
    // Internal methods.
    ////////////////////////////////////////////////////////////////

    /**
     * Copy on write for the internal tables in this context.
     *
     * <p>This class is optimized for the normal case where most
     * elements do not contain Namespace declarations. In that case,
     * the Context2 will share data structures with its parent.
     * New tables are obtained only when new declarations are issued,
     * so they can be popped off the stack.</p>
     *
     * <p> JJK: **** Alternative: each Context2 might declare
     *  _only_ its local bindings, and delegate upward if not found.</p>
     */     
    private void copyTables ()
    {
        // Start by copying our parent's bindings
        prefixTable = (Hashtable)prefixTable.clone();
        uriTable = (Hashtable)uriTable.clone();

        // Replace the caches with empty ones, rather than
        // trying to determine which bindings should be flushed.
        // As far as I can tell, these caches are never actually
        // used in Xalan... More efficient to remove the whole
        // cache system? ****
        if(elementNameTable!=null)
            elementNameTable=new Hashtable(); 
        if(attributeNameTable!=null)
            attributeNameTable=new Hashtable(); 
        tablesDirty = true;
    }

}


// end of NamespaceSupport2.java
