1 package org.exolab.castor.xml;
2
3 import java.util.List;
4 import java.util.Stack;
5
6 import javax.xml.namespace.QName;
7 import javax.xml.stream.Location;
8 import javax.xml.stream.XMLEventReader;
9 import javax.xml.stream.XMLStreamConstants;
10 import javax.xml.stream.XMLStreamReader;
11
12 import org.apache.commons.logging.Log;
13 import org.apache.commons.logging.LogFactory;
14 import org.xml.sax.Attributes;
15 import org.xml.sax.ContentHandler;
16 import org.xml.sax.ErrorHandler;
17 import org.xml.sax.Locator;
18 import org.xml.sax.SAXException;
19
20
21
22
23
24
25
26
27
28
29 public abstract class BaseSax2EventFromStaxProducer implements
30 SAX2EventAndErrorProducer {
31
32
33
34
35 private static final Log LOG = LogFactory
36 .getLog(BaseSax2EventFromStaxProducer.class);
37
38
39
40
41 private Stack<List<String>> prefixes = new Stack<List<String>>();
42
43
44
45
46
47 private ContentHandler contentHandler;
48
49
50
51
52 private ErrorHandler errorHandler;
53
54 public static SAX2EventAndErrorProducer createSax2EventFromStax(
55 XMLStreamReader streamReader) {
56 return new Sax2EventFromStaxStreamProducer(streamReader);
57 }
58
59 public static SAX2EventAndErrorProducer createSax2EventFromStax(
60 XMLEventReader eventReader) {
61 return new Sax2EventFromStaxEventProducer(eventReader);
62 }
63
64 public void setContentHandler(ContentHandler contentHandler) {
65 this.contentHandler = contentHandler;
66 }
67
68 public void setErrorHandler(ErrorHandler errorHandler) {
69 this.errorHandler = errorHandler;
70 }
71
72 public Stack<List<String>> getPrefixes() {
73 return prefixes;
74 }
75
76 public ContentHandler getContentHandler() {
77 return contentHandler;
78 }
79
80 public ErrorHandler getErrorHandler() {
81 return errorHandler;
82 }
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99 int handleEventType(int eventType, int depth) throws SAXException {
100 switch (eventType) {
101 case XMLStreamConstants.START_ELEMENT:
102 handleStartElement();
103 return ++depth;
104 case XMLStreamConstants.END_ELEMENT:
105 handleEndElement();
106 return --depth;
107 case XMLStreamConstants.START_DOCUMENT:
108 handleStartDocument();
109 return ++depth;
110 case XMLStreamConstants.END_DOCUMENT:
111 handleEndDocument();
112 return --depth;
113 case XMLStreamConstants.CHARACTERS:
114 handleCharacters();
115 return depth;
116 case XMLStreamConstants.SPACE:
117 handleSpace();
118 return depth;
119 default:
120 return depth;
121 }
122 }
123
124
125
126
127
128
129
130 void handleStartDocument() throws SAXException {
131 LOG.info("< handleStartDocument >");
132
133 handleDocumentLocator();
134
135 contentHandler.startDocument();
136 }
137
138
139
140
141
142
143
144
145
146 void handleEndDocument() throws SAXException {
147 LOG.info("< handleEndDocument >");
148 contentHandler.endDocument();
149
150 }
151
152
153
154
155
156
157
158
159
160
161 void handleStartElement() throws SAXException {
162 LOG.info("< handleStartElement >");
163
164 QName qName = getQName();
165 String localName = qName.getLocalPart();
166 String uri = qName.getNamespaceURI();
167 String prefix = qName.getPrefix();
168 String qNameString = getQName(prefix, localName);
169
170 Attributes atts = getAttributes();
171
172 doStartPrefixMapping();
173
174 contentHandler.startElement(uri, localName, qNameString, atts);
175
176 }
177
178
179
180
181
182
183
184
185
186
187 void handleEndElement() throws SAXException {
188 LOG.info("< handleEndElement >");
189
190 QName qName = getQName();
191 String localName = qName.getLocalPart();
192 String uri = qName.getNamespaceURI();
193 String prefix = qName.getPrefix();
194 String qNameString = getQName(prefix, localName);
195
196 contentHandler.endElement(uri, localName, qNameString);
197
198 doEndPrefixMapping();
199 }
200
201
202
203
204
205
206 void handleSpace() throws SAXException {
207
208 }
209
210
211
212
213
214
215
216
217
218
219
220
221
222 void handleCharacters() throws SAXException {
223 LOG.info("< handleCharacters >");
224 char[] chars;
225 chars = getCharacters();
226
227 if (isIgnorableWhitespace(chars, 0, chars.length))
228 contentHandler.ignorableWhitespace(chars, 0, chars.length);
229 else
230 contentHandler.characters(chars, 0, chars.length);
231
232 }
233
234
235
236
237
238
239
240 String getQName(String prefix, String localPart) {
241 return getNonEmpty(prefix).length() >= 1 ? prefix + ":" + localPart
242 : localPart;
243 }
244
245
246
247
248
249
250
251
252
253
254
255 boolean isIgnorableWhitespace(char[] chars, int start, int length) {
256 StringBuffer buffer = new StringBuffer();
257 buffer.append(chars, start, length);
258 String string = buffer.toString();
259 if (string.trim().length() == 0)
260 return true;
261 return false;
262 }
263
264
265
266
267
268
269
270
271
272
273 String getNonEmpty(String string) {
274 return string == null ? "" : string;
275 }
276
277
278
279
280 abstract Location getLocation();
281
282
283
284
285 abstract char[] getCharacters();
286
287
288
289
290
291
292
293 abstract void doStartPrefixMapping() throws SAXException;
294
295
296
297
298
299 abstract void doEndPrefixMapping() throws SAXException;
300
301
302
303
304 abstract Attributes getAttributes();
305
306
307
308
309 abstract QName getQName();
310
311
312
313
314
315 private void handleDocumentLocator() {
316 Locator locator = getSAXLocator(getLocation());
317 contentHandler.setDocumentLocator(locator);
318 }
319
320
321
322
323
324
325
326
327 protected Locator getSAXLocator(Location location) {
328 return new Locator() {
329 public String getSystemId() {
330 return getLocation().getSystemId();
331 }
332
333 public String getPublicId() {
334 return getLocation().getPublicId();
335 }
336
337 public int getLineNumber() {
338 return getLocation().getLineNumber();
339 }
340
341 public int getColumnNumber() {
342 return getLocation().getColumnNumber();
343 }
344 };
345 }
346 }