1 /* Copyright 2005 Elliotte Rusty Harold 2 3 This library is free software; you can redistribute it and/or modify 4 it under the terms of version 2.1 of the GNU Lesser General Public 5 License as published by the Free Software Foundation. 6 7 This library is distributed in the hope that it will be useful, 8 but WITHOUT ANY WARRANTY; without even the implied warranty of 9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 GNU Lesser General Public License for more details. 11 12 You should have received a copy of the GNU Lesser General Public 13 License along with this library; if not, write to the 14 Free Software Foundation, Inc., 59 Temple Place, Suite 330, 15 Boston, MA 02111-1307 USA 16 17 You can contact Elliotte Rusty Harold by sending e-mail to 18 elharo@ibiblio.org. Please include the word "XOM" in the 19 subject line. The XOM home page is located at http://www.xom.nu/ 20 */ 21 22 package nu.xom; 23 24 /** 25 * <p> 26 * Represents a namespace in scope. It is used by XOM's 27 * XPath implementation for the namespace axis. However, it is not 28 * really part of the XOM data model. Namespace objects are only 29 * created as needed when evaluating XPath. While a namespace node has 30 * a parent element (which may be null), that element does not know 31 * about these namespace nodes and cannot remove them. (This is an 32 * inconsistency in the XPath data model, and is shared with attributes 33 * which also have parents but are not children.) 34 * </p> 35 * 36 * @author Elliotte Rusty Harold 37 * @version 1.1b3 38 * 39 */ 40 public final class Namespace extends Node { 41 42 private final String prefix; 43 private final String uri; 44 45 /** 46 * Namespace URI specified for <code>xml</code> prefix 47 */ 48 public final static String XML_NAMESPACE 49 = "http://www.w3.org/XML/1998/namespace"; 50 51 52 /** 53 * <p> 54 * Create a new namespace node. 55 * </p> 56 * 57 * @param prefix the prefix for the namespace; may be the empty 58 * string or a non-colonized name 59 * @param URI the namespace URI 60 * @param parent the element that possesses this namespace node 61 * 62 * @throws MalformedURIException if <code>URI</code> is 63 * not an RFC 3986 URI reference 64 * @throws IllegalNameException if 65 * <ul> 66 * <li>The prefix is <code>xmlns</code>.</li> 67 * <li>The prefix is not the empty string, and the URI is 68 * null or the empty string.</li> 69 * </ul> 70 * @throws NamespaceConflictException if 71 * <ul> 72 * <li>The prefix is the empty string, and the URI is 73 * null or the empty string.</li> 74 * <li>The prefix is <code>xml</code>, and the URI is not 75 * <code>http://www.w3.org/XML/1998/namespace</code>.</li> 76 * <li>The prefix is not <code>xml</code>, and the URI is 77 * <code>http://www.w3.org/XML/1998/namespace</code>.</li> 78 * </ul> 79 */ Namespace(String prefix, String URI, Element parent)80 public Namespace(String prefix, String URI, Element parent) { 81 82 if (prefix == null) prefix = ""; 83 else if ("xmlns".equals(prefix)) { 84 throw new IllegalNameException( 85 "The xmlns prefix may not be bound to a URI."); 86 } 87 else if ("xml".equals(prefix)) { 88 if (! XML_NAMESPACE.equals(URI) ) { 89 throw new NamespaceConflictException( 90 "The prefix xml can only be bound to the URI " 91 + "http://www.w3.org/XML/1998/namespace"); 92 } 93 } 94 95 if (prefix.length() != 0) Verifier.checkNCName(prefix); 96 97 if (URI == null) URI = ""; 98 else if (URI.equals(XML_NAMESPACE)) { 99 if (! "xml".equals(prefix)) { 100 throw new NamespaceConflictException( 101 "The URI http://www.w3.org/XML/1998/namespace can " 102 + "only be bound to the prefix xml"); 103 } 104 } 105 106 if (URI.length() == 0) { // faster than "".equals(uri) 107 if (prefix.length() != 0) { 108 throw new NamespaceConflictException( 109 "Prefixed elements must have namespace URIs." 110 ); 111 } 112 } 113 else Verifier.checkAbsoluteURIReference(URI); 114 115 this.prefix = prefix; 116 this.uri = URI; 117 super.setParent(parent); 118 } 119 120 121 /** 122 * <p> 123 * Returns the namespace prefix, or the empty string if this node 124 * is the default namespace. 125 * </p> 126 * 127 * @return the namespace prefix 128 */ getPrefix()129 public String getPrefix() { 130 return prefix; 131 } 132 133 134 /** 135 * <p> 136 * Returns the namespace URI. 137 * </p> 138 * 139 * @return the namespace URI 140 */ getValue()141 public String getValue() { 142 return uri; 143 } 144 145 146 /** 147 * <p> 148 * Throws <code>IndexOutOfBoundsException</code> because 149 * namespaces do not have children. 150 * </p> 151 * 152 * @return never returns because document type declarations do not 153 * have children. Always throws an exception. 154 * 155 * @param position the index of the child node to return 156 * 157 * @throws IndexOutOfBoundsException because document type declarations 158 * do not have children 159 */ getChild(int position)160 public Node getChild(int position) { 161 throw new IndexOutOfBoundsException( 162 "Namespaces do not have children"); 163 } 164 165 166 /** 167 * <p> 168 * Returns 0 because namespaces do not have 169 * children. 170 * </p> 171 * 172 * @return zero 173 */ getChildCount()174 public int getChildCount() { 175 return 0; 176 } 177 178 179 /** 180 * <p> 181 * Returns a copy of this namespace which has 182 * the same prefix and URI, but no parent. 183 * </p> 184 * 185 * @return a copy of this <code>Namespace</code> 186 * that is not part of a document 187 */ copy()188 public Node copy() { 189 return new Namespace(prefix, uri, null); 190 } 191 192 193 /** 194 * <p> 195 * Removes this namespace node from its parent. 196 * </p> 197 * 198 * @see nu.xom.Node#detach() 199 */ detach()200 public void detach() { 201 super.setParent(null); 202 } 203 204 205 /** 206 * <p> 207 * Returns a string containing the actual XML 208 * form of the namespace declaration represented 209 * by this object. For example, 210 * <code>xmlns:pre="http://www.example.org/"</code>. 211 * </p> 212 * 213 * @return a <code>String</code> containing 214 * an XML namespace declaration 215 */ toXML()216 public String toXML() { 217 String colon = prefix.equals("") ? "" : ":"; 218 return "xmlns" + colon + prefix + "=\"" + uri + "\""; 219 } 220 221 222 /** 223 * <p> 224 * Returns a string form of the 225 * <code>Namespace</code> suitable for debugging 226 * and diagnosis. It deliberately does not return 227 * an actual XML namespace declaration. 228 * </p> 229 * 230 * @return a string representation of this object 231 */ toString()232 public String toString() { 233 return "[Namespace: " + this.toXML() + "]"; 234 } 235 236 237 }