All Downloads are FREE. Search and download functionalities are using the official Maven repository.

javanet.staxutils.SimpleNamespaceContext Maven / Gradle / Ivy

/*
 * $Id: SimpleNamespaceContext.java,v 1.7 2004/07/14 13:23:54 cniles Exp $
 * 
 * Copyright (c) 2004, Christian Niles, unit12.net
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 *		*   Redistributions of source code must retain the above copyright
 *          notice, this list of conditions and the following disclaimer.
 * 
 *	    *	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.
 * 
 *      *   Neither the name of Christian Niles, Unit12, nor the names of its
 *          contributors may be used to endorse or promote products derived from
 *          this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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.
 * 
 */
package javanet.staxutils;

import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;

/**
 * Simple NamespaceContext implementation backed by a HashMap.
 * 
 * @author Christian Niles
 * @version $Revision: 1.7 $
 */
public class SimpleNamespaceContext
        implements
            ExtendedNamespaceContext,
            StaticNamespaceContext {

    /**
     * The parent context, which may be null
     */
    protected NamespaceContext parent;

    /**
     * map containing bound namespaces, keyed by their prefix. A LinkedHashMap
     * is used to ensure that {@link #getPrefix(String)} always returns the same
     * prefix, unless that prefix is removed.
     */
    protected Map namespaces = new LinkedHashMap();

    /**
     * Constructs a SimpleNamespaceContext with no parent context or namespace
     * declarations.
     */
    public SimpleNamespaceContext() {

    }

    /**
     * Constructs a SimpleNamespaceContext with no parent context that contains
     * the specified prefixes.
     * 
     * @param namespaces A Map of namespace URIs, keyed by their prefixes.
     */
    public SimpleNamespaceContext(Map namespaces) {

        if (namespaces != null) {

            this.namespaces.putAll(namespaces);

        }

    }

    /**
     * Constructs an empty SimpleNamespaceContext with the given parent. The
     * parent context will be forwarded any requests for namespaces not declared
     * in this context.
     * 
     * @param parent The parent context.
     */
    public SimpleNamespaceContext(NamespaceContext parent) {

        this.parent = parent;

    }

    /**
     * Constructs an empty SimpleNamespaceContext with the given parent. The
     * parent context will be forwarded any requests for namespaces not declared
     * in this context.
     * 
     * @param parent The parent context.
     * @param namespaces A Map of namespace URIs, keyed by their prefixes.
     */
    public SimpleNamespaceContext(NamespaceContext parent, Map namespaces) {

        this.parent = parent;

        if (namespaces != null) {

            this.namespaces.putAll(namespaces);

        }

    }

    /**
     * Returns a reference to the parent of this context.
     * 
     * @return The parent context, or null if this is a root
     * 		context.
     */
    public NamespaceContext getParent() {

        return parent;

    }

    /**
     * Sets the parent context used to inherit namespace bindings.
     * 
     * @param parent The new parent context.
     */
    public void setParent(NamespaceContext parent) {

        this.parent = parent;

    }

    /**
     * Determines if this is a root context.
     * 
     * @return true if this is a root context, false
     * 		otherwise.
     */
    public boolean isRootContext() {

        return parent == null;

    }

    public String getNamespaceURI(String prefix) {

        if (prefix == null) {

            throw new IllegalArgumentException("prefix argument was null");

        } else if (prefix.equals(XMLConstants.XML_NS_PREFIX)) {

            return XMLConstants.XML_NS_URI;

        } else if (prefix.equals(XMLConstants.XMLNS_ATTRIBUTE)) {

            return XMLConstants.XMLNS_ATTRIBUTE_NS_URI;

        } else if (namespaces.containsKey(prefix)) {

            // The StAX spec says to return null for any undefined prefix. To support
            // undefining a prefix as specified in the Namespaces spec, we store
            // undefined prefixes as the empty string.

            String uri = (String) namespaces.get(prefix);
            if (uri.length() == 0) {

                return null;

            } else {

                return uri;

            }

        } else if (parent != null) {

            return parent.getNamespaceURI(prefix);

        } else {

            return null;

        }

    }

    public String getPrefix(String nsURI) {

        if (nsURI == null) {

            throw new IllegalArgumentException("nsURI was null");

        } else if (nsURI.length() == 0) {

            throw new IllegalArgumentException("nsURI was empty");

        } else if (nsURI.equals(XMLConstants.XML_NS_URI)) {

            return XMLConstants.XML_NS_PREFIX;

        } else if (nsURI.equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)) {

            return XMLConstants.XMLNS_ATTRIBUTE;

        }

        Iterator iter = namespaces.entrySet().iterator();
        while (iter.hasNext()) {

            Map.Entry entry = (Map.Entry) iter.next();
            String uri = (String) entry.getValue();

            if (uri.equals(nsURI)) {

                return (String) entry.getKey();

            }

        }

        if (parent != null) {

            return parent.getPrefix(nsURI);

        } else if (nsURI.length() == 0) {

            return "";

        } else {

            return null;

        }

    }

    /**
     * Determines if the specified prefix is declared within this context,
     * irrespective of any ancestor contexts.
     * 
     * @param prefix The prefix to check.
     * @return true if the prefix is declared in this context,
     * 		false otherwise.
     */
    public boolean isPrefixDeclared(String prefix) {

        return namespaces.containsKey(prefix);

    }

    public Iterator getDeclaredPrefixes() {

        return Collections.unmodifiableCollection(this.namespaces.keySet())
                .iterator();

    }

    /**
     * Returns the number of namespace prefixes declared in this context.
     * 
     * @return The number of namespace prefixes declared in this context.
     */
    public int getDeclaredPrefixCount() {

        return namespaces.size();

    }

    public Iterator getPrefixes() {

        if (parent == null || !(parent instanceof ExtendedNamespaceContext)) {

            return getDeclaredPrefixes();

        } else {

            Set prefixes = new HashSet(this.namespaces.keySet());

            ExtendedNamespaceContext superCtx = (ExtendedNamespaceContext) parent;
            for (Iterator i = superCtx.getPrefixes(); i.hasNext();) {

                String prefix = (String) i.next();
                prefixes.add(prefix);

            }

            return prefixes.iterator();

        }

    }

    public Iterator getPrefixes(String nsURI) {

        if (nsURI == null) {

            throw new IllegalArgumentException("nsURI was null");

        } else if (nsURI.equals(XMLConstants.XML_NS_URI)) {

            return Collections.singleton(XMLConstants.XML_NS_PREFIX).iterator();

        } else if (nsURI.equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)) {

            return Collections.singleton(XMLConstants.XMLNS_ATTRIBUTE)
                    .iterator();

        }

        Set prefixes = null;
        Iterator iter = namespaces.entrySet().iterator();
        while (iter.hasNext()) {

            Map.Entry entry = (Map.Entry) iter.next();
            String uri = (String) entry.getValue();
            if (uri.equals(nsURI)) {

                if (prefixes == null) {

                    prefixes = new HashSet();

                }
                prefixes.add(entry.getKey());

            }

        }

        if (parent != null) {

            for (Iterator i = parent.getPrefixes(nsURI); i.hasNext();) {

                String prefix = (String) i.next();

                if (prefixes == null) {

                    prefixes = new HashSet();

                }
                prefixes.add(prefix);

            }

        }

        if (prefixes != null) {

            return Collections.unmodifiableSet(prefixes).iterator();

        } else if (nsURI.length() == 0) {

            return Collections.singleton("").iterator();

        } else {

            return Collections.EMPTY_LIST.iterator();

        }

    }

    /**
     * Sets the default namespace in this context.
     * 
     * @param nsURI The default namespace URI.
     * @return The previously declared namespace uri, or null if
     * 		the default prefix wasn't previously declared in this context.
     */
    public String setDefaultNamespace(String nsURI) {

        if (nsURI != null) {

            if (nsURI.equals(XMLConstants.XML_NS_URI)) {

                throw new IllegalArgumentException("Attempt to map 'xml' uri");

            } else if (nsURI.equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)) {

                throw new IllegalArgumentException("Attempt to map 'xmlns' uri");

            }

            return (String) namespaces.put(XMLConstants.DEFAULT_NS_PREFIX,
                    nsURI);

        } else {
            
            // put the empty string to record an undefined prefix
            return (String) namespaces.put(XMLConstants.DEFAULT_NS_PREFIX, "");

        }

    }

    /**
     * Declares a namespace binding in this context.
     * 
     * @param prefix The namespace prefix.
     * @param nsURI The namespace URI.
     * @return The previously declared namespace uri, or null if
     * 		the prefix wasn't previously declared in this context.
     */
    public String setPrefix(String prefix, String nsURI) {

        if (prefix == null) {

            throw new NullPointerException("Namespace Prefix was null");

        } else if (prefix.equals(XMLConstants.DEFAULT_NS_PREFIX)) {

            return setDefaultNamespace(nsURI);

        } else if (prefix.equals(XMLConstants.XML_NS_PREFIX)) {

            throw new IllegalArgumentException("Attempt to map 'xml' prefix");

        } else if (prefix.equals(XMLConstants.XMLNS_ATTRIBUTE)) {

            throw new IllegalArgumentException("Attempt to map 'xmlns' prefix");

        } else if (nsURI != null) {

            if (nsURI.equals(XMLConstants.XML_NS_URI)) {

                throw new IllegalArgumentException("Attempt to map 'xml' uri");

            } else if (nsURI.equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)) {

                throw new IllegalArgumentException("Attempt to map 'xmlns' uri");

            } else {

                return (String) namespaces.put(prefix, nsURI);

            }

        } else {

            // put the empty string to record an undefined prefix
            return (String) namespaces.put(prefix, "");

        }

    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy