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