001/*
002 * Copyright 2001 (C) MetaStuff, Ltd. All Rights Reserved.
003 * 
004 * This software is open source. 
005 * See the bottom of this file for the licence.
006 * 
007 * $Id: Namespace.java,v 1.13 2001/08/01 09:17:21 jstrachan Exp $
008 */
009
010package org.dom4j;
011
012import org.dom4j.tree.AbstractNode;
013import org.dom4j.tree.NamespaceCache;
014import org.dom4j.tree.DefaultNamespace;
015
016/** <p><code>Namespace</code> is a Flyweight Namespace that can be shared amongst nodes.</p>
017  * 
018  * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
019  * @version $Revision: 1.13 $
020  */
021public class Namespace extends AbstractNode {
022    
023    /** Cache of Namespace instances */
024    protected static final NamespaceCache cache = new NamespaceCache();
025    
026    /** XML Namespace */
027    public static final Namespace XML_NAMESPACE 
028        = cache.get("xml", "http://www.w3.org/XML/1998/namespace");
029    
030    /** No Namespace present */
031    public static final Namespace NO_NAMESPACE 
032        = cache.get("", "");
033
034    
035    /** The prefix mapped to this namespace */
036    private String prefix;
037
038    /** The URI for this namespace */
039    private String uri;
040
041    /** A cached version of the hashcode for efficiency */
042    private int hashCode;
043
044    
045    /** A helper method to return the Namespace instance
046      * for the given prefix and URI
047      *
048      * @return an interned Namespace object
049      */
050    public static Namespace get(String prefix, String uri) {
051        return cache.get(prefix, uri);
052    }
053    
054    /** A helper method to return the Namespace instance
055      * for no prefix and the URI
056      *
057      * @return an interned Namespace object
058      */
059    public static Namespace get(String uri) {
060        return cache.get(uri);
061    }
062    
063    /** @param prefix is the prefix for this namespace
064      * @param uri is the URI for this namespace
065      */
066    public Namespace(String prefix, String uri) {
067        this.prefix = (prefix != null) ? prefix : "";
068        this.uri = (uri != null) ? uri : "";;
069    }
070
071    
072    public short getNodeType() {
073        return NAMESPACE_NODE;
074    }
075
076    /** @return the hash code based on the qualified name and the URI of the 
077      * namespace.
078      */
079    public int hashCode() {
080        if ( hashCode == 0 ) {
081            hashCode = createHashCode();
082        }
083        return hashCode;
084    }
085        
086    /** Factory method to create the hashcode allowing derived classes to change the behaviour */
087    protected int createHashCode() {        
088        int hashCode = uri.hashCode() ^ prefix.hashCode();
089        if ( hashCode == 0 ) {
090            hashCode = 0xbabe;
091        }            
092        return hashCode;
093    }
094
095  
096    public boolean equals(Object object) {
097        if ( this == object ) {
098            return true;
099        }
100        else if ( object instanceof Namespace ) {
101            Namespace that = (Namespace) object;
102            
103            // we cache hash codes so this should be quick
104            if ( hashCode() == that.hashCode() ) {
105                return uri.equals( that.getURI() ) 
106                    && prefix.equals( that.getPrefix() );
107            }
108        }
109        return false;
110    }
111    
112    public String getText() {
113        return uri;
114    }
115    
116    public String getStringValue() {
117        return uri;
118    }
119    
120    /** @return the prefix for this <code>Namespace</code>.
121      */
122    public String getPrefix() {
123        return prefix;
124    }
125
126    /** @return the URI for this <code>Namespace</code>.
127      */
128    public String getURI() {
129        return uri;
130    }
131
132
133    public String getPath(Element context) {
134        String match = ( prefix != null ) ? prefix : "*";
135        Element parent = getParent();
136        return ( parent != null && parent != context ) 
137            ? parent.getPath( context ) + "/namespace::" + match
138            : "namespace::" + match;
139    }
140    
141    public String getUniquePath(Element context) {
142        String match = ( prefix != null ) ? prefix : "*";
143        Element parent = getParent();
144        return ( parent != null && parent != context ) 
145            ? parent.getUniquePath( context ) + "/namespace::" + match
146            : "namespace::" + match;
147    }
148    
149    public String toString() {
150        return super.toString() + " [Namespace: prefix " + getPrefix() 
151            + " mapped to URI \"" + getURI() + "\"]";
152    }
153
154    public String asXML() {
155        return "xmlns:" + getPrefix() + "=\"" + getURI() + "\"";
156    }
157    
158    public void accept(Visitor visitor) {
159        visitor.visit(this);
160    }
161    
162    protected Node createXPathResult(Element parent) {
163        return new DefaultNamespace( parent, getPrefix(), getURI() );
164    }    
165    
166}
167
168
169
170
171/*
172 * Redistribution and use of this software and associated documentation
173 * ("Software"), with or without modification, are permitted provided
174 * that the following conditions are met:
175 *
176 * 1. Redistributions of source code must retain copyright
177 *    statements and notices.  Redistributions must also contain a
178 *    copy of this document.
179 *
180 * 2. Redistributions in binary form must reproduce the
181 *    above copyright notice, this list of conditions and the
182 *    following disclaimer in the documentation and/or other
183 *    materials provided with the distribution.
184 *
185 * 3. The name "DOM4J" must not be used to endorse or promote
186 *    products derived from this Software without prior written
187 *    permission of MetaStuff, Ltd.  For written permission,
188 *    please contact dom4j-info@metastuff.com.
189 *
190 * 4. Products derived from this Software may not be called "DOM4J"
191 *    nor may "DOM4J" appear in their names without prior written
192 *    permission of MetaStuff, Ltd. DOM4J is a registered
193 *    trademark of MetaStuff, Ltd.
194 *
195 * 5. Due credit should be given to the DOM4J Project
196 *    (http://dom4j.org/).
197 *
198 * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS
199 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
200 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
201 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
202 * METASTUFF, LTD. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
203 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
204 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
205 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
206 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
207 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
208 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
209 * OF THE POSSIBILITY OF SUCH DAMAGE.
210 *
211 * Copyright 2001 (C) MetaStuff, Ltd. All Rights Reserved.
212 *
213 * $Id: Namespace.java,v 1.13 2001/08/01 09:17:21 jstrachan Exp $
214 */