1 /* 2 * The Apache Software License, Version 1.1 3 * 4 * 5 * Copyright (c) 2001-2003 The Apache Software Foundation. All rights 6 * reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. The end-user documentation included with the redistribution, 21 * if any, must include the following acknowledgment: 22 * "This product includes software developed by the 23 * Apache Software Foundation (http://www.apache.org/)." 24 * Alternately, this acknowledgment may appear in the software itself, 25 * if and wherever such third-party acknowledgments normally appear. 26 * 27 * 4. The names "Axis" and "Apache Software Foundation" must 28 * not be used to endorse or promote products derived from this 29 * software without prior written permission. For written 30 * permission, please contact apache@apache.org. 31 * 32 * 5. Products derived from this software may not be called "Apache", 33 * nor may "Apache" appear in their name, without prior written 34 * permission of the Apache Software Foundation. 35 * 36 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 37 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 38 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 39 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 42 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 43 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 44 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 45 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 46 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 47 * SUCH DAMAGE. 48 * ==================================================================== 49 * 50 * This software consists of voluntary contributions made by many 51 * individuals on behalf of the Apache Software Foundation. For more 52 * information on the Apache Software Foundation, please see 53 * <http://www.apache.org/>. 54 */ 55 package com.kenai.jbosh; 56 57 import java.io.IOException; 58 import java.io.ObjectInputStream; 59 import java.io.Serializable; 60 61 /** 62 * <code>QName</code> class represents the value of a qualified name 63 * as specified in <a href="http://www.w3.org/TR/xmlschema-2/#QName">XML 64 * Schema Part2: Datatypes specification</a>. 65 * <p> 66 * The value of a QName contains a <b>namespaceURI</b>, a <b>localPart</b> and a <b>prefix</b>. 67 * The localPart provides the local part of the qualified name. The 68 * namespaceURI is a URI reference identifying the namespace. 69 * 70 * @version 1.1 71 */ 72 public class QName implements Serializable { 73 74 /** comment/shared empty string */ 75 private static final String emptyString = "".intern(); 76 77 /** Field namespaceURI */ 78 private String namespaceURI; 79 80 /** Field localPart */ 81 private String localPart; 82 83 /** Field prefix */ 84 private String prefix; 85 86 /** 87 * Constructor for the QName. 88 * 89 * @param localPart Local part of the QName 90 */ QName(String localPart)91 public QName(String localPart) { 92 this(emptyString, localPart, emptyString); 93 } 94 95 /** 96 * Constructor for the QName. 97 * 98 * @param namespaceURI Namespace URI for the QName 99 * @param localPart Local part of the QName. 100 */ QName(String namespaceURI, String localPart)101 public QName(String namespaceURI, String localPart) { 102 this(namespaceURI, localPart, emptyString); 103 } 104 105 /** 106 * Constructor for the QName. 107 * 108 * @param namespaceURI Namespace URI for the QName 109 * @param localPart Local part of the QName. 110 * @param prefix Prefix of the QName. 111 */ QName(String namespaceURI, String localPart, String prefix)112 public QName(String namespaceURI, String localPart, String prefix) { 113 this.namespaceURI = (namespaceURI == null) 114 ? emptyString 115 : namespaceURI.intern(); 116 if (localPart == null) { 117 throw new IllegalArgumentException("invalid QName local part"); 118 } else { 119 this.localPart = localPart.intern(); 120 } 121 122 if (prefix == null) { 123 throw new IllegalArgumentException("invalid QName prefix"); 124 } else { 125 this.prefix = prefix.intern(); 126 } 127 } 128 129 /** 130 * Gets the Namespace URI for this QName 131 * 132 * @return Namespace URI 133 */ getNamespaceURI()134 public String getNamespaceURI() { 135 return namespaceURI; 136 } 137 138 /** 139 * Gets the Local part for this QName 140 * 141 * @return Local part 142 */ getLocalPart()143 public String getLocalPart() { 144 return localPart; 145 } 146 147 /** 148 * Gets the Prefix for this QName 149 * 150 * @return Prefix 151 */ getPrefix()152 public String getPrefix() { 153 return prefix; 154 } 155 156 /** 157 * Returns a string representation of this QName 158 * 159 * @return a string representation of the QName 160 */ toString()161 public String toString() { 162 163 return ((namespaceURI == emptyString) 164 ? localPart 165 : '{' + namespaceURI + '}' + localPart); 166 } 167 168 /** 169 * Tests this QName for equality with another object. 170 * <p> 171 * If the given object is not a QName or is null then this method 172 * returns <tt>false</tt>. 173 * <p> 174 * For two QNames to be considered equal requires that both 175 * localPart and namespaceURI must be equal. This method uses 176 * <code>String.equals</code> to check equality of localPart 177 * and namespaceURI. Any class that extends QName is required 178 * to satisfy this equality contract. 179 * <p> 180 * This method satisfies the general contract of the <code>Object.equals</code> method. 181 * 182 * @param obj the reference object with which to compare 183 * 184 * @return <code>true</code> if the given object is identical to this 185 * QName: <code>false</code> otherwise. 186 */ equals(Object obj)187 public final boolean equals(Object obj) { 188 189 if (obj == this) { 190 return true; 191 } 192 193 if (!(obj instanceof QName)) { 194 return false; 195 } 196 197 if ((namespaceURI == ((QName) obj).namespaceURI) 198 && (localPart == ((QName) obj).localPart)) { 199 return true; 200 } 201 202 return false; 203 } 204 205 /** 206 * Returns a QName holding the value of the specified String. 207 * <p> 208 * The string must be in the form returned by the QName.toString() 209 * method, i.e. "{namespaceURI}localPart", with the "{namespaceURI}" 210 * part being optional. 211 * <p> 212 * This method doesn't do a full validation of the resulting QName. 213 * In particular, it doesn't check that the resulting namespace URI 214 * is a legal URI (per RFC 2396 and RFC 2732), nor that the resulting 215 * local part is a legal NCName per the XML Namespaces specification. 216 * 217 * @param s the string to be parsed 218 * @throws java.lang.IllegalArgumentException If the specified String cannot be parsed as a QName 219 * @return QName corresponding to the given String 220 */ valueOf(String s)221 public static QName valueOf(String s) { 222 223 if ((s == null) || s.equals("")) { 224 throw new IllegalArgumentException("invalid QName literal"); 225 } 226 227 if (s.charAt(0) == '{') { 228 int i = s.indexOf('}'); 229 230 if (i == -1) { 231 throw new IllegalArgumentException("invalid QName literal"); 232 } 233 234 if (i == s.length() - 1) { 235 throw new IllegalArgumentException("invalid QName literal"); 236 } else { 237 return new QName(s.substring(1, i), s.substring(i + 1)); 238 } 239 } else { 240 return new QName(s); 241 } 242 } 243 244 /** 245 * Returns a hash code value for this QName object. The hash code 246 * is based on both the localPart and namespaceURI parts of the 247 * QName. This method satisfies the general contract of the 248 * <code>Object.hashCode</code> method. 249 * 250 * @return a hash code value for this Qname object 251 */ hashCode()252 public final int hashCode() { 253 return namespaceURI.hashCode() ^ localPart.hashCode(); 254 } 255 256 /** 257 * Ensure that deserialization properly interns the results. 258 * @param in the ObjectInputStream to be read 259 */ readObject(ObjectInputStream in)260 private void readObject(ObjectInputStream in) throws 261 IOException, ClassNotFoundException { 262 in.defaultReadObject(); 263 264 namespaceURI = namespaceURI.intern(); 265 localPart = localPart.intern(); 266 prefix = prefix.intern(); 267 } 268 } 269 270