1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.castor.xmlctf.xmldiff.xml;
19
20 import java.util.HashMap;
21 import java.util.Iterator;
22 import java.util.Map;
23 import java.util.Stack;
24
25 import org.castor.xmlctf.xmldiff.xml.nodes.Attribute;
26 import org.castor.xmlctf.xmldiff.xml.nodes.Element;
27 import org.castor.xmlctf.xmldiff.xml.nodes.Namespace;
28 import org.castor.xmlctf.xmldiff.xml.nodes.ParentNode;
29 import org.castor.xmlctf.xmldiff.xml.nodes.ProcessingInstruction;
30 import org.castor.xmlctf.xmldiff.xml.nodes.Root;
31 import org.castor.xmlctf.xmldiff.xml.nodes.Text;
32 import org.xml.sax.Attributes;
33 import org.xml.sax.ContentHandler;
34 import org.xml.sax.Locator;
35 import org.xml.sax.SAXException;
36
37
38
39
40
41
42
43
44 public class XMLContentHandler implements ContentHandler {
45
46
47 private final Stack _nodeStack = new Stack();
48
49 private final Root _root = new Root();
50
51
52 private Locator _locator = null;
53
54 private ParentNode _currentNode = null;
55
56 private Map _prefixes = new HashMap();
57
58
59
60
61 public XMLContentHandler() {
62 _nodeStack.push(_root);
63 _currentNode = _root;
64 }
65
66
67
68
69
70
71
72
73
74 public void characters(final char[] chars, final int start, final int length) throws org.xml.sax.SAXException {
75 _currentNode.addChild(new Text(new String(chars, start, length)));
76 }
77
78
79
80
81
82 public void endDocument() throws org.xml.sax.SAXException {
83
84 }
85
86
87
88
89
90
91
92
93 public void endElement(final String uri, final String name, final String qName)
94 throws org.xml.sax.SAXException {
95 final String localName = name;
96
97 final int idx = qName.indexOf(':');
98 final String prefix = (idx >= 0) ? qName.substring(0, idx) : "";
99
100
101 String uriOfPrefix = _currentNode.getNamespaceURI(prefix);
102 String uriOfElement = _currentNode.getNamespaceURI();
103 if ((uriOfPrefix == null ^ uriOfElement == null)
104 || (uriOfPrefix != null && !uriOfPrefix.equals(uriOfElement))) {
105 throw new org.xml.sax.SAXException("In Element " + qName + ", URI of prefix " + uriOfPrefix +
106 " does not match URI of Element " + uriOfElement);
107 }
108
109 String cName = _currentNode.getLocalName();
110 if (!cName.equals(localName)) {
111 String err = "Element end tag mismatch: expecting </" + cName
112 + "> but recieved </" + localName + ">";
113 throw new SAXException(err);
114 }
115
116 _nodeStack.pop();
117 _currentNode = (ParentNode) _nodeStack.peek();
118 }
119
120
121
122
123
124
125 public void endPrefixMapping(final String prefix) throws SAXException {
126 _prefixes.remove(prefix);
127 }
128
129
130
131
132
133 public Root getRoot() {
134 return _root;
135 }
136
137
138
139
140
141
142
143
144
145 public void ignorableWhitespace(final char[] chars, final int start, final int length)
146 throws org.xml.sax.SAXException {
147
148 }
149
150
151
152
153
154
155
156
157 public void processingInstruction(final String target, final String data)
158 throws org.xml.sax.SAXException {
159 ProcessingInstruction pi = new ProcessingInstruction(target, data);
160 _currentNode.addChild(pi);
161 }
162
163
164
165
166
167
168 public void setDocumentLocator(final Locator locator) {
169 _locator = locator;
170 }
171
172
173
174
175
176 public void skippedEntity(final String name) {
177
178 }
179
180
181
182
183
184 public void startDocument() throws SAXException {
185
186 }
187
188
189
190
191
192
193
194
195
196
197 public void startElement(final String uri, final String name, final String qName, final Attributes atts) throws org.xml.sax.SAXException {
198 if (qName == null) {
199 throw new SAXException("No Element name given");
200 }
201
202 final String prefix;
203 final String localName;
204
205 int idx = qName.indexOf(':');
206 if (idx >= 0) {
207 prefix = qName.substring(0, idx);
208 localName = qName.substring(idx + 1);
209 } else {
210 prefix = "";
211 localName = qName;
212 }
213
214 Element element = new Element(null, localName);
215
216 if (_locator != null) {
217 element.setLocation(new Location(_locator));
218 }
219
220 _currentNode.addChild(element);
221
222
223 for (Iterator i = _prefixes.entrySet().iterator(); i.hasNext(); ) {
224 Map.Entry me = (Map.Entry) i.next();
225 element.addNamespace(new Namespace((String)me.getKey(), (String) me.getValue()));
226 }
227
228
229 if (atts != null && atts.getLength() > 0) {
230 for (int i = 0; i < atts.getLength(); i++) {
231 String attName = atts.getQName(i);
232 String ns = null;
233 idx = attName.indexOf(':');
234 if (idx > 0) {
235 ns = element.getNamespaceURI(attName.substring(0, idx));
236 attName = attName.substring(idx + 1);
237 }
238 element.addAttribute(new Attribute(ns, attName, atts.getValue(i)));
239 }
240 }
241
242
243 if (prefix != null && prefix.length() > 0) {
244 String namespace = element.getNamespaceURI(prefix);
245 element.setNamespace(namespace);
246 } else {
247 String namespace = element.getNamespaceURI("");
248 if (namespace != null) {
249 element.setNamespace(namespace);
250 }
251 }
252
253 _nodeStack.push(element);
254 _currentNode = element;
255 }
256
257
258
259
260
261
262
263 public void startPrefixMapping(final String prefix, final String uri) {
264 _prefixes.put(prefix, uri);
265 }
266
267 }