123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278 |
- /*--
-
- $Id: Namespace.java,v 1.43 2007/11/10 05:28:59 jhunter Exp $
-
- Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
- 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 disclaimer that follows
- these conditions in the documentation and/or other materials
- provided with the distribution.
-
- 3. The name "JDOM" must not be used to endorse or promote products
- derived from this software without prior written permission. For
- written permission, please contact <request_AT_jdom_DOT_org>.
-
- 4. Products derived from this software may not be called "JDOM", nor
- may "JDOM" appear in their name, without prior written permission
- from the JDOM Project Management <request_AT_jdom_DOT_org>.
-
- In addition, we request (but do not require) that you include in the
- end-user documentation provided with the redistribution and/or in the
- software itself an acknowledgement equivalent to the following:
- "This product includes software developed by the
- JDOM Project (http://www.jdom.org/)."
- Alternatively, the acknowledgment may be graphical using the logos
- available at http://www.jdom.org/images/logos.
-
- 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 JDOM AUTHORS OR THE PROJECT
- 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 JDOM Project and was originally
- created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
- Brett McLaughlin <brett_AT_jdom_DOT_org>. For more information
- on the JDOM Project, please see <http://www.jdom.org/>.
-
- */
-
- package org.jdom;
-
- import java.util.*;
-
- /**
- * An XML namespace representation, as well as a factory for creating XML
- * namespace objects. Namespaces are not Serializable, however objects that use
- * namespaces have special logic to handle serialization manually. These classes
- * call the getNamespace() method on deserialization to ensure there is one
- * unique Namespace object for any unique prefix/uri pair.
- *
- * @version $Revision: 1.43 $, $Date: 2007/11/10 05:28:59 $
- * @author Brett McLaughlin
- * @author Elliotte Rusty Harold
- * @author Jason Hunter
- * @author Wesley Biggs
- */
- public final class Namespace {
-
- // XXX May want to use weak references to keep the maps from growing
- // large with extended use
-
- // XXX We may need to make the namespaces HashMap synchronized with
- // reader/writer locks or perhaps make Namespace no longer a flyweight.
- // As written, multiple put() calls may happen from different threads
- // concurrently and cause a ConcurrentModificationException. See
- // http://lists.denveronline.net/lists/jdom-interest/2000-September/003009.html.
- // No one has ever reported this over the many years, so don't worry yet.
-
- private static final String CVS_ID =
- "@(#) $RCSfile: Namespace.java,v $ $Revision: 1.43 $ $Date: 2007/11/10 05:28:59 $ $Name: jdom_1_1 $";
-
- /**
- * Factory list of namespaces.
- * Keys are <i>prefix</i>&<i>URI</i>.
- * Values are Namespace objects
- */
- private static HashMap namespaces;
-
- /** Define a <code>Namespace</code> for when <i>not</i> in a namespace */
- public static final Namespace NO_NAMESPACE = new Namespace("", "");
-
- /** Define a <code>Namespace</code> for the standard xml prefix. */
- public static final Namespace XML_NAMESPACE =
- new Namespace("xml", "http://www.w3.org/XML/1998/namespace");
-
- /** The prefix mapped to this namespace */
- private String prefix;
-
- /** The URI for this namespace */
- private String uri;
-
- /**
- * This static initializer acts as a factory contructor.
- * It sets up storage and required initial values.
- */
- static {
- namespaces = new HashMap(16);
-
- // Add the "empty" namespace
- namespaces.put(new NamespaceKey(NO_NAMESPACE), NO_NAMESPACE);
- namespaces.put(new NamespaceKey(XML_NAMESPACE), XML_NAMESPACE);
- }
-
- /**
- * This will retrieve (if in existence) or create (if not) a
- * <code>Namespace</code> for the supplied prefix and URI.
- *
- * @param prefix <code>String</code> prefix to map to
- * <code>Namespace</code>.
- * @param uri <code>String</code> URI of new <code>Namespace</code>.
- * @return <code>Namespace</code> - ready to use namespace.
- * @throws IllegalNameException if the given prefix and uri make up
- * an illegal namespace name.
- */
- public static Namespace getNamespace(String prefix, String uri) {
- // Sanity checking
- if ((prefix == null) || (prefix.trim().equals(""))) {
- // Short-cut out for common case of no namespace
- if ((uri == null) || (uri.trim().equals(""))) {
- return NO_NAMESPACE;
- }
- prefix = "";
- }
- else if ((uri == null) || (uri.trim().equals(""))) {
- uri = "";
- }
-
- // Return existing namespace if found. The preexisting namespaces
- // should all be legal. In other words, an illegal namespace won't
- // have been placed in this. Thus we can do this test before
- // verifying the URI and prefix.
- NamespaceKey lookup = new NamespaceKey(prefix, uri);
- Namespace preexisting = (Namespace) namespaces.get(lookup);
- if (preexisting != null) {
- return preexisting;
- }
-
- // Ensure proper naming
- String reason;
- if ((reason = Verifier.checkNamespacePrefix(prefix)) != null) {
- throw new IllegalNameException(prefix, "Namespace prefix", reason);
- }
- if ((reason = Verifier.checkNamespaceURI(uri)) != null) {
- throw new IllegalNameException(uri, "Namespace URI", reason);
- }
-
- // Unless the "empty" Namespace (no prefix and no URI), require a URI
- if ((!prefix.equals("")) && (uri.equals(""))) {
- throw new IllegalNameException("", "namespace",
- "Namespace URIs must be non-null and non-empty Strings");
- }
-
- // Handle XML namespace mislabels. If the user requested the correct
- // namespace and prefix -- xml, http://www.w3.org/XML/1998/namespace
- // -- then it was already returned from the preexisting namespaces.
- // Thus any use of the xml prefix or the
- // http://www.w3.org/XML/1998/namespace URI at this point must be
- // incorrect.
- if (prefix.equals("xml")) {
- throw new IllegalNameException(prefix, "Namespace prefix",
- "The xml prefix can only be bound to " +
- "http://www.w3.org/XML/1998/namespace");
- }
-
- // The erratum to Namespaces in XML 1.0 that suggests this
- // next check is controversial. Not everyone accepts it.
- if (uri.equals("http://www.w3.org/XML/1998/namespace")) {
- throw new IllegalNameException(uri, "Namespace URI",
- "The http://www.w3.org/XML/1998/namespace must be bound to " +
- "the xml prefix.");
- }
-
- // Finally, store and return
- Namespace ns = new Namespace(prefix, uri);
- namespaces.put(lookup, ns);
- return ns;
- }
-
- /**
- * This will retrieve (if in existence) or create (if not) a
- * <code>Namespace</code> for the supplied URI, and make it usable
- * as a default namespace, as no prefix is supplied.
- *
- * @param uri <code>String</code> URI of new <code>Namespace</code>.
- * @return <code>Namespace</code> - ready to use namespace.
- */
- public static Namespace getNamespace(String uri) {
- return getNamespace("", uri);
- }
-
- /**
- * This constructor handles creation of a <code>Namespace</code> object
- * with a prefix and URI; it is intentionally left <code>private</code>
- * so that it cannot be invoked by external programs/code.
- *
- * @param prefix <code>String</code> prefix to map to this namespace.
- * @param uri <code>String</code> URI for namespace.
- */
- private Namespace(String prefix, String uri) {
- this.prefix = prefix;
- this.uri = uri;
- }
-
- /**
- * This returns the prefix mapped to this <code>Namespace</code>.
- *
- * @return <code>String</code> - prefix for this <code>Namespace</code>.
- */
- public String getPrefix() {
- return prefix;
- }
-
- /**
- * This returns the namespace URI for this <code>Namespace</code>.
- *
- * @return <code>String</code> - URI for this <code>Namespace</code>.
- */
- public String getURI() {
- return uri;
- }
-
- /**
- * This tests for equality - Two <code>Namespaces</code>
- * are equal if and only if their URIs are byte-for-byte equals.
- *
- * @param ob <code>Object</code> to compare to this <code>Namespace</code>.
- * @return <code>boolean</code> - whether the supplied object is equal to
- * this <code>Namespace</code>.
- */
- public boolean equals(Object ob) {
- if (this == ob) {
- return true;
- }
- if (ob instanceof Namespace) { // instanceof returns false if null
- return uri.equals(((Namespace)ob).uri);
- }
- return false;
- }
-
- /**
- * This returns a <code>String</code> representation of this
- * <code>Namespace</code>, suitable for use in debugging.
- *
- * @return <code>String</code> - information about this instance.
- */
- public String toString() {
- return "[Namespace: prefix \"" + prefix + "\" is mapped to URI \"" +
- uri + "\"]";
- }
-
- /**
- * This returns a probably unique hash code for the <code>Namespace</code>.
- * If two namespaces have the same URI, they are equal and have the same
- * hash code, even if they have different prefixes.
- *
- * @return <code>int</code> - hash code for this <code>Namespace</code>.
- */
- public int hashCode() {
- return uri.hashCode();
- }
- }
|