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