1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package org.codehaus.xfire.xmlbeans.util;
35
36 import org.xml.sax.Attributes;
37 import org.xml.sax.Locator;
38 import org.xml.sax.SAXException;
39 import org.xml.sax.helpers.DefaultHandler;
40
41 import javax.xml.stream.XMLStreamException;
42 import javax.xml.stream.XMLStreamWriter;
43 import java.util.Stack;
44
45 /***
46 * This is a simple utility class that adapts SAX events into StAX
47 * {@link javax.xml.stream.XMLStreamWriter} events, bridging between
48 * the two parser technologies.
49 *
50 * This ContentHandler does not own the XMLStreamWriter. Therefore, it will
51 * not close or flush the writer at any point.
52 *
53 * @author Ryan.Shoemaker@Sun.COM
54 * @version 1.0
55 */
56 public class ContentHandlerToXMLStreamWriter extends DefaultHandler {
57
58
59 private final XMLStreamWriter staxWriter;
60
61
62 private final Stack prefixBindings;
63
64 private boolean writeStart;
65
66 public ContentHandlerToXMLStreamWriter(XMLStreamWriter staxCore, boolean writeStart) {
67 this.staxWriter = staxCore;
68 prefixBindings = new Stack();
69 this.writeStart = writeStart;
70 }
71
72
73
74
75
76
77 public void endDocument() throws SAXException {
78 try {
79
80 staxWriter.flush();
81 } catch (XMLStreamException e) {
82 throw new SAXException(e);
83 }
84 }
85
86
87
88
89
90
91 public void startDocument() throws SAXException {
92
93 }
94
95
96
97
98
99
100 public void characters(char[] ch, int start, int length)
101 throws SAXException {
102
103 try {
104 staxWriter.writeCharacters(ch, start, length);
105 } catch (XMLStreamException e) {
106 throw new SAXException(e);
107 }
108
109 }
110
111
112
113
114
115
116 public void ignorableWhitespace(char[] ch, int start, int length)
117 throws SAXException {
118
119 characters(ch,start,length);
120 }
121
122
123
124
125
126
127 public void endPrefixMapping(String prefix) throws SAXException
128 {
129
130
131
132
133 }
134
135
136
137
138
139
140 public void skippedEntity(String name) throws SAXException {
141 try {
142 staxWriter.writeEntityRef(name);
143 } catch (XMLStreamException e) {
144 throw new SAXException(e);
145 }
146 }
147
148
149
150
151
152
153 public void setDocumentLocator(Locator locator) {
154
155
156
157
158 }
159
160
161
162
163
164
165
166 public void processingInstruction(String target, String data)
167 throws SAXException {
168
169 try {
170 staxWriter.writeProcessingInstruction(target, data);
171 } catch (XMLStreamException e) {
172 throw new SAXException(e);
173 }
174
175 }
176
177
178
179
180
181
182
183 public void startPrefixMapping(String prefix, String uri)
184 throws SAXException {
185
186 if (prefix.equals("xml")) {
187 return;
188 }
189
190
191 if (prefix == null) {
192 prefix = "";
193 }
194
195 prefixBindings.add(prefix);
196 prefixBindings.add(uri);
197 }
198
199
200
201
202
203
204
205 public void endElement(String namespaceURI, String localName, String qName)
206 throws SAXException {
207
208 try {
209
210 staxWriter.writeEndElement();
211 } catch (XMLStreamException e) {
212 throw new SAXException(e);
213 }
214 }
215
216 public void startElement(String uri, String localName,
217 String qName, Attributes atts) throws SAXException
218 {
219
220 try
221 {
222 String prefix = getPrefix(qName);
223
224
225 if ( uri != null )
226 {
227 if ( prefix.equals("") )
228 {
229 String defNS = staxWriter.getNamespaceContext().getNamespaceURI("");
230 if ( !defNS.equals(uri) )
231 {
232 staxWriter.setDefaultNamespace(uri);
233 staxWriter.writeStartElement( uri, localName );
234 staxWriter.writeDefaultNamespace( uri );
235 }
236 else
237 {
238 staxWriter.writeStartElement( uri, localName );
239 }
240 }
241 else
242 {
243 staxWriter.setPrefix( prefix, uri );
244
245 staxWriter.writeStartElement(
246 prefix,
247 localName,
248 uri);
249 }
250 }
251 else
252 {
253 staxWriter.writeStartElement( localName );
254 }
255
256 String nsuri, nsprefix;
257 while (prefixBindings.size() != 0)
258 {
259 nsuri = (String) prefixBindings.pop();
260 nsprefix = (String) prefixBindings.pop();
261 if (nsprefix.length() != 0)
262 {
263
264
265
266 staxWriter.writeNamespace(nsprefix, nsuri);
267 }
268 }
269 staxWriter.flush();
270
271 }
272 catch (XMLStreamException e)
273 {
274 throw new RuntimeException(e);
275 }
276
277 }
278
279 /***
280 * Generate a StAX writeAttribute event for each attribute
281 *
282 * @param atts
283 * attributes from the SAX event
284 */
285 private void writeAttributes(Attributes atts) throws XMLStreamException
286 {
287 for (int i = 0; i < atts.getLength(); i++)
288 {
289 System.out.println("writing attribute " + atts.getQName(i));
290 staxWriter.writeAttribute(getPrefix(atts.getQName(i)), atts
291 .getURI(i), atts.getLocalName(i), atts.getValue(i));
292 }
293 }
294
295 /***
296 * Pull the prefix off of the specified QName.
297 *
298 * @param qName
299 * the QName
300 * @return the prefix or the empty string if it doesn't exist.
301 */
302 private String getPrefix(String qName)
303 {
304 int idx = qName.indexOf(':');
305 if (idx == -1)
306 {
307 return "";
308 }
309 else
310 {
311 return qName.substring(0, idx);
312 }
313 }
314
315 }