Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jaxp/src/javax/xml/namespace/QName.java
48534 views
1
/*
2
* Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package javax.xml.namespace;
27
28
import java.io.Serializable;
29
import java.security.AccessController;
30
import java.security.PrivilegedAction;
31
32
import javax.xml.XMLConstants;
33
34
/**
35
* <p><code>QName</code> represents a <strong>qualified name</strong>
36
* as defined in the XML specifications: <a
37
* href="http://www.w3.org/TR/xmlschema-2/#QName">XML Schema Part2:
38
* Datatypes specification</a>, <a
39
* href="http://www.w3.org/TR/REC-xml-names/#ns-qualnames">Namespaces
40
* in XML</a>, <a
41
* href="http://www.w3.org/XML/xml-names-19990114-errata">Namespaces
42
* in XML Errata</a>.</p>
43
*
44
* <p>The value of a <code>QName</code> contains a <strong>Namespace
45
* URI</strong>, <strong>local part</strong> and
46
* <strong>prefix</strong>.</p>
47
*
48
* <p>The prefix is included in <code>QName</code> to retain lexical
49
* information <strong><em>when present</em></strong> in an {@link
50
* javax.xml.transform.Source XML input source}. The prefix is
51
* <strong><em>NOT</em></strong> used in {@link #equals(Object)
52
* QName.equals(Object)} or to compute the {@link #hashCode()
53
* QName.hashCode()}. Equality and the hash code are defined using
54
* <strong><em>only</em></strong> the Namespace URI and local part.</p>
55
*
56
* <p>If not specified, the Namespace URI is set to {@link
57
* javax.xml.XMLConstants#NULL_NS_URI XMLConstants.NULL_NS_URI}.
58
* If not specified, the prefix is set to {@link
59
* javax.xml.XMLConstants#DEFAULT_NS_PREFIX
60
* XMLConstants.DEFAULT_NS_PREFIX}.</p>
61
*
62
* <p><code>QName</code> is immutable.</p>
63
*
64
* @author <a href="mailto:[email protected]">Jeff Suttor</a>
65
* @version $Revision: 1.8 $, $Date: 2010/03/18 03:06:17 $
66
* @see <a href="http://www.w3.org/TR/xmlschema-2/#QName">
67
* XML Schema Part2: Datatypes specification</a>
68
* @see <a href="http://www.w3.org/TR/REC-xml-names/#ns-qualnames">
69
* Namespaces in XML</a>
70
* @see <a href="http://www.w3.org/XML/xml-names-19990114-errata">
71
* Namespaces in XML Errata</a>
72
* @since 1.5
73
*/
74
75
public class QName implements Serializable {
76
77
/**
78
* <p>Stream Unique Identifier.</p>
79
*
80
* <p>Due to a historical defect, QName was released with multiple
81
* serialVersionUID values even though its serialization was the
82
* same.</p>
83
*
84
* <p>To workaround this issue, serialVersionUID is set with either
85
* a default value or a compatibility value. To use the
86
* compatiblity value, set the system property:</p>
87
*
88
* <code>com.sun.xml.namespace.QName.useCompatibleSerialVersionUID=1.0</code>
89
*
90
* <p>This workaround was inspired by classes in the javax.management
91
* package, e.g. ObjectName, etc.
92
* See CR6267224 for original defect report.</p>
93
*/
94
private static final long serialVersionUID;
95
/**
96
* <p>Default <code>serialVersionUID</code> value.</p>
97
*/
98
private static final long defaultSerialVersionUID = -9120448754896609940L;
99
/**
100
* <p>Compatibility <code>serialVersionUID</code> value.</p>
101
*/
102
private static final long compatibleSerialVersionUID = 4418622981026545151L;
103
/**
104
* <p>Flag to use default or campatible serialVersionUID.</p>
105
*/
106
private static boolean useDefaultSerialVersionUID = true;
107
static {
108
try {
109
// use a privileged block as reading a system property
110
String valueUseCompatibleSerialVersionUID = (String) AccessController.doPrivileged(
111
new PrivilegedAction() {
112
public Object run() {
113
return System.getProperty("com.sun.xml.namespace.QName.useCompatibleSerialVersionUID");
114
}
115
}
116
);
117
useDefaultSerialVersionUID = (valueUseCompatibleSerialVersionUID != null && valueUseCompatibleSerialVersionUID.equals("1.0")) ? false : true;
118
} catch (Exception exception) {
119
// use default if any Exceptions
120
useDefaultSerialVersionUID = true;
121
}
122
123
// set serialVersionUID to desired value
124
if (useDefaultSerialVersionUID) {
125
serialVersionUID = defaultSerialVersionUID;
126
} else {
127
serialVersionUID = compatibleSerialVersionUID;
128
}
129
}
130
131
/**
132
* <p>Namespace URI of this <code>QName</code>.</p>
133
*/
134
private final String namespaceURI;
135
136
/**
137
* <p>local part of this <code>QName</code>.</p>
138
*/
139
private final String localPart;
140
141
/**
142
* <p>prefix of this <code>QName</code>.</p>
143
*/
144
private final String prefix;
145
146
/**
147
* <p><code>QName</code> constructor specifying the Namespace URI
148
* and local part.</p>
149
*
150
* <p>If the Namespace URI is <code>null</code>, it is set to
151
* {@link javax.xml.XMLConstants#NULL_NS_URI
152
* XMLConstants.NULL_NS_URI}. This value represents no
153
* explicitly defined Namespace as defined by the <a
154
* href="http://www.w3.org/TR/REC-xml-names/#ns-qualnames">Namespaces
155
* in XML</a> specification. This action preserves compatible
156
* behavior with QName 1.0. Explicitly providing the {@link
157
* javax.xml.XMLConstants#NULL_NS_URI
158
* XMLConstants.NULL_NS_URI} value is the preferred coding
159
* style.</p>
160
*
161
* <p>If the local part is <code>null</code> an
162
* <code>IllegalArgumentException</code> is thrown.
163
* A local part of "" is allowed to preserve
164
* compatible behavior with QName 1.0. </p>
165
*
166
* <p>When using this constructor, the prefix is set to {@link
167
* javax.xml.XMLConstants#DEFAULT_NS_PREFIX
168
* XMLConstants.DEFAULT_NS_PREFIX}.</p>
169
*
170
* <p>The Namespace URI is not validated as a
171
* <a href="http://www.ietf.org/rfc/rfc2396.txt">URI reference</a>.
172
* The local part is not validated as a
173
* <a href="http://www.w3.org/TR/REC-xml-names/#NT-NCName">NCName</a>
174
* as specified in <a href="http://www.w3.org/TR/REC-xml-names/">Namespaces
175
* in XML</a>.</p>
176
*
177
* @param namespaceURI Namespace URI of the <code>QName</code>
178
* @param localPart local part of the <code>QName</code>
179
*
180
* @throws IllegalArgumentException When <code>localPart</code> is
181
* <code>null</code>
182
*
183
* @see #QName(String namespaceURI, String localPart, String
184
* prefix) QName(String namespaceURI, String localPart, String
185
* prefix)
186
*/
187
public QName(final String namespaceURI, final String localPart) {
188
this(namespaceURI, localPart, XMLConstants.DEFAULT_NS_PREFIX);
189
}
190
191
/**
192
* <p><code>QName</code> constructor specifying the Namespace URI,
193
* local part and prefix.</p>
194
*
195
* <p>If the Namespace URI is <code>null</code>, it is set to
196
* {@link javax.xml.XMLConstants#NULL_NS_URI
197
* XMLConstants.NULL_NS_URI}. This value represents no
198
* explicitly defined Namespace as defined by the <a
199
* href="http://www.w3.org/TR/REC-xml-names/#ns-qualnames">Namespaces
200
* in XML</a> specification. This action preserves compatible
201
* behavior with QName 1.0. Explicitly providing the {@link
202
* javax.xml.XMLConstants#NULL_NS_URI
203
* XMLConstants.NULL_NS_URI} value is the preferred coding
204
* style.</p>
205
*
206
* <p>If the local part is <code>null</code> an
207
* <code>IllegalArgumentException</code> is thrown.
208
* A local part of "" is allowed to preserve
209
* compatible behavior with QName 1.0. </p>
210
*
211
* <p>If the prefix is <code>null</code>, an
212
* <code>IllegalArgumentException</code> is thrown. Use {@link
213
* javax.xml.XMLConstants#DEFAULT_NS_PREFIX
214
* XMLConstants.DEFAULT_NS_PREFIX} to explicitly indicate that no
215
* prefix is present or the prefix is not relevant.</p>
216
*
217
* <p>The Namespace URI is not validated as a
218
* <a href="http://www.ietf.org/rfc/rfc2396.txt">URI reference</a>.
219
* The local part and prefix are not validated as a
220
* <a href="http://www.w3.org/TR/REC-xml-names/#NT-NCName">NCName</a>
221
* as specified in <a href="http://www.w3.org/TR/REC-xml-names/">Namespaces
222
* in XML</a>.</p>
223
*
224
* @param namespaceURI Namespace URI of the <code>QName</code>
225
* @param localPart local part of the <code>QName</code>
226
* @param prefix prefix of the <code>QName</code>
227
*
228
* @throws IllegalArgumentException When <code>localPart</code>
229
* or <code>prefix</code> is <code>null</code>
230
*/
231
public QName(String namespaceURI, String localPart, String prefix) {
232
233
// map null Namespace URI to default
234
// to preserve compatibility with QName 1.0
235
if (namespaceURI == null) {
236
this.namespaceURI = XMLConstants.NULL_NS_URI;
237
} else {
238
this.namespaceURI = namespaceURI;
239
}
240
241
// local part is required.
242
// "" is allowed to preserve compatibility with QName 1.0
243
if (localPart == null) {
244
throw new IllegalArgumentException(
245
"local part cannot be \"null\" when creating a QName");
246
}
247
this.localPart = localPart;
248
249
// prefix is required
250
if (prefix == null) {
251
throw new IllegalArgumentException(
252
"prefix cannot be \"null\" when creating a QName");
253
}
254
this.prefix = prefix;
255
}
256
257
/**
258
* <p><code>QName</code> constructor specifying the local part.</p>
259
*
260
* <p>If the local part is <code>null</code> an
261
* <code>IllegalArgumentException</code> is thrown.
262
* A local part of "" is allowed to preserve
263
* compatible behavior with QName 1.0. </p>
264
*
265
* <p>When using this constructor, the Namespace URI is set to
266
* {@link javax.xml.XMLConstants#NULL_NS_URI
267
* XMLConstants.NULL_NS_URI} and the prefix is set to {@link
268
* javax.xml.XMLConstants#DEFAULT_NS_PREFIX
269
* XMLConstants.DEFAULT_NS_PREFIX}.</p>
270
*
271
* <p><em>In an XML context, all Element and Attribute names exist
272
* in the context of a Namespace. Making this explicit during the
273
* construction of a <code>QName</code> helps prevent hard to
274
* diagnosis XML validity errors. The constructors {@link
275
* #QName(String namespaceURI, String localPart) QName(String
276
* namespaceURI, String localPart)} and
277
* {@link #QName(String namespaceURI, String localPart, String prefix)}
278
* are preferred.</em></p>
279
*
280
* <p>The local part is not validated as a
281
* <a href="http://www.w3.org/TR/REC-xml-names/#NT-NCName">NCName</a>
282
* as specified in <a href="http://www.w3.org/TR/REC-xml-names/">Namespaces
283
* in XML</a>.</p>
284
*
285
* @param localPart local part of the <code>QName</code>
286
*
287
* @throws IllegalArgumentException When <code>localPart</code> is
288
* <code>null</code>
289
*
290
* @see #QName(String namespaceURI, String localPart) QName(String
291
* namespaceURI, String localPart)
292
* @see #QName(String namespaceURI, String localPart, String
293
* prefix) QName(String namespaceURI, String localPart, String
294
* prefix)
295
*/
296
public QName(String localPart) {
297
this(
298
XMLConstants.NULL_NS_URI,
299
localPart,
300
XMLConstants.DEFAULT_NS_PREFIX);
301
}
302
303
/**
304
* <p>Get the Namespace URI of this <code>QName</code>.</p>
305
*
306
* @return Namespace URI of this <code>QName</code>
307
*/
308
public String getNamespaceURI() {
309
return namespaceURI;
310
}
311
312
/**
313
* <p>Get the local part of this <code>QName</code>.</p>
314
*
315
* @return local part of this <code>QName</code>
316
*/
317
public String getLocalPart() {
318
return localPart;
319
}
320
321
/**
322
* <p>Get the prefix of this <code>QName</code>.</p>
323
*
324
* <p>The prefix assigned to a <code>QName</code> might
325
* <strong><em>NOT</em></strong> be valid in a different
326
* context. For example, a <code>QName</code> may be assigned a
327
* prefix in the context of parsing a document but that prefix may
328
* be invalid in the context of a different document.</p>
329
*
330
* @return prefix of this <code>QName</code>
331
*/
332
public String getPrefix() {
333
return prefix;
334
}
335
336
/**
337
* <p>Test this <code>QName</code> for equality with another
338
* <code>Object</code>.</p>
339
*
340
* <p>If the <code>Object</code> to be tested is not a
341
* <code>QName</code> or is <code>null</code>, then this method
342
* returns <code>false</code>.</p>
343
*
344
* <p>Two <code>QName</code>s are considered equal if and only if
345
* both the Namespace URI and local part are equal. This method
346
* uses <code>String.equals()</code> to check equality of the
347
* Namespace URI and local part. The prefix is
348
* <strong><em>NOT</em></strong> used to determine equality.</p>
349
*
350
* <p>This method satisfies the general contract of {@link
351
* java.lang.Object#equals(Object) Object.equals(Object)}</p>
352
*
353
* @param objectToTest the <code>Object</code> to test for
354
* equality with this <code>QName</code>
355
* @return <code>true</code> if the given <code>Object</code> is
356
* equal to this <code>QName</code> else <code>false</code>
357
*/
358
public final boolean equals(Object objectToTest) {
359
if (objectToTest == this) {
360
return true;
361
}
362
363
if (objectToTest == null || !(objectToTest instanceof QName)) {
364
return false;
365
}
366
367
QName qName = (QName) objectToTest;
368
369
return localPart.equals(qName.localPart)
370
&& namespaceURI.equals(qName.namespaceURI);
371
}
372
373
/**
374
* <p>Generate the hash code for this <code>QName</code>.</p>
375
*
376
* <p>The hash code is calculated using both the Namespace URI and
377
* the local part of the <code>QName</code>. The prefix is
378
* <strong><em>NOT</em></strong> used to calculate the hash
379
* code.</p>
380
*
381
* <p>This method satisfies the general contract of {@link
382
* java.lang.Object#hashCode() Object.hashCode()}.</p>
383
*
384
* @return hash code for this <code>QName</code> <code>Object</code>
385
*/
386
public final int hashCode() {
387
return namespaceURI.hashCode() ^ localPart.hashCode();
388
}
389
390
/**
391
* <p><code>String</code> representation of this
392
* <code>QName</code>.</p>
393
*
394
* <p>The commonly accepted way of representing a <code>QName</code>
395
* as a <code>String</code> was
396
* <a href="http://jclark.com/xml/xmlns.htm">defined</a>
397
* by James Clark. Although this is not a <em>standard</em>
398
* specification, it is in common use, e.g. {@link
399
* javax.xml.transform.Transformer#setParameter(String name, Object value)}.
400
* This implementation represents a <code>QName</code> as:
401
* "{" + Namespace URI + "}" + local part. If the Namespace URI
402
* <code>.equals(XMLConstants.NULL_NS_URI)</code>, only the
403
* local part is returned. An appropriate use of this method is
404
* for debugging or logging for human consumption.</p>
405
*
406
* <p>Note the prefix value is <strong><em>NOT</em></strong>
407
* returned as part of the <code>String</code> representation.</p>
408
*
409
* <p>This method satisfies the general contract of {@link
410
* java.lang.Object#toString() Object.toString()}.</p>
411
*
412
* @return <code>String</code> representation of this <code>QName</code>
413
*/
414
public String toString() {
415
if (namespaceURI.equals(XMLConstants.NULL_NS_URI)) {
416
return localPart;
417
} else {
418
return "{" + namespaceURI + "}" + localPart;
419
}
420
}
421
422
/**
423
* <p><code>QName</code> derived from parsing the formatted
424
* <code>String</code>.</p>
425
*
426
* <p>If the <code>String</code> is <code>null</code> or does not conform to
427
* {@link #toString() QName.toString()} formatting, an
428
* <code>IllegalArgumentException</code> is thrown.</p>
429
*
430
* <p><em>The <code>String</code> <strong>MUST</strong> be in the
431
* form returned by {@link #toString() QName.toString()}.</em></p>
432
*
433
* <p>The commonly accepted way of representing a <code>QName</code>
434
* as a <code>String</code> was
435
* <a href="http://jclark.com/xml/xmlns.htm">defined</a>
436
* by James Clark. Although this is not a <em>standard</em>
437
* specification, it is in common use, e.g. {@link
438
* javax.xml.transform.Transformer#setParameter(String name, Object value)}.
439
* This implementation parses a <code>String</code> formatted
440
* as: "{" + Namespace URI + "}" + local part. If the Namespace
441
* URI <code>.equals(XMLConstants.NULL_NS_URI)</code>, only the
442
* local part should be provided.</p>
443
*
444
* <p>The prefix value <strong><em>CANNOT</em></strong> be
445
* represented in the <code>String</code> and will be set to
446
* {@link javax.xml.XMLConstants#DEFAULT_NS_PREFIX
447
* XMLConstants.DEFAULT_NS_PREFIX}.</p>
448
*
449
* <p>This method does not do full validation of the resulting
450
* <code>QName</code>.
451
* <p>The Namespace URI is not validated as a
452
* <a href="http://www.ietf.org/rfc/rfc2396.txt">URI reference</a>.
453
* The local part is not validated as a
454
* <a href="http://www.w3.org/TR/REC-xml-names/#NT-NCName">NCName</a>
455
* as specified in
456
* <a href="http://www.w3.org/TR/REC-xml-names/">Namespaces in XML</a>.</p>
457
*
458
* @param qNameAsString <code>String</code> representation
459
* of the <code>QName</code>
460
*
461
* @throws IllegalArgumentException When <code>qNameAsString</code> is
462
* <code>null</code> or malformed
463
*
464
* @return <code>QName</code> corresponding to the given <code>String</code>
465
* @see #toString() QName.toString()
466
*/
467
public static QName valueOf(String qNameAsString) {
468
469
// null is not valid
470
if (qNameAsString == null) {
471
throw new IllegalArgumentException(
472
"cannot create QName from \"null\" or \"\" String");
473
}
474
475
// "" local part is valid to preserve compatible behavior with QName 1.0
476
if (qNameAsString.length() == 0) {
477
return new QName(
478
XMLConstants.NULL_NS_URI,
479
qNameAsString,
480
XMLConstants.DEFAULT_NS_PREFIX);
481
}
482
483
// local part only?
484
if (qNameAsString.charAt(0) != '{') {
485
return new QName(
486
XMLConstants.NULL_NS_URI,
487
qNameAsString,
488
XMLConstants.DEFAULT_NS_PREFIX);
489
}
490
491
// Namespace URI improperly specified?
492
if (qNameAsString.startsWith("{" + XMLConstants.NULL_NS_URI + "}")) {
493
throw new IllegalArgumentException(
494
"Namespace URI .equals(XMLConstants.NULL_NS_URI), "
495
+ ".equals(\"" + XMLConstants.NULL_NS_URI + "\"), "
496
+ "only the local part, "
497
+ "\""
498
+ qNameAsString.substring(2 + XMLConstants.NULL_NS_URI.length())
499
+ "\", "
500
+ "should be provided.");
501
}
502
503
// Namespace URI and local part specified
504
int endOfNamespaceURI = qNameAsString.indexOf('}');
505
if (endOfNamespaceURI == -1) {
506
throw new IllegalArgumentException(
507
"cannot create QName from \""
508
+ qNameAsString
509
+ "\", missing closing \"}\"");
510
}
511
return new QName(
512
qNameAsString.substring(1, endOfNamespaceURI),
513
qNameAsString.substring(endOfNamespaceURI + 1),
514
XMLConstants.DEFAULT_NS_PREFIX);
515
}
516
}
517
518