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