1320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson/*
2320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * Licensed to the Apache Software Foundation (ASF) under one or more
3320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * contributor license agreements.  See the NOTICE file distributed with
4320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * this work for additional information regarding copyright ownership.
5320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * The ASF licenses this file to You under the Apache License, Version 2.0
6320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * (the "License"); you may not use this file except in compliance with
7320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * the License.  You may obtain a copy of the License at
8320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson *
9320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson *     http://www.apache.org/licenses/LICENSE-2.0
10320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson *
11320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * Unless required by applicable law or agreed to in writing, software
12320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
13320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * See the License for the specific language governing permissions and
15320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * limitations under the License.
16320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson */
17320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
18320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson// $Id: QName.java 754581 2009-03-15 01:32:39Z mrglavas $
19320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
20320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilsonpackage javax.xml.namespace;
21320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
22320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilsonimport java.io.IOException;
23320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilsonimport java.io.ObjectInputStream;
24320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilsonimport java.io.Serializable;
25320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilsonimport javax.xml.XMLConstants;
26320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
27f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes/**
28320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p><code>QName</code> represents a <strong>qualified name</strong>
29320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * as defined in the XML specifications: <a
30320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * href="http://www.w3.org/TR/xmlschema-2/#QName">XML Schema Part2:
31320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * Datatypes specification</a>, <a
32320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * href="http://www.w3.org/TR/REC-xml-names/#ns-qualnames">Namespaces
33320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * in XML</a>, <a
34320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * href="http://www.w3.org/XML/xml-names-19990114-errata">Namespaces
35320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * in XML Errata</a>.</p>
36320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson *
37320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>The value of a <code>QName</code> contains a <strong>Namespace
38320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * URI</strong>, <strong>local part</strong> and
39320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <strong>prefix</strong>.</p>
40320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson *
41320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>The prefix is included in <code>QName</code> to retain lexical
42320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * information <strong><em>when present</em></strong> in an {@link
43320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * javax.xml.transform.Source XML input source}. The prefix is
44320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <strong><em>NOT</em></strong> used in {@link #equals(Object)
45320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * QName.equals(Object)} or to compute the {@link #hashCode()
46320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * QName.hashCode()}.  Equality and the hash code are defined using
47320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <strong><em>only</em></strong> the Namespace URI and local part.</p>
48320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson *
49320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>If not specified, the Namespace URI is set to {@link
50320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * javax.xml.XMLConstants#NULL_NS_URI XMLConstants.NULL_NS_URI}.
51320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * If not specified, the prefix is set to {@link
52320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * javax.xml.XMLConstants#DEFAULT_NS_PREFIX
53320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * XMLConstants.DEFAULT_NS_PREFIX}.</p>
54320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson *
55320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p><code>QName</code> is immutable.</p>
56320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson *
57320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @author <a href="mailto:Jeff.Suttor@Sun.com">Jeff Suttor</a>
58320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @version $Revision: 754581 $, $Date: 2009-03-14 18:32:39 -0700 (Sat, 14 Mar 2009) $
59320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @see <a href="http://www.w3.org/TR/xmlschema-2/#QName">XML Schema Part2: Datatypes specification</a>
60320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @see <a href="http://www.w3.org/TR/REC-xml-names/#ns-qualnames">Namespaces in XML</a>
61320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @see <a href="http://www.w3.org/XML/xml-names-19990114-errata">Namespaces in XML Errata</a>
62320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @since 1.5
63320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson */
64320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
65320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilsonpublic class QName implements Serializable {
66320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
67320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    /**
68320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Stream Unique Identifier.</p>
69f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
70320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>To enable the compatibility <code>serialVersionUID</code>
71320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * set the System Property
72320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <code>org.apache.xml.namespace.QName.useCompatibleSerialVersionUID</code>
73320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * to a value of "1.0".</p>
74320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     */
75320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    private static final long serialVersionUID;
76f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
77320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    /**
78320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>The original default Stream Unique Identifier.</p>
79320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     */
80320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    private static final long defaultSerialVersionUID = -9120448754896609940L;
81f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
82320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    /**
83320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>The compatibility Stream Unique Identifier that was introduced
84320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * with Java 5 SE SDK.</p>
85320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     */
8690b140190f219fd63ede200a63da40bf9e6ca98dElliott Hughes    private static final long compatibilitySerialVersionUID = 4418622981026545151L;
87f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
88320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    static {
8990b140190f219fd63ede200a63da40bf9e6ca98dElliott Hughes        String compatPropValue = System.getProperty("org.apache.xml.namespace.QName.useCompatibleSerialVersionUID");
90320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        // If 1.0 use compatibility serialVersionUID
9190b140190f219fd63ede200a63da40bf9e6ca98dElliott Hughes        serialVersionUID = !"1.0".equals(compatPropValue) ? defaultSerialVersionUID : compatibilitySerialVersionUID;
92320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    }
93320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
94320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    /**
95320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Namespace URI of this <code>QName</code>.</p>
96320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     */
97320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    private final String namespaceURI;
98320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
99320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    /**
100320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>local part of this <code>QName</code>.</p>
101320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     */
102320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    private final String localPart;
103320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
104320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    /**
105320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>prefix of this <code>QName</code>.</p>
106320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     */
107320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    private String prefix;
108f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
109320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    /**
110320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p><code>String</code> representation of this <code>QName</code>.</p>
111320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     */
112320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    private transient String qNameAsString;
113320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
114f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes    /**
115320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p><code>QName</code> constructor specifying the Namespace URI
116320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * and local part.</p>
117320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *
118320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>If the Namespace URI is <code>null</code>, it is set to
119320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * {@link javax.xml.XMLConstants#NULL_NS_URI
120320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * XMLConstants.NULL_NS_URI}.  This value represents no
121320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * explicitly defined Namespace as defined by the <a
122320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * href="http://www.w3.org/TR/REC-xml-names/#ns-qualnames">Namespaces
123320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * in XML</a> specification.  This action preserves compatible
124320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * behavior with QName 1.0.  Explicitly providing the {@link
125320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * javax.xml.XMLConstants#NULL_NS_URI
126320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * XMLConstants.NULL_NS_URI} value is the preferred coding
127320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * style.</p>
128320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *
129320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>If the local part is <code>null</code> an
130320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <code>IllegalArgumentException</code> is thrown.
131320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * A local part of "" is allowed to preserve
132320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * compatible behavior with QName 1.0. </p>
133320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *
134320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>When using this constructor, the prefix is set to {@link
135320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * javax.xml.XMLConstants#DEFAULT_NS_PREFIX
136320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * XMLConstants.DEFAULT_NS_PREFIX}.</p>
137320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *
138320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>The Namespace URI is not validated as a
139320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <a href="http://www.ietf.org/rfc/rfc2396.txt">URI reference</a>.
140320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * The local part is not validated as a
141320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <a href="http://www.w3.org/TR/REC-xml-names/#NT-NCName">NCName</a>
142320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * as specified in <a href="http://www.w3.org/TR/REC-xml-names/">Namespaces
143320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * in XML</a>.</p>
144320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *
145320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param namespaceURI Namespace URI of the <code>QName</code>
146320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param localPart    local part of the <code>QName</code>
147f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
148320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @see #QName(String namespaceURI, String localPart, String
149320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * prefix) QName(String namespaceURI, String localPart, String
150320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * prefix)
151320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     */
152320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    public QName(final String namespaceURI, final String localPart) {
153320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        this(namespaceURI, localPart, XMLConstants.DEFAULT_NS_PREFIX);
154320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    }
155320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
156f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes    /**
157320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p><code>QName</code> constructor specifying the Namespace URI,
158320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * local part and prefix.</p>
159320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *
160320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>If the Namespace URI is <code>null</code>, it is set to
161320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * {@link javax.xml.XMLConstants#NULL_NS_URI
162320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * XMLConstants.NULL_NS_URI}.  This value represents no
163320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * explicitly defined Namespace as defined by the <a
164320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * href="http://www.w3.org/TR/REC-xml-names/#ns-qualnames">Namespaces
165320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * in XML</a> specification.  This action preserves compatible
166320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * behavior with QName 1.0.  Explicitly providing the {@link
167320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * javax.xml.XMLConstants#NULL_NS_URI
168320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * XMLConstants.NULL_NS_URI} value is the preferred coding
169320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * style.</p>
170f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
171320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>If the local part is <code>null</code> an
172320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <code>IllegalArgumentException</code> is thrown.
173320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * A local part of "" is allowed to preserve
174320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * compatible behavior with QName 1.0. </p>
175f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
176320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>If the prefix is <code>null</code>, an
177320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <code>IllegalArgumentException</code> is thrown.  Use {@link
178320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * javax.xml.XMLConstants#DEFAULT_NS_PREFIX
179320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * XMLConstants.DEFAULT_NS_PREFIX} to explicitly indicate that no
180320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * prefix is present or the prefix is not relevant.</p>
181320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *
182320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>The Namespace URI is not validated as a
183320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <a href="http://www.ietf.org/rfc/rfc2396.txt">URI reference</a>.
184320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * The local part and prefix are not validated as a
185320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <a href="http://www.w3.org/TR/REC-xml-names/#NT-NCName">NCName</a>
186320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * as specified in <a href="http://www.w3.org/TR/REC-xml-names/">Namespaces
187320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * in XML</a>.</p>
188320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *
189320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param namespaceURI Namespace URI of the <code>QName</code>
190320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param localPart    local part of the <code>QName</code>
191320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param prefix       prefix of the <code>QName</code>
192320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     */
193320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    public QName(String namespaceURI, String localPart, String prefix) {
194320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
195320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        // map null Namespace URI to default to preserve compatibility with QName 1.0
196320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        if (namespaceURI == null) {
197320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            this.namespaceURI = XMLConstants.NULL_NS_URI;
198320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        } else {
199320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            this.namespaceURI = namespaceURI;
200320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        }
201320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
202f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        // local part is required.  "" is allowed to preserve compatibility with QName 1.0
203320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        if (localPart == null) {
204320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            throw new IllegalArgumentException("local part cannot be \"null\" when creating a QName");
205320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        }
206320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        this.localPart = localPart;
207320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
208f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        // prefix is required
209320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        if (prefix == null) {
210320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            throw new IllegalArgumentException("prefix cannot be \"null\" when creating a QName");
211320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        }
212320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        this.prefix = prefix;
213320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    }
214320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
215f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes    /**
216320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p><code>QName</code> constructor specifying the local part.</p>
217320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *
218320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>If the local part is <code>null</code> an
219320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <code>IllegalArgumentException</code> is thrown.
220320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * A local part of "" is allowed to preserve
221320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * compatible behavior with QName 1.0. </p>
222320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *
223320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>When using this constructor, the Namespace URI is set to
224320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * {@link javax.xml.XMLConstants#NULL_NS_URI
225320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * XMLConstants.NULL_NS_URI} and the prefix is set to {@link
226320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * javax.xml.XMLConstants#DEFAULT_NS_PREFIX
227320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * XMLConstants.DEFAULT_NS_PREFIX}.</p>
228320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *
229320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p><em>In an XML context, all Element and Attribute names exist
230320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * in the context of a Namespace.  Making this explicit during the
231320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * construction of a <code>QName</code> helps prevent hard to
232320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * diagnosis XML validity errors.  The constructors {@link
233320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * #QName(String namespaceURI, String localPart) QName(String
234320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * namespaceURI, String localPart)} and
235f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * {@link #QName(String namespaceURI, String localPart, String prefix)}
236320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * are preferred.</em></p>
237f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
238320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>The local part is not validated as a
239320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <a href="http://www.w3.org/TR/REC-xml-names/#NT-NCName">NCName</a>
240320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * as specified in <a href="http://www.w3.org/TR/REC-xml-names/">Namespaces
241320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * in XML</a>.</p>
242320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *
243320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param localPart local part of the <code>QName</code>
244320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @see #QName(String namespaceURI, String localPart) QName(String
245320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * namespaceURI, String localPart)
246320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @see #QName(String namespaceURI, String localPart, String
247320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * prefix) QName(String namespaceURI, String localPart, String
248320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * prefix)
249320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     */
250320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    public QName(String localPart) {
251320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        this(
252320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            XMLConstants.NULL_NS_URI,
253320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            localPart,
254320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            XMLConstants.DEFAULT_NS_PREFIX);
255320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    }
256f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
257f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes    /**
258320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Get the Namespace URI of this <code>QName</code>.</p>
259320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *
260320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @return Namespace URI of this <code>QName</code>
261320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     */
262320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    public String getNamespaceURI() {
263320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        return namespaceURI;
264320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    }
265320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
266320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    /**
267320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Get the local part of this <code>QName</code>.</p>
268320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *
269320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *  @return local part of this <code>QName</code>
270320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     */
271320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    public String getLocalPart() {
272320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        return localPart;
273320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    }
274320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
275f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes    /**
276320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Get the prefix of this <code>QName</code>.</p>
277320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *
278320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>The prefix assigned to a <code>QName</code> might
279320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <strong><em>NOT</em></strong> be valid in a different
280320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * context. For example, a <code>QName</code> may be assigned a
281320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * prefix in the context of parsing a document but that prefix may
282320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * be invalid in the context of a different document.</p>
283320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *
284320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *  @return prefix of this <code>QName</code>
285320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     */
286320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    public String getPrefix() {
287320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        return prefix;
288320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    }
289320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
290320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    /**
291320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Test this <code>QName</code> for equality with another
292320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <code>Object</code>.</p>
293320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *
294320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>If the <code>Object</code> to be tested is not a
295320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <code>QName</code> or is <code>null</code>, then this method
296320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * returns <code>false</code>.</p>
297320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *
298320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Two <code>QName</code>s are considered equal if and only if
299320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * both the Namespace URI and local part are equal. This method
300320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * uses <code>String.equals()</code> to check equality of the
301320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * Namespace URI and local part. The prefix is
302320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <strong><em>NOT</em></strong> used to determine equality.</p>
303320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *
304320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>This method satisfies the general contract of {@link
305320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * java.lang.Object#equals(Object) Object.equals(Object)}</p>
306320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *
307320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param objectToTest the <code>Object</code> to test for
308320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * equality with this <code>QName</code>
309320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @return <code>true</code> if the given <code>Object</code> is
310320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * equal to this <code>QName</code> else <code>false</code>
311320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     */
312320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    public final boolean equals(Object objectToTest) {
313320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        // Is this the same object?
314320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        if (objectToTest == this) {
315320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            return true;
316320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        }
317320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        // Is this a QName?
318320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        if (objectToTest instanceof QName) {
319320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            QName qName = (QName) objectToTest;
320320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            return localPart.equals(qName.localPart) && namespaceURI.equals(qName.namespaceURI);
321320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        }
322320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        return false;
323320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    }
324320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
325320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    /**
326320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Generate the hash code for this <code>QName</code>.</p>
327320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *
328320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>The hash code is calculated using both the Namespace URI and
329320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * the local part of the <code>QName</code>.  The prefix is
330320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <strong><em>NOT</em></strong> used to calculate the hash
331320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * code.</p>
332320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *
333320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>This method satisfies the general contract of {@link
334320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * java.lang.Object#hashCode() Object.hashCode()}.</p>
335320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *
336320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @return hash code for this <code>QName</code> <code>Object</code>
337320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     */
338320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    public final int hashCode() {
339320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        return namespaceURI.hashCode() ^ localPart.hashCode();
340320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    }
341320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
342f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes    /**
343d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes     * <p><code>String</code> representation of this
344d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes     * <code>QName</code>.</p>
345d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes     *
346d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes     * <p>The commonly accepted way of representing a <code>QName</code>
347d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes     * as a <code>String</code> was <a href="http://jclark.com/xml/xmlns.htm">defined</a>
348d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes     * by James Clark.  Although this is not a <em>standard</em>
349d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes     * specification, it is in common use,  e.g. {@link javax.xml.transform.Transformer#setParameter(String name, Object value)}.
350d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes     * This implementation represents a <code>QName</code> as:
351d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes     * "{" + Namespace URI + "}" + local part.  If the Namespace URI
352d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes     * <code>.equals(XMLConstants.NULL_NS_URI)</code>, only the
353d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes     * local part is returned.  An appropriate use of this method is
354d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes     * for debugging or logging for human consumption.</p>
355d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes     *
356d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes     * <p>Note the prefix value is <strong><em>NOT</em></strong>
357d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes     * returned as part of the <code>String</code> representation.</p>
358f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
359d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes     * <p>This method satisfies the general contract of {@link
360d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes     * java.lang.Object#toString() Object.toString()}.</p>
361d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes     *
362d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes     * @return <code>String</code> representation of this <code>QName</code>
363d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes     */
364320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    public String toString() {
365320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        String _qNameAsString = qNameAsString;
366320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        if (_qNameAsString == null) {
367320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int nsLength = namespaceURI.length();
368320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            if (nsLength == 0) {
369320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                _qNameAsString = localPart;
370320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            }
371320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            else {
3727f0c06f737b6f1f6b3a5bb30111f95dd0ca586a2Brian Carlstrom                StringBuilder buffer = new StringBuilder(nsLength + localPart.length() + 2);
373320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                buffer.append('{');
374320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                buffer.append(namespaceURI);
375320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                buffer.append('}');
376320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                buffer.append(localPart);
377320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                _qNameAsString = buffer.toString();
378320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            }
379320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            qNameAsString = _qNameAsString;
380320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        }
381320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        return _qNameAsString;
382320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    }
383320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
384f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes    /**
385320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p><code>QName</code> derived from parsing the formatted
386320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <code>String</code>.</p>
387320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *
388320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>If the <code>String</code> is <code>null</code> or does not conform to
389320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * {@link #toString() QName.toString()} formatting, an
390320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <code>IllegalArgumentException</code> is thrown.</p>
391f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
392320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p><em>The <code>String</code> <strong>MUST</strong> be in the
393320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * form returned by {@link #toString() QName.toString()}.</em></p>
394320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *
395320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>The commonly accepted way of representing a <code>QName</code>
396320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * as a <code>String</code> was <a href="http://jclark.com/xml/xmlns.htm">defined</a>
397320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * by James Clark.  Although this is not a <em>standard</em>
398320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * specification, it is in common use,  e.g. {@link javax.xml.transform.Transformer#setParameter(String name, Object value)}.
399320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * This implementation parses a <code>String</code> formatted
400320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * as: "{" + Namespace URI + "}" + local part.  If the Namespace
401320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * URI <code>.equals(XMLConstants.NULL_NS_URI)</code>, only the
402320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * local part should be provided.</p>
403320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *
404320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>The prefix value <strong><em>CANNOT</em></strong> be
405320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * represented in the <code>String</code> and will be set to
406320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * {@link javax.xml.XMLConstants#DEFAULT_NS_PREFIX
407320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * XMLConstants.DEFAULT_NS_PREFIX}.</p>
408320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *
409320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>This method does not do full validation of the resulting
410f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * <code>QName</code>.
411320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>The Namespace URI is not validated as a
412320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <a href="http://www.ietf.org/rfc/rfc2396.txt">URI reference</a>.
413320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * The local part is not validated as a
414320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <a href="http://www.w3.org/TR/REC-xml-names/#NT-NCName">NCName</a>
415320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * as specified in
416320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <a href="http://www.w3.org/TR/REC-xml-names/">Namespaces in XML</a>.</p>
417320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *
418320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param qNameAsString <code>String</code> representation
419320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * of the <code>QName</code>
420320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @return <code>QName</code> corresponding to the given <code>String</code>
421320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @see #toString() QName.toString()
422320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     */
423320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    public static QName valueOf(String qNameAsString) {
424320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
425320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        // null is not valid
426320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        if (qNameAsString == null) {
427320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            throw new IllegalArgumentException("cannot create QName from \"null\" or \"\" String");
428320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        }
429320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
430320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        // "" local part is valid to preserve compatible behavior with QName 1.0
431320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        if (qNameAsString.length() == 0) {
432320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            return new QName(
433320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                XMLConstants.NULL_NS_URI,
434320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                qNameAsString,
435320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                XMLConstants.DEFAULT_NS_PREFIX);
436320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        }
437320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
438320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        // local part only?
439320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        if (qNameAsString.charAt(0) != '{') {
440320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            return new QName(
441320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                XMLConstants.NULL_NS_URI,
442320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                qNameAsString,
443320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                XMLConstants.DEFAULT_NS_PREFIX);
444320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        }
445320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
446320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        // Namespace URI improperly specified?
447320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        if (qNameAsString.startsWith("{" + XMLConstants.NULL_NS_URI + "}")) {
448320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            throw new IllegalArgumentException(
449320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                "Namespace URI .equals(XMLConstants.NULL_NS_URI), "
450320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                + ".equals(\"" + XMLConstants.NULL_NS_URI + "\"), "
451320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                + "only the local part, "
452320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                + "\"" + qNameAsString.substring(2 + XMLConstants.NULL_NS_URI.length()) + "\", "
453320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                + "should be provided.");
454320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        }
455320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
456320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        // Namespace URI and local part specified
457320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        int endOfNamespaceURI = qNameAsString.indexOf('}');
458320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        if (endOfNamespaceURI == -1) {
459320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            throw new IllegalArgumentException(
460320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                "cannot create QName from \""
461320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                    + qNameAsString
462320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                    + "\", missing closing \"}\"");
463320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        }
464320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        return new QName(
465320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            qNameAsString.substring(1, endOfNamespaceURI),
466320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            qNameAsString.substring(endOfNamespaceURI + 1),
467320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            XMLConstants.DEFAULT_NS_PREFIX);
468320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    }
469f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
470320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    /*
471320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * For old versions of QName which didn't have a prefix field,
472320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <code>ObjectInputStream.defaultReadObject()</code> will initialize
473320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * the prefix to <code>null</code> instead of the empty string. This
474320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * method fixes up the prefix field if it didn't exist in the serialized
475320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * object.
476320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     */
477f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes    private void readObject(ObjectInputStream in)
478320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        throws IOException, ClassNotFoundException {
479320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        in.defaultReadObject();
480320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        if (prefix == null) {
481320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            prefix = XMLConstants.DEFAULT_NS_PREFIX;
482320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        }
483320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    }
484320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson}
485