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
47 package org.exolab.castor.xml.util;
48
49 import java.util.Stack;
50
51 import org.exolab.castor.types.AnyNode;
52 import org.exolab.castor.xml.Namespaces;
53 import org.exolab.castor.xml.NamespacesStack;
54 import org.xml.sax.AttributeList;
55 import org.xml.sax.Attributes;
56 import org.xml.sax.ContentHandler;
57 import org.xml.sax.DocumentHandler;
58 import org.xml.sax.ErrorHandler;
59 import org.xml.sax.Locator;
60 import org.xml.sax.SAXException;
61 import org.xml.sax.SAXParseException;
62
63
64
65
66
67
68
69 public class SAX2ANY implements ContentHandler, DocumentHandler, ErrorHandler {
70
71
72
73 private final static String XMLNS_PREFIX = "xmlns";
74 private final static int XMLNS_PREFIX_LENGTH = XMLNS_PREFIX.length() + 1;
75
76
77
78
79 private AnyNode _startingNode;
80
81
82
83
84 private AnyNode _node;
85
86
87
88
89 private Stack _nodeStack = new Stack();
90
91
92
93
94 private Stack _namespaces = new Stack();
95
96
97
98
99
100
101
102 private boolean _processNamespace = true;
103
104
105
106
107 private boolean _character = false;
108
109
110
111
112 private NamespacesStack namespacesStack;
113
114 private boolean _wsPreserve = false;
115
116
117
118
119 public SAX2ANY() {
120 super();
121 init();
122 }
123
124
125
126
127
128
129
130 public SAX2ANY(NamespacesStack namespacesStack, boolean wsPreserve) {
131 this.namespacesStack = namespacesStack;
132 _wsPreserve = wsPreserve;
133 init();
134 }
135
136 private void init() {
137 if (this.namespacesStack == null)
138 this.namespacesStack = new NamespacesStack();
139 }
140
141
142
143
144
145 public void setDocumentLocator(final Locator locator) { }
146
147
148
149
150 public void startDocument() throws SAXException {
151 }
152
153 public void endDocument() throws SAXException {
154 }
155
156 public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
157 return;
158 }
159
160 public void processingInstruction(String target, String data) throws SAXException {
161 return;
162 }
163
164 public void skippedEntity(String name) throws SAXException {
165 return;
166 }
167
168
169
170 public void startPrefixMapping(String prefix, String uri) throws SAXException {
171 AnyNode temp = new AnyNode(AnyNode.NAMESPACE, null, prefix, uri, null);
172 _namespaces.push(temp);
173 if (_processNamespace) {
174 namespacesStack.addNewNamespaceScope();
175 _processNamespace = true;
176 }
177 namespacesStack.addNamespace(prefix, uri);
178 }
179
180 public void endPrefixMapping(String prefix) throws SAXException {
181 namespacesStack.removeNamespace(prefix);
182 }
183
184
185
186
187
188 public void startElement(String name, AttributeList atts)
189 throws SAXException {
190 _character = false;
191 String qName;
192 String value;
193 AnyNode tempNode = null;
194
195
196
197
198 namespacesStack.addNewNamespaceScope();
199 String prefix = "";
200 String namespaceURI = null;
201 int idx = name.indexOf(':');
202 if (idx >= 0) {
203 prefix = name.substring(0,idx);
204 }
205 namespaceURI = namespacesStack.getNamespaceURI(prefix);
206
207 for (int i=0; i<atts.getLength(); ++i) {
208 qName = atts.getName(i);
209 value = atts.getValue(i);
210 String nsPrefix = null;
211
212 if (qName.startsWith(XMLNS_PREFIX)) {
213
214
215 nsPrefix = (qName.equals(XMLNS_PREFIX))?null:qName.substring(XMLNS_PREFIX_LENGTH);
216 tempNode = new AnyNode(AnyNode.NAMESPACE, getLocalPart(qName), nsPrefix, value, null);
217 namespacesStack.addNamespace(nsPrefix, value);
218 _namespaces.push(tempNode);
219 if (prefix.equals(nsPrefix))
220 namespaceURI = value;
221 }
222 }
223
224
225 createNodeElement(namespaceURI, getLocalPart(name), name);
226 while (!_namespaces.empty()) {
227 tempNode = (AnyNode)_namespaces.pop();
228 _node.addNamespace(tempNode);
229 }
230
231
232 for (int i=0; i<atts.getLength(); ++i) {
233
234 qName = atts.getName(i);
235 value = atts.getValue(i);
236
237
238 if (!qName.startsWith(XMLNS_PREFIX)) {
239 tempNode = new AnyNode(AnyNode.ATTRIBUTE, getLocalPart(qName), null, null, value);
240 _node.addAttribute(tempNode);
241 }
242 }
243 tempNode = null;
244 }
245
246
247
248
249 public void startElement(String namespaceURI, String localName,
250 String qName, Attributes atts) throws SAXException {
251 AnyNode tempNode;
252
253
254 if (_processNamespace) {
255
256
257
258 namespacesStack.addNewNamespaceScope();
259 String prefix = "";
260 int idx = qName.indexOf(':');
261 if (idx >= 0) {
262 prefix = qName.substring(0,idx);
263 }
264 namespaceURI = namespacesStack.getNamespaceURI(prefix);
265
266 for (int i=0; i<atts.getLength(); ++i) {
267 String attrqName = atts.getQName(i);
268 String value = atts.getValue(i);
269 String nsPrefix = null;
270
271 if (attrqName.startsWith(XMLNS_PREFIX)) {
272
273 nsPrefix = (attrqName.equals(XMLNS_PREFIX))?null:attrqName.substring(XMLNS_PREFIX_LENGTH);
274 tempNode = new AnyNode(AnyNode.NAMESPACE, getLocalPart(attrqName), nsPrefix, value, null);
275 namespacesStack.addNamespace(nsPrefix, value);
276 _namespaces.push(tempNode);
277 if (prefix.equals(nsPrefix))
278 namespaceURI = value;
279 }
280 }
281
282 }
283
284
285 createNodeElement(namespaceURI, localName, qName);
286
287
288 for (int i=0; i<atts.getLength(); ++i) {
289
290 String uri = atts.getURI(i);
291 String attqName = atts.getQName(i);
292 String value = atts.getValue(i);
293 String prefix = null;
294
295
296 if (_processNamespace )
297 if(attqName.startsWith(XMLNS_PREFIX))
298 continue;
299
300
301 if ((attqName.length() != 0) && (attqName.indexOf(':') != -1 ))
302 prefix = attqName.substring(0,attqName.indexOf(':'));
303
304
305 if (_processNamespace ) {
306
307 if(prefix!=null)
308 uri = namespacesStack.getNamespaceURI(prefix);
309 }
310
311 tempNode = new AnyNode(AnyNode.ATTRIBUTE, getLocalPart(attqName), prefix, uri, value);
312 _node.addAttribute(tempNode);
313 }
314
315
316
317 while (!_namespaces.empty()) {
318 tempNode = (AnyNode)_namespaces.pop();
319 _node.addNamespace(tempNode);
320 }
321 tempNode = null;
322 }
323
324
325 public void endElement(String name) throws SAXException {
326 int idx = name.indexOf(':');
327 String prefix = (idx >= 0) ? name.substring(0,idx) : "";
328 String namespaceURI = namespacesStack.getNamespaceURI(prefix);
329 endElement(namespaceURI,getLocalPart(name), name);
330 namespacesStack.removeNamespaceScope();
331 }
332
333 public void endElement(String namespaceURI, String localName, String qName)
334 throws SAXException {
335 _character = false;
336 String name = null;
337
338
339 if (localName != null && localName.length() > 0) {
340 name = localName;
341 } else {
342 name = getLocalPart(qName);
343 }
344
345
346 if (_startingNode.getLocalName().equals(name) && _nodeStack.empty())
347 return;
348
349
350 _node = (AnyNode)_nodeStack.pop();
351
352
353
354 if (_nodeStack.empty()) {
355 _startingNode.addChild(_node);
356 _node = _startingNode;
357 } else {
358 AnyNode previousNode = (AnyNode) _nodeStack.peek();
359 previousNode.addChild(_node);
360
361 _node = previousNode;
362 }
363 }
364
365 public void characters(char[] ch, int start, int length) throws SAXException {
366
367 String temp = new String(ch, start, length);
368
369 if (isWhitespace(temp) && !_wsPreserve && !_character) return;
370 AnyNode tempNode = new AnyNode(AnyNode.TEXT, null, null, null, temp);
371 _node.addChild(tempNode);
372 _character = true;
373 }
374
375
376
377
378 public void warning(SAXParseException e) throws SAXException {
379 String err = "SAX2ANY warning\n" + "Line : " + e.getLineNumber() + '\n'
380 + "URI : " + e.getSystemId() + '\n' + e.getMessage();
381 throw new SAXException(err, e);
382 }
383
384 public void error(SAXParseException e) throws SAXException {
385 String err = "SAX2ANY Error \n" + "Line : " + e.getLineNumber() + '\n'
386 + "URI : " + e.getSystemId() + '\n' + e.getMessage();
387 throw new SAXException(err, e);
388 }
389
390 public void fatalError(SAXParseException e) throws SAXException {
391 String err = "SAX2ANY Fatal Error \n" + "Line : " + e.getLineNumber()
392 + '\n' + "URI : " + e.getSystemId() + '\n' + e.getMessage();
393 throw new SAXException(err, e);
394 }
395
396
397
398 public AnyNode getStartingNode() {
399 return _startingNode;
400 }
401
402
403
404
405
406
407
408
409
410 private boolean isWhitespace(String string) {
411 for (int i = 0; i < string.length(); i++) {
412 char ch = string.charAt(i);
413 switch (ch) {
414 case ' ':
415 case '\n':
416 case '\t':
417 case '\r':
418 break;
419 default:
420 return false;
421 }
422 }
423 return true;
424 }
425
426
427
428
429
430
431
432 private String getLocalPart(String ncName) {
433 int idx = ncName.indexOf(':');
434 if (idx >= 0) return ncName.substring(idx+1);
435 return ncName;
436 }
437
438 private void createNodeElement(String namespaceURI, String localName,
439 String qName) {
440
441 String prefix = null;
442
443 if (namespaceURI != null) {
444 prefix = namespacesStack.getNamespacePrefix(namespaceURI);
445 }
446 else if (qName != null) {
447 if ((qName.length() != 0) && (qName.indexOf(':') != -1 ))
448 prefix = qName.substring(0,qName.indexOf(':'));
449 }
450
451 String name = null;
452
453
454 if (localName != null && localName.length() > 0)
455 name = localName;
456 else
457 name = getLocalPart(qName);
458
459
460
461 if ( (_nodeStack.empty()) && (_startingNode == null)) {
462 _startingNode = new AnyNode(AnyNode.ELEMENT, name, prefix, namespaceURI, null);
463 _node = _startingNode;
464 } else {
465 _node = new AnyNode(AnyNode.ELEMENT, name, prefix, namespaceURI, null);
466
467 _nodeStack.push(_node);
468 }
469 }
470
471 }