src/share/jaxws_classes/com/sun/xml/internal/fastinfoset/tools/SAXEventSerializer.java

changeset 286
f50545b5e2f1
child 384
8f2986ff0235
equal deleted inserted replaced
284:88b85470e72c 286:f50545b5e2f1
1 /*
2 * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 *
25 * THIS FILE WAS MODIFIED BY SUN MICROSYSTEMS, INC.
26 */
27
28 package com.sun.xml.internal.fastinfoset.tools;
29
30 import java.io.IOException;
31 import java.io.OutputStream;
32 import java.io.OutputStreamWriter;
33 import java.io.Writer;
34 import java.util.ArrayList;
35 import java.util.List;
36 import java.util.Stack;
37
38 import org.xml.sax.Attributes;
39 import org.xml.sax.SAXException;
40 import org.xml.sax.ext.LexicalHandler;
41 import org.xml.sax.helpers.DefaultHandler;
42 import com.sun.xml.internal.fastinfoset.CommonResourceBundle;
43
44 public class SAXEventSerializer extends DefaultHandler
45 implements LexicalHandler {
46
47 private Writer _writer;
48 private boolean _charactersAreCDATA;
49 private StringBuffer _characters;
50
51 private Stack _namespaceStack = new Stack();
52 protected List _namespaceAttributes;
53
54 public SAXEventSerializer(OutputStream s) throws IOException {
55 _writer = new OutputStreamWriter(s);
56 _charactersAreCDATA = false;
57 }
58
59 // -- ContentHandler interface ---------------------------------------
60
61 public void startDocument() throws SAXException {
62 try {
63 _writer.write("<sax xmlns=\"http://www.sun.com/xml/sax-events\">\n");
64 _writer.write("<startDocument/>\n");
65 _writer.flush();
66 }
67 catch (IOException e) {
68 throw new SAXException(e);
69 }
70 }
71
72 public void endDocument() throws SAXException {
73 try {
74 _writer.write("<endDocument/>\n");
75 _writer.write("</sax>");
76 _writer.flush();
77 _writer.close();
78 }
79 catch (IOException e) {
80 throw new SAXException(e);
81 }
82 }
83
84
85 public void startPrefixMapping(String prefix, String uri)
86 throws SAXException
87 {
88 if (_namespaceAttributes == null) {
89 _namespaceAttributes = new ArrayList();
90 }
91
92 String qName = (prefix.length() == 0) ? "xmlns" : "xmlns" + prefix;
93 AttributeValueHolder attribute = new AttributeValueHolder(
94 qName,
95 prefix,
96 uri,
97 null,
98 null);
99 _namespaceAttributes.add(attribute);
100 }
101
102 public void endPrefixMapping(String prefix)
103 throws SAXException
104 {
105 /*
106 try {
107 outputCharacters();
108
109 _writer.write("<endPrefixMapping prefix=\"" +
110 prefix + "\"/>\n");
111 _writer.flush();
112 }
113 catch (IOException e) {
114 throw new SAXException(e);
115 }
116 */
117 }
118
119 public void startElement(String uri, String localName,
120 String qName, Attributes attributes)
121 throws SAXException
122 {
123 try {
124 outputCharacters();
125
126 if (_namespaceAttributes != null) {
127
128 AttributeValueHolder[] attrsHolder = new AttributeValueHolder[0];
129 attrsHolder = (AttributeValueHolder[])_namespaceAttributes.toArray(attrsHolder);
130
131 // Sort attributes
132 quicksort(attrsHolder, 0, attrsHolder.length - 1);
133
134 for (int i = 0; i < attrsHolder.length; i++) {
135 _writer.write("<startPrefixMapping prefix=\"" +
136 attrsHolder[i].localName + "\" uri=\"" + attrsHolder[i].uri + "\"/>\n");
137 _writer.flush();
138 }
139
140 _namespaceStack.push(attrsHolder);
141 _namespaceAttributes = null;
142 } else {
143 _namespaceStack.push(null);
144 }
145
146 AttributeValueHolder[] attrsHolder =
147 new AttributeValueHolder[attributes.getLength()];
148 for (int i = 0; i < attributes.getLength(); i++) {
149 attrsHolder[i] = new AttributeValueHolder(
150 attributes.getQName(i),
151 attributes.getLocalName(i),
152 attributes.getURI(i),
153 attributes.getType(i),
154 attributes.getValue(i));
155 }
156
157 // Sort attributes
158 quicksort(attrsHolder, 0, attrsHolder.length - 1);
159
160 int attributeCount = 0;
161 for (int i = 0; i < attrsHolder.length; i++) {
162 if (attrsHolder[i].uri.equals("http://www.w3.org/2000/xmlns/")) {
163 // Ignore XMLNS attributes
164 continue;
165 }
166 attributeCount++;
167 }
168
169 if (attributeCount == 0) {
170 _writer.write("<startElement uri=\"" + uri
171 + "\" localName=\"" + localName + "\" qName=\""
172 + qName + "\"/>\n");
173 return;
174 }
175
176 _writer.write("<startElement uri=\"" + uri
177 + "\" localName=\"" + localName + "\" qName=\""
178 + qName + "\">\n");
179
180 // Serialize attributes as children
181 for (int i = 0; i < attrsHolder.length; i++) {
182 if (attrsHolder[i].uri.equals("http://www.w3.org/2000/xmlns/")) {
183 // Ignore XMLNS attributes
184 continue;
185 }
186 _writer.write(
187 " <attribute qName=\"" + attrsHolder[i].qName +
188 "\" localName=\"" + attrsHolder[i].localName +
189 "\" uri=\"" + attrsHolder[i].uri +
190 // "\" type=\"" + attrsHolder[i].type +
191 "\" value=\"" + attrsHolder[i].value +
192 "\"/>\n");
193 }
194
195 _writer.write("</startElement>\n");
196 _writer.flush();
197 }
198 catch (IOException e) {
199 throw new SAXException(e);
200 }
201 }
202
203 public void endElement(String uri, String localName, String qName)
204 throws SAXException
205 {
206 try {
207 outputCharacters();
208
209 _writer.write("<endElement uri=\"" + uri
210 + "\" localName=\"" + localName + "\" qName=\""
211 + qName + "\"/>\n");
212 _writer.flush();
213
214 // Write out the end prefix here rather than waiting
215 // for the explicit events
216 AttributeValueHolder[] attrsHolder = (AttributeValueHolder[])_namespaceStack.pop();
217 if (attrsHolder != null) {
218 for (int i = 0; i < attrsHolder.length; i++) {
219 _writer.write("<endPrefixMapping prefix=\"" +
220 attrsHolder[i].localName + "\"/>\n");
221 _writer.flush();
222 }
223 }
224
225 }
226 catch (IOException e) {
227 throw new SAXException(e);
228 }
229 }
230
231 public void characters(char[] ch, int start, int length)
232 throws SAXException
233 {
234 if (length == 0) {
235 return;
236 }
237
238 if (_characters == null) {
239 _characters = new StringBuffer();
240 }
241
242 // Coalesce multiple character events
243 _characters.append(ch, start, length);
244
245 /*
246 try {
247 _writer.write("<characters>" +
248 (_charactersAreCDATA ? "<![CDATA[" : "") +
249 new String(ch, start, length) +
250 (_charactersAreCDATA ? "]]>" : "") +
251 "</characters>\n");
252 _writer.flush();
253 }
254 catch (IOException e) {
255 throw new SAXException(e);
256 }
257 */
258 }
259
260 private void outputCharacters() throws SAXException {
261 if (_characters == null) {
262 return;
263 }
264
265 try {
266 _writer.write("<characters>" +
267 (_charactersAreCDATA ? "<![CDATA[" : "") +
268 _characters +
269 (_charactersAreCDATA ? "]]>" : "") +
270 "</characters>\n");
271 _writer.flush();
272
273 _characters = null;
274 } catch (IOException e) {
275 throw new SAXException(e);
276 }
277 }
278
279 public void ignorableWhitespace(char[] ch, int start, int length)
280 throws SAXException
281 {
282 // Report ignorable ws as characters (assumes validation off)
283 characters(ch, start, length);
284 }
285
286 public void processingInstruction(String target, String data)
287 throws SAXException
288 {
289 try {
290 outputCharacters();
291
292 _writer.write("<processingInstruction target=\"" + target
293 + "\" data=\"" + data + "\"/>\n");
294 _writer.flush();
295 }
296 catch (IOException e) {
297 throw new SAXException(e);
298 }
299 }
300
301 // -- LexicalHandler interface ---------------------------------------
302
303 public void startDTD(String name, String publicId, String systemId)
304 throws SAXException {
305 // Not implemented
306 }
307
308 public void endDTD()
309 throws SAXException {
310 // Not implemented
311 }
312
313 public void startEntity(String name)
314 throws SAXException {
315 // Not implemented
316 }
317
318 public void endEntity(String name)
319 throws SAXException {
320 // Not implemented
321 }
322
323 public void startCDATA()
324 throws SAXException {
325 _charactersAreCDATA = true;
326 }
327
328 public void endCDATA()
329 throws SAXException {
330 _charactersAreCDATA = false;
331 }
332
333 public void comment(char[] ch, int start, int length)
334 throws SAXException
335 {
336 try {
337 outputCharacters();
338
339 _writer.write("<comment>" +
340 new String(ch, start, length) +
341 "</comment>\n");
342 _writer.flush();
343 }
344 catch (IOException e) {
345 throw new SAXException(e);
346 }
347 }
348
349 // -- Utility methods ------------------------------------------------
350
351 private void quicksort(AttributeValueHolder[] attrs, int p, int r) {
352 while (p < r) {
353 final int q = partition(attrs, p, r);
354 quicksort(attrs, p, q);
355 p = q + 1;
356 }
357 }
358
359 private int partition(AttributeValueHolder[] attrs, int p, int r) {
360 AttributeValueHolder x = attrs[(p + r) >>> 1];
361 int i = p - 1;
362 int j = r + 1;
363 while (true) {
364 while (x.compareTo(attrs[--j]) < 0);
365 while (x.compareTo(attrs[++i]) > 0);
366 if (i < j) {
367 final AttributeValueHolder t = attrs[i];
368 attrs[i] = attrs[j];
369 attrs[j] = t;
370 }
371 else {
372 return j;
373 }
374 }
375 }
376
377 public static class AttributeValueHolder implements Comparable {
378 public final String qName;
379 public final String localName;
380 public final String uri;
381 public final String type;
382 public final String value;
383
384 public AttributeValueHolder(String qName,
385 String localName,
386 String uri,
387 String type,
388 String value)
389 {
390 this.qName = qName;
391 this.localName = localName;
392 this.uri = uri;
393 this.type = type;
394 this.value = value;
395 }
396
397 public int compareTo(Object o) {
398 try {
399 return qName.compareTo(((AttributeValueHolder) o).qName);
400 }
401 catch (Exception e) {
402 throw new RuntimeException(CommonResourceBundle.getInstance().getString("message.AttributeValueHolderExpected"));
403 }
404 }
405 }
406
407 }

mercurial