1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.qedeq.kernel.xml.handler.common;
16
17 import java.util.Stack;
18
19 import org.qedeq.base.io.SourceArea;
20 import org.qedeq.base.io.SourcePosition;
21 import org.qedeq.base.trace.Trace;
22 import org.qedeq.kernel.se.common.ModuleService;
23 import org.qedeq.kernel.se.common.SourceFileException;
24 import org.qedeq.kernel.se.common.SourceFileExceptionList;
25 import org.qedeq.kernel.xml.common.XmlSyntaxException;
26 import org.xml.sax.Attributes;
27 import org.xml.sax.SAXException;
28 import org.xml.sax.SAXParseException;
29
30
31
32
33
34
35
36
37
38
39
40
41
42 public class SaxDefaultHandler extends SimpleHandler {
43
44
45 private static final Class CLASS = SaxDefaultHandler.class;
46
47
48 private AbstractSimpleHandler currentHandler;
49
50
51 private Stack handlerStack = new Stack();
52
53
54 private AbstractSimpleHandler basisHandler;
55
56
57 private SourceFileExceptionList errorList;
58
59
60 private StringBuffer buffer = new StringBuffer(2000);
61
62
63 private int level;
64
65
66 private Stack levelStack = new Stack();
67
68
69 private String currentElementName;
70
71
72 private final ModuleService plugin;
73
74
75
76
77
78
79 public SaxDefaultHandler(final ModuleService plugin) {
80 super();
81 this.plugin = plugin;
82 }
83
84
85
86
87
88
89 public void setExceptionList(final SourceFileExceptionList errorList) {
90 this.errorList = errorList;
91 }
92
93
94
95
96
97
98
99
100
101 public final void setBasisDocumentHandler(final AbstractSimpleHandler handler) {
102 basisHandler = handler;
103 currentHandler = handler;
104 handlerStack.clear();
105 level = 0;
106 }
107
108
109
110
111 public final void startDocument() throws SAXException {
112 sendCharacters();
113 currentHandler = basisHandler;
114 handlerStack.clear();
115 level = 0;
116 currentElementName = null;
117 }
118
119
120
121
122 public final void endDocument() throws SAXException {
123 sendCharacters();
124 currentElementName = null;
125 }
126
127
128
129
130
131 public final void startElement(final String uri, final String localName, final String qName,
132 final Attributes amap) throws SAXException {
133 final String method = "startElement";
134 try {
135 Trace.param(CLASS, this, method, "currentHandler", currentHandler.getClass().getName());
136 Trace.param(CLASS, this, method, "localName", localName);
137 Trace.param(CLASS, this, method, "qName", qName);
138 if (handlerStack.empty() && level == 0) {
139 currentHandler.init();
140 }
141 level++;
142 Trace.param(CLASS, this, method, "level", level);
143 sendCharacters();
144 currentElementName = localName;
145 final SimpleAttributes attributes = new SimpleAttributes();
146 for (int i = 0; i < amap.getLength(); i++) {
147 attributes.add(amap.getQName(i), amap.getValue(i));
148 }
149 Trace.param(CLASS, this, method, "attributes", attributes);
150 currentHandler.startElement(qName, attributes);
151 } catch (XmlSyntaxException e) {
152 Trace.trace(CLASS, this, method, e);
153 addXmlSyntaxException(e);
154 } catch (RuntimeException e) {
155 Trace.trace(CLASS, this, method, e);
156 final XmlSyntaxException ex = XmlSyntaxException.createByRuntimeException(e);
157 addXmlSyntaxException(ex);
158 }
159 }
160
161
162
163
164
165 public final void endElement(final String uri, final String localName, final String qName)
166 throws SAXException {
167 sendCharacters();
168 final String method = "endElement";
169 try {
170 Trace.param(CLASS, this, method, "currentHandler", currentHandler.getClass().getName());
171 Trace.param(CLASS, this, method, "qName", qName);
172 currentHandler.endElement(qName);
173 } catch (XmlSyntaxException e) {
174 Trace.trace(CLASS, this, method, e);
175 addXmlSyntaxException(e);
176 } catch (RuntimeException e) {
177 Trace.trace(CLASS, this, method, e);
178 final XmlSyntaxException ex = XmlSyntaxException.createByRuntimeException(e);
179 addXmlSyntaxException(ex);
180 }
181 try {
182 currentElementName = null;
183 level--;
184 Trace.param(CLASS, this, method, "level", level);
185 if (level <= 0) {
186 restoreHandler(localName);
187 }
188 } catch (XmlSyntaxException e) {
189 Trace.trace(CLASS, this, method, e);
190 addXmlSyntaxException(e);
191 } catch (RuntimeException e) {
192 Trace.trace(CLASS, this, method, e);
193 final XmlSyntaxException ex = XmlSyntaxException.createByRuntimeException(e);
194 addXmlSyntaxException(ex);
195 }
196 }
197
198
199
200
201 public final void characters(final char[] ch, final int start, final int length) {
202 buffer.append(ch, start, length);
203 }
204
205
206
207
208
209 private void sendCharacters() {
210 try {
211 if (buffer.length() > 0) {
212 final String str = buffer.toString();
213 buffer.setLength(0);
214 if (str.trim().length() > 0) {
215 currentHandler.characters(currentElementName, str);
216 }
217 }
218 } catch (XmlSyntaxException e) {
219 Trace.trace(CLASS, this, "sendCharacters", e);
220 addXmlSyntaxException(e);
221 } catch (RuntimeException e) {
222 Trace.trace(CLASS, this, "sendCharacters", e);
223 final XmlSyntaxException ex = XmlSyntaxException.createByRuntimeException(e);
224 addXmlSyntaxException(ex);
225 }
226 }
227
228
229
230
231
232
233 private void addXmlSyntaxException(final XmlSyntaxException exception) {
234 if (errorList.size() < 20) {
235 errorList.add(new SourceFileException(plugin, exception, createSourceArea(), null));
236 }
237 }
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266 public final void changeHandler(final AbstractSimpleHandler newHandler,
267 final String elementName, final SimpleAttributes attributes)
268 throws XmlSyntaxException {
269 handlerStack.push(currentHandler);
270 levelStack.push(new Integer(level));
271 currentHandler = newHandler;
272 level = 0;
273 level++;
274 Trace.param(CLASS, this, "changeHandler", "level", level);
275 currentHandler.init();
276 currentHandler.startElement(elementName, attributes);
277 }
278
279
280
281
282
283
284
285
286 private final void restoreHandler(final String elementName) throws XmlSyntaxException {
287 while (level <= 0 && !handlerStack.empty()) {
288 currentHandler = (AbstractSimpleHandler) handlerStack.pop();
289 Trace.param(CLASS, this, "restoreHandler", "currentHandler", currentHandler);
290 level = ((Integer) levelStack.pop()).intValue();
291 currentHandler.endElement(elementName);
292 level--;
293 Trace.param(CLASS, this, "restoreHandler", "level", level);
294 }
295 if (handlerStack.empty()) {
296 Trace.trace(CLASS, this, "restoreHandler", "no handler to restore");
297 }
298 }
299
300
301
302
303
304
305 public final int getLevel() {
306 return level;
307 }
308
309
310
311
312
313
314
315 public final SAXParseException createSAXParseException(final Exception e) {
316 return new SAXParseException(null, getLocator(), e);
317 }
318
319
320
321
322
323
324
325 public final SAXParseException createSAXParseException(final String message) {
326 return new SAXParseException(message, getLocator());
327 }
328
329
330
331
332
333
334 public final SourceArea createSourceArea() {
335 if (getLocator() != null && getUrl() != null) {
336 return new SourceArea(getUrl(), new SourcePosition(getLocator().getLineNumber(), 1),
337 new SourcePosition(getLocator().getLineNumber(), getLocator().getColumnNumber()));
338 }
339 return new SourceArea(getUrl());
340 }
341
342
343
344
345
346
347 public ModuleService getPlugin() {
348 return plugin;
349 }
350
351 }