1 /*
2  * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
3  *
4  * This software is open source.
5  * See the bottom of this file for the licence.
6  */
7 
8 package org.dom4j;
9 
10 import org.dom4j.tree.AbstractNode;
11 import org.dom4j.tree.DefaultNamespace;
12 import org.dom4j.tree.NamespaceCache;
13 
14 /**
15  * <p>
16  * <code>Namespace</code> is a Flyweight Namespace that can be shared amongst
17  * nodes.
18  * </p>
19  *
20  * @author <a href="mailto:jstrachan@apache.org">James Strachan </a>
21  * @version $Revision: 1.22 $
22  */
23 public class Namespace extends AbstractNode {
24     /** Cache of Namespace instances */
25     protected static final NamespaceCache CACHE = new NamespaceCache();
26 
27     /** XML Namespace */
28     public static final Namespace XML_NAMESPACE = CACHE.get("xml",
29             "http://www.w3.org/XML/1998/namespace");
30 
31     /** No Namespace present */
32     public static final Namespace NO_NAMESPACE = CACHE.get("", "");
33 
34     /** The prefix mapped to this namespace */
35     private String prefix;
36 
37     /** The URI for this namespace */
38     private String uri;
39 
40     /** A cached version of the hashcode for efficiency */
41     private int hashCode;
42 
43     /**
44      * DOCUMENT ME!
45      *
46      * @param prefix
47      *            is the prefix for this namespace
48      * @param uri
49      *            is the URI for this namespace
50      */
Namespace(String prefix, String uri)51     public Namespace(String prefix, String uri) {
52         this.prefix = (prefix != null) ? prefix : "";
53         this.uri = (uri != null) ? uri : "";
54     }
55 
56     /**
57      * A helper method to return the Namespace instance for the given prefix and
58      * URI
59      *
60      * @param prefix
61      *            DOCUMENT ME!
62      * @param uri
63      *            DOCUMENT ME!
64      *
65      * @return an interned Namespace object
66      */
get(String prefix, String uri)67     public static Namespace get(String prefix, String uri) {
68         return CACHE.get(prefix, uri);
69     }
70 
71     /**
72      * A helper method to return the Namespace instance for no prefix and the
73      * URI
74      *
75      * @param uri
76      *            DOCUMENT ME!
77      *
78      * @return an interned Namespace object
79      */
get(String uri)80     public static Namespace get(String uri) {
81         return CACHE.get(uri);
82     }
83 
getNodeType()84     public short getNodeType() {
85         return NAMESPACE_NODE;
86     }
87 
88     /**
89      * DOCUMENT ME!
90      *
91      * @return the hash code based on the qualified name and the URI of the
92      *         namespace.
93      */
hashCode()94     public int hashCode() {
95         if (hashCode == 0) {
96             hashCode = createHashCode();
97         }
98 
99         return hashCode;
100     }
101 
102     /**
103      * Factory method to create the hashcode allowing derived classes to change
104      * the behaviour
105      *
106      * @return DOCUMENT ME!
107      */
createHashCode()108     protected int createHashCode() {
109         int result = uri.hashCode() ^ prefix.hashCode();
110 
111         if (result == 0) {
112             result = 0xbabe;
113         }
114 
115         return result;
116     }
117 
118     /**
119      * Checks whether this Namespace equals the given Namespace. Two Namespaces
120      * are equals if their URI and prefix are equal.
121      *
122      * @param object
123      *            DOCUMENT ME!
124      *
125      * @return DOCUMENT ME!
126      */
equals(Object object)127     public boolean equals(Object object) {
128         if (this == object) {
129             return true;
130         } else if (object instanceof Namespace) {
131             Namespace that = (Namespace) object;
132 
133             // we cache hash codes so this should be quick
134             if (hashCode() == that.hashCode()) {
135                 return uri.equals(that.getURI())
136                         && prefix.equals(that.getPrefix());
137             }
138         }
139 
140         return false;
141     }
142 
getText()143     public String getText() {
144         return uri;
145     }
146 
getStringValue()147     public String getStringValue() {
148         return uri;
149     }
150 
151     /**
152      * DOCUMENT ME!
153      *
154      * @return the prefix for this <code>Namespace</code>.
155      */
getPrefix()156     public String getPrefix() {
157         return prefix;
158     }
159 
160     /**
161      * DOCUMENT ME!
162      *
163      * @return the URI for this <code>Namespace</code>.
164      */
getURI()165     public String getURI() {
166         return uri;
167     }
168 
getXPathNameStep()169     public String getXPathNameStep() {
170         if ((prefix != null) && !"".equals(prefix)) {
171             return "namespace::" + prefix;
172         }
173 
174         return "namespace::*[name()='']";
175     }
176 
getPath(Element context)177     public String getPath(Element context) {
178         StringBuffer path = new StringBuffer(10);
179         Element parent = getParent();
180 
181         if ((parent != null) && (parent != context)) {
182             path.append(parent.getPath(context));
183             path.append('/');
184         }
185 
186         path.append(getXPathNameStep());
187 
188         return path.toString();
189     }
190 
getUniquePath(Element context)191     public String getUniquePath(Element context) {
192         StringBuffer path = new StringBuffer(10);
193         Element parent = getParent();
194 
195         if ((parent != null) && (parent != context)) {
196             path.append(parent.getUniquePath(context));
197             path.append('/');
198         }
199 
200         path.append(getXPathNameStep());
201 
202         return path.toString();
203     }
204 
toString()205     public String toString() {
206         return super.toString() + " [Namespace: prefix " + getPrefix()
207                 + " mapped to URI \"" + getURI() + "\"]";
208     }
209 
asXML()210     public String asXML() {
211         StringBuffer asxml = new StringBuffer(10);
212         String pref = getPrefix();
213 
214         if ((pref != null) && (pref.length() > 0)) {
215             asxml.append("xmlns:");
216             asxml.append(pref);
217             asxml.append("=\"");
218         } else {
219             asxml.append("xmlns=\"");
220         }
221 
222         asxml.append(getURI());
223         asxml.append("\"");
224 
225         return asxml.toString();
226     }
227 
accept(Visitor visitor)228     public void accept(Visitor visitor) {
229         visitor.visit(this);
230     }
231 
createXPathResult(Element parent)232     protected Node createXPathResult(Element parent) {
233         return new DefaultNamespace(parent, getPrefix(), getURI());
234     }
235 }
236 
237 /*
238  * Redistribution and use of this software and associated documentation
239  * ("Software"), with or without modification, are permitted provided that the
240  * following conditions are met:
241  *
242  * 1. Redistributions of source code must retain copyright statements and
243  * notices. Redistributions must also contain a copy of this document.
244  *
245  * 2. Redistributions in binary form must reproduce the above copyright notice,
246  * this list of conditions and the following disclaimer in the documentation
247  * and/or other materials provided with the distribution.
248  *
249  * 3. The name "DOM4J" must not be used to endorse or promote products derived
250  * from this Software without prior written permission of MetaStuff, Ltd. For
251  * written permission, please contact dom4j-info@metastuff.com.
252  *
253  * 4. Products derived from this Software may not be called "DOM4J" nor may
254  * "DOM4J" appear in their names without prior written permission of MetaStuff,
255  * Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
256  *
257  * 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
258  *
259  * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
260  * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
261  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
262  * ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE
263  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
264  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
265  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
266  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
267  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
268  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
269  * POSSIBILITY OF SUCH DAMAGE.
270  *
271  * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
272  */
273