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 */
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 */
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 */
80 public static Namespace get(String uri) {
81 return CACHE.get(uri);
82 }
83
84 @Override
85 public NodeType getNodeTypeEnum() {
86 return NodeType.NAMESPACE_NODE;
87 }
88
89 /**
90 * DOCUMENT ME!
91 *
92 * @return the hash code based on the qualified name and the URI of the
93 * namespace.
94 */
95 @Override
96 public int hashCode() {
97 if (hashCode == 0) {
98 hashCode = createHashCode();
99 }
100
101 return hashCode;
102 }
103
104 /**
105 * Factory method to create the hashcode allowing derived classes to change
106 * the behaviour
107 *
108 * @return DOCUMENT ME!
109 */
110 protected int createHashCode() {
111 int result = uri.hashCode() ^ prefix.hashCode();
112
113 if (result == 0) {
114 result = 0xbabe;
115 }
116
117 return result;
118 }
119
120 /**
121 * Checks whether this Namespace equals the given Namespace. Two Namespaces
122 * are equals if their URI and prefix are equal.
123 *
124 * @param object
125 * DOCUMENT ME!
126 *
127 * @return DOCUMENT ME!
128 */
129 @Override
130 public boolean equals(Object object) {
131 if (this == object) {
132 return true;
133 } else if (object instanceof Namespace) {
134 Namespace that = (Namespace) object;
135
136 // we cache hash codes so this should be quick
137 if (hashCode() == that.hashCode()) {
138 return uri.equals(that.getURI())
139 && prefix.equals(that.getPrefix());
140 }
141 }
142
143 return false;
144 }
145
146 @Override
147 public String getText() {
148 return uri;
149 }
150
151 @Override
152 public String getStringValue() {
153 return uri;
154 }
155
156 /**
157 * DOCUMENT ME!
158 *
159 * @return the prefix for this <code>Namespace</code>.
160 */
161 public String getPrefix() {
162 return prefix;
163 }
164
165 /**
166 * DOCUMENT ME!
167 *
168 * @return the URI for this <code>Namespace</code>.
169 */
170 public String getURI() {
171 return uri;
172 }
173
174 public String getXPathNameStep() {
175 if ((prefix != null) && !"".equals(prefix)) {
176 return "namespace::" + prefix;
177 }
178
179 return "namespace::*[name()='']";
180 }
181
182 public String getPath(Element context) {
183 StringBuffer path = new StringBuffer(10);
184 Element parent = getParent();
185
186 if ((parent != null) && (parent != context)) {
187 path.append(parent.getPath(context));
188 path.append('/');
189 }
190
191 path.append(getXPathNameStep());
192
193 return path.toString();
194 }
195
196 public String getUniquePath(Element context) {
197 StringBuffer path = new StringBuffer(10);
198 Element parent = getParent();
199
200 if ((parent != null) && (parent != context)) {
201 path.append(parent.getUniquePath(context));
202 path.append('/');
203 }
204
205 path.append(getXPathNameStep());
206
207 return path.toString();
208 }
209
210 @Override
211 public String toString() {
212 return super.toString() + " [Namespace: prefix " + getPrefix()
213 + " mapped to URI \"" + getURI() + "\"]";
214 }
215
216 public String asXML() {
217 StringBuffer asxml = new StringBuffer(10);
218 String pref = getPrefix();
219
220 if ((pref != null) && (pref.length() > 0)) {
221 asxml.append("xmlns:");
222 asxml.append(pref);
223 asxml.append("=\"");
224 } else {
225 asxml.append("xmlns=\"");
226 }
227
228 asxml.append(getURI());
229 asxml.append("\"");
230
231 return asxml.toString();
232 }
233
234 public void accept(Visitor visitor) {
235 visitor.visit(this);
236 }
237
238 @Override
239 protected Node createXPathResult(Element parent) {
240 return new DefaultNamespace(parent, getPrefix(), getURI());
241 }
242 }
243
244 /*
245 * Redistribution and use of this software and associated documentation
246 * ("Software"), with or without modification, are permitted provided that the
247 * following conditions are met:
248 *
249 * 1. Redistributions of source code must retain copyright statements and
250 * notices. Redistributions must also contain a copy of this document.
251 *
252 * 2. Redistributions in binary form must reproduce the above copyright notice,
253 * this list of conditions and the following disclaimer in the documentation
254 * and/or other materials provided with the distribution.
255 *
256 * 3. The name "DOM4J" must not be used to endorse or promote products derived
257 * from this Software without prior written permission of MetaStuff, Ltd. For
258 * written permission, please contact dom4j-info@metastuff.com.
259 *
260 * 4. Products derived from this Software may not be called "DOM4J" nor may
261 * "DOM4J" appear in their names without prior written permission of MetaStuff,
262 * Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
263 *
264 * 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
265 *
266 * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
267 * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
268 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
269 * ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE
270 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
271 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
272 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
273 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
274 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
275 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
276 * POSSIBILITY OF SUCH DAMAGE.
277 *
278 * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
279 */