1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 package org.exolab.castor.xml;
47
48 import java.util.ArrayList;
49 import java.util.Enumeration;
50 import java.util.HashMap;
51 import java.util.Iterator;
52 import java.util.List;
53 import java.util.Map;
54 import org.castor.core.util.Assert;
55 import org.xml.sax.ContentHandler;
56 import org.xml.sax.SAXException;
57 import org.xml.sax.helpers.AttributeListImpl;
58
59
60
61
62
63
64
65
66 public final class Namespaces {
67
68
69
70
71 public static final String XML_NAMESPACE_PREFIX = "xml";
72
73
74
75
76 public static final String XML_NAMESPACE = "http://www.w3.org/XML/1998/namespace";
77
78
79
80
81 private static final String CDATA = "CDATA";
82
83
84
85
86 private static final String XMLNS = "xmlns";
87
88
89
90
91 private final List<Namespace> namespaces = new ArrayList<Namespace>();
92
93
94
95
96 private final Map<String, Namespace> namespaceMap = new HashMap<String, Namespace>();
97
98 public Namespaces() {
99 super();
100 namespaceMap.put(XML_NAMESPACE_PREFIX, new Namespace(XML_NAMESPACE_PREFIX, XML_NAMESPACE));
101 }
102
103
104
105
106
107
108
109
110
111
112
113 public synchronized void addNamespace(String prefix, String uri) {
114
115
116 Assert.notNull(uri, "Namespace URI must not be null");
117
118
119 if (prefix == null)
120 prefix = "";
121
122
123 if (XML_NAMESPACE_PREFIX.equalsIgnoreCase(prefix)) {
124 if (!XML_NAMESPACE.equals(uri)) {
125 String err = "The prefix 'xml' is reserved (XML 1.0 Specification) " + "and cannot be declared.";
126 throw new IllegalArgumentException(err);
127 }
128
129
130 return;
131 }
132
133 else if (XML_NAMESPACE.equals(uri)) {
134 String err = "The namespace '" + XML_NAMESPACE;
135 err += "' is reserved (XML 1.0 Specification) and cannot be declared.";
136 throw new IllegalArgumentException(err);
137 }
138
139
140 Namespace namespace;
141 if (namespaceMap.containsKey(prefix)) {
142 namespaceMap.get(prefix).setUri(uri);
143 } else {
144 namespace = new Namespace(prefix, uri);
145 namespaces.add(namespace);
146 namespaceMap.put(prefix, namespace);
147 }
148 }
149
150
151
152
153
154
155 public Enumeration<String> getLocalNamespaces() {
156 return new NamespaceEnumerator(namespaces.iterator());
157 }
158
159
160
161
162
163
164
165
166
167 public String getNamespaceURI(String prefix) {
168
169 if (prefix == null)
170 prefix = "";
171
172
173
174
175
176
177 Namespace namespace = namespaceMap.get(prefix);
178
179 if (namespace != null) {
180 return namespace.getUri();
181 }
182
183 return null;
184 }
185
186
187
188
189
190
191
192
193
194
195
196
197
198 public String getNamespacePrefix(String nsURI) {
199
200
201 Assert.notNull(nsURI, "Namespace URI must not be null.");
202
203 for (Namespace namespace : namespaces) {
204
205 if (nsURI.equals(namespace.getUri())) {
206 return namespace.getPrefix();
207 }
208 }
209
210
211 if (XML_NAMESPACE.equals(nsURI)) {
212 return XML_NAMESPACE_PREFIX;
213 }
214
215 return null;
216
217 }
218
219
220
221
222
223
224 public Enumeration<String> getLocalNamespacePrefixes() {
225 return new NamespaceEnumerator(namespaces.iterator(), NamespaceEnumerator.PREFIX);
226 }
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241 public String[] getNamespacePrefixes(String nsURI) {
242
243
244 Assert.notNull(nsURI, "Namespace URI must not be null.");
245
246 List<String> prefixes = new ArrayList<String>();
247 for (Namespace namespace : namespaces) {
248 if (namespace.getUri().equals(nsURI)) {
249 prefixes.add(namespace.getPrefix());
250 }
251 }
252
253 return prefixes.toArray(new String[0]);
254 }
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269 public String getNonDefaultNamespacePrefix(String nsURI) {
270 Assert.notNull(nsURI, "Namespace URI must not be null.");
271 for (Namespace namespace : namespaces) {
272 if (nsURI.equals(namespace.getUri()) && namespace.getPrefix().length() > 0) {
273 return namespace.getPrefix();
274 }
275 }
276
277
278 if (XML_NAMESPACE.equals(nsURI)) {
279 return XML_NAMESPACE_PREFIX;
280 }
281
282 return null;
283
284 }
285
286
287
288
289
290
291
292
293
294
295 public synchronized boolean removeNamespace(String prefix) {
296 if (prefix == null) {
297 return false;
298 }
299
300 if (namespaceMap.containsKey(prefix)) {
301 Namespace namespace = namespaceMap.get(prefix);
302 namespaceMap.remove(prefix);
303 namespaces.remove(namespace);
304
305 return true;
306 }
307
308 return false;
309 }
310
311
312
313
314
315
316
317
318 public void sendEndEvents(ContentHandler handler) throws SAXException {
319 for (Namespace namespace : namespaces) {
320 handler.endPrefixMapping(namespace.getPrefix());
321 }
322 }
323
324
325
326
327
328
329
330
331 public void sendStartEvents(ContentHandler handler) throws SAXException {
332 for (Namespace namespace : namespaces) {
333 handler.startPrefixMapping(namespace.getPrefix(), namespace.getUri());
334 }
335 }
336
337
338
339
340
341
342
343 @SuppressWarnings("deprecation")
344 public void declareAsAttributes(AttributeListImpl atts) {
345
346 String attName = null;
347 for (Namespace ns : namespaces) {
348 if (ns.prefix != null) {
349 int len = ns.prefix.length();
350 if (len > 0) {
351 StringBuffer buf = new StringBuffer(6 + len);
352 buf.append(XMLNS);
353 buf.append(':');
354 buf.append(ns.prefix);
355 attName = buf.toString();
356 atts.addAttribute(attName, CDATA, ns.uri);
357 }
358
359 else {
360 atts.addAttribute(XMLNS, CDATA, ns.uri);
361 }
362 }
363 else {
364 atts.addAttribute(XMLNS, CDATA, ns.uri);
365 }
366 }
367 }
368
369
370
371
372 class Namespace {
373
374
375
376
377 private String uri;
378
379
380
381
382 private String prefix;
383
384
385
386
387
388
389 Namespace() {
390 super();
391 }
392
393 Namespace(String prefix, String uri) {
394 this.prefix = prefix;
395 this.uri = uri;
396 }
397
398
399
400
401
402
403 public String getPrefix() {
404 return prefix;
405 }
406
407
408
409
410
411
412
413 public void setPrefix(String prefix) {
414 this.prefix = prefix;
415 }
416
417
418
419
420
421
422 public String getUri() {
423 return uri;
424 }
425
426
427
428
429
430
431
432 public void setUri(String uri) {
433 this.uri = uri;
434 }
435
436
437
438
439 @Override
440 public boolean equals(Object object) {
441 if (this == object) {
442 return true;
443 }
444 if (object == null || getClass() != object.getClass()) {
445 return false;
446 }
447
448 Namespace namespace = (Namespace) object;
449
450 if (prefix != null ? !prefix.equals(namespace.prefix) : namespace.prefix != null)
451 return false;
452 if (uri != null ? !uri.equals(namespace.uri) : namespace.uri != null)
453 return false;
454
455 return true;
456 }
457
458
459
460
461 @Override
462 public int hashCode() {
463 int result = prefix != null ? prefix.hashCode() : 0;
464 result = 31 * result + (uri != null ? uri.hashCode() : 0);
465 return result;
466 }
467 }
468
469
470
471
472 static class NamespaceEnumerator implements java.util.Enumeration<String> {
473 public static final int URI = 0;
474 public static final int PREFIX = 1;
475
476 private int _returnType = URI;
477
478 private Iterator<Namespace> namespaceIterator;
479
480 NamespaceEnumerator(Iterator<Namespace> namespaceIterator) {
481 this.namespaceIterator = namespaceIterator;
482 }
483
484 NamespaceEnumerator(Iterator<Namespace> namespaceIterator, int returnType) {
485 this.namespaceIterator = namespaceIterator;
486 _returnType = returnType;
487 }
488
489 public boolean hasMoreElements() {
490 return namespaceIterator.hasNext();
491 }
492
493 public String nextElement() {
494
495 String result;
496 Namespace ns = namespaceIterator.next();
497
498 if (_returnType == URI) {
499 result = ns.getUri();
500 } else {
501 result = ns.getPrefix();
502 }
503
504 return result;
505 }
506
507 }
508
509 }