1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package net.sf.webmancer.util.xml.sax;
22
23 import net.sf.webmancer.util.ContractChecker;
24 import net.sf.webmancer.util.xml.dom.DOMSemanticException;
25 import net.sf.webmancer.util.xml.dom.IDOMProcessor;
26
27 import org.w3c.dom.Document;
28 import org.w3c.dom.Element;
29 import org.w3c.dom.Node;
30 import org.w3c.dom.Text;
31 import org.xml.sax.Attributes;
32 import org.xml.sax.SAXException;
33
34
35
36
37 public class SAXDOMHandler extends DefaultHandler {
38 private IDOMProcessor processor;
39
40 private Document document;
41
42 private Node current;
43
44
45
46
47 public SAXDOMHandler(final IDOMProcessor processor) {
48 super();
49 ContractChecker.mustNotBeNull(processor, "processor");
50 ContractChecker.mustNotBeNull(processor.getDOMImplementation(), "processor.getDOMImplementation()");
51 this.processor = processor;
52 this.document = null;
53 this.current = null;
54 }
55
56
57
58
59 @Override
60 @SuppressWarnings("unused")
61 public void characters(final char[] ch, final int start, final int length) throws SAXException {
62 assert this.processor != null;
63 ContractChecker
64 .checkState(this.document != null && this.current != null, "Element expected but text was found");
65 Text text = createText(ch, start, length);
66 this.current.appendChild(text);
67 text.setUserData("locator", this.locator, null);
68 }
69
70
71
72
73
74 @Override
75 @SuppressWarnings("unused")
76 public void startElement(final String uri, final String localName, final String qName, final Attributes atts) throws SAXException {
77 assert this.processor != null;
78 if (this.document == null) {
79 assert this.current == null;
80 this.document = this.processor.getDOMImplementation().createDocument(uri, qName, null);
81 this.current = this.document.getDocumentElement();
82 } else {
83 assert this.current != null;
84 Element element = createElement(uri, localName, qName);
85 assert element != null;
86 this.current.appendChild(element);
87 this.current = element;
88 }
89 assert this.current instanceof Element;
90 setElementAttributes((Element) this.current, atts);
91 this.current.setUserData("locator", this.locator, null);
92 }
93
94
95
96
97
98 @Override
99 @SuppressWarnings("unused")
100 public void endElement(final String uri, final String localName, final String qName) throws SAXException {
101 assert this.processor != null;
102 ContractChecker.checkState(this.document != null && this.current != this.document, "Unexpected end of element");
103 assert this.current != null;
104 this.current = this.current.getParentNode();
105 if (this.current == this.document) {
106 try {
107 this.processor.process(this.document);
108 } catch (DOMSemanticException e) {
109 throw new SAXSemanticException("", null, e);
110 } finally {
111 this.document = null;
112 this.current = null;
113 }
114 }
115 }
116
117
118
119
120
121
122
123 protected Element createElement(final String uri, final String localName, final String qName) {
124 return this.document.createElementNS(uri, qName);
125 }
126
127
128
129
130
131 protected void setElementAttributes(final Element element, final Attributes atts) {
132 for (int i = 0; i < atts.getLength(); i++) {
133 element.setAttributeNS(atts.getURI(i), atts.getQName(i), atts.getValue(i));
134 }
135 }
136
137
138
139
140
141
142
143 protected Text createText(final char[] ch, final int start, final int length) {
144 return this.document.createTextNode(new String(ch, start, length));
145 }
146 }