src/share/jaxws_classes/com/sun/xml/internal/fastinfoset/sax/SAXDocumentSerializer.java

changeset 0
373ffda63c9a
equal deleted inserted replaced
-1:000000000000 0:373ffda63c9a
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.sax;
29
30 import com.sun.xml.internal.fastinfoset.Encoder;
31 import com.sun.xml.internal.fastinfoset.EncodingConstants;
32 import com.sun.xml.internal.fastinfoset.QualifiedName;
33 import com.sun.xml.internal.org.jvnet.fastinfoset.sax.FastInfosetWriter;
34 import com.sun.xml.internal.fastinfoset.util.LocalNameQualifiedNamesMap;
35 import java.io.IOException;
36 import com.sun.xml.internal.org.jvnet.fastinfoset.EncodingAlgorithmIndexes;
37 import com.sun.xml.internal.org.jvnet.fastinfoset.FastInfosetException;
38 import com.sun.xml.internal.org.jvnet.fastinfoset.RestrictedAlphabet;
39 import com.sun.xml.internal.org.jvnet.fastinfoset.sax.EncodingAlgorithmAttributes;
40 import org.xml.sax.Attributes;
41 import org.xml.sax.SAXException;
42 import com.sun.xml.internal.fastinfoset.CommonResourceBundle;
43
44 /**
45 * The Fast Infoset SAX serializer.
46 * <p>
47 * Instantiate this serializer to serialize a fast infoset document in accordance
48 * with the SAX API.
49 * <p>
50 * This utilizes the SAX API in a reverse manner to that of parsing. It is the
51 * responsibility of the client to call the appropriate event methods on the
52 * SAX handlers, and to ensure that such a sequence of methods calls results
53 * in the production well-formed fast infoset documents. The
54 * SAXDocumentSerializer performs no well-formed checks.
55 *
56 * <p>
57 * More than one fast infoset document may be encoded to the
58 * {@link java.io.OutputStream}.
59 */
60 public class SAXDocumentSerializer extends Encoder implements FastInfosetWriter {
61 protected boolean _elementHasNamespaces = false;
62
63 protected boolean _charactersAsCDATA = false;
64
65 protected SAXDocumentSerializer(boolean v) {
66 super(v);
67 }
68
69 public SAXDocumentSerializer() {
70 }
71
72
73 public void reset() {
74 super.reset();
75
76 _elementHasNamespaces = false;
77 _charactersAsCDATA = false;
78 }
79
80 // ContentHandler
81
82 public final void startDocument() throws SAXException {
83 try {
84 reset();
85 encodeHeader(false);
86 encodeInitialVocabulary();
87 } catch (IOException e) {
88 throw new SAXException("startDocument", e);
89 }
90 }
91
92 public final void endDocument() throws SAXException {
93 try {
94 encodeDocumentTermination();
95 } catch (IOException e) {
96 throw new SAXException("endDocument", e);
97 }
98 }
99
100 public void startPrefixMapping(String prefix, String uri) throws SAXException {
101 try {
102 if (_elementHasNamespaces == false) {
103 encodeTermination();
104
105 // Mark the current buffer position to flag attributes if necessary
106 mark();
107 _elementHasNamespaces = true;
108
109 // Write out Element byte with namespaces
110 write(EncodingConstants.ELEMENT | EncodingConstants.ELEMENT_NAMESPACES_FLAG);
111 }
112
113 encodeNamespaceAttribute(prefix, uri);
114 } catch (IOException e) {
115 throw new SAXException("startElement", e);
116 }
117 }
118
119 public final void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
120 // TODO consider using buffer for encoding of attributes, then pre-counting is not necessary
121 final int attributeCount = (atts != null && atts.getLength() > 0)
122 ? countAttributes(atts) : 0;
123 try {
124 if (_elementHasNamespaces) {
125 _elementHasNamespaces = false;
126
127 if (attributeCount > 0) {
128 // Flag the marked byte with attributes
129 _octetBuffer[_markIndex] |= EncodingConstants.ELEMENT_ATTRIBUTE_FLAG;
130 }
131 resetMark();
132
133 write(EncodingConstants.TERMINATOR);
134
135 _b = 0;
136 } else {
137 encodeTermination();
138
139 _b = EncodingConstants.ELEMENT;
140 if (attributeCount > 0) {
141 _b |= EncodingConstants.ELEMENT_ATTRIBUTE_FLAG;
142 }
143 }
144
145 encodeElement(namespaceURI, qName, localName);
146
147 if (attributeCount > 0) {
148 encodeAttributes(atts);
149 }
150 } catch (IOException e) {
151 throw new SAXException("startElement", e);
152 } catch (FastInfosetException e) {
153 throw new SAXException("startElement", e);
154 }
155 }
156
157 public final void endElement(String namespaceURI, String localName, String qName) throws SAXException {
158 try {
159 encodeElementTermination();
160 } catch (IOException e) {
161 throw new SAXException("endElement", e);
162 }
163 }
164
165 public final void characters(char[] ch, int start, int length) throws SAXException {
166 if (length <= 0) {
167 return;
168 }
169
170 if (getIgnoreWhiteSpaceTextContent() &&
171 isWhiteSpace(ch, start, length)) return;
172
173 try {
174 encodeTermination();
175
176 if (!_charactersAsCDATA) {
177 encodeCharacters(ch, start, length);
178 } else {
179 encodeCIIBuiltInAlgorithmDataAsCDATA(ch, start, length);
180 }
181 } catch (IOException e) {
182 throw new SAXException(e);
183 } catch (FastInfosetException e) {
184 throw new SAXException(e);
185 }
186 }
187
188 public final void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
189 if (getIgnoreWhiteSpaceTextContent()) return;
190
191 characters(ch, start, length);
192 }
193
194 public final void processingInstruction(String target, String data) throws SAXException {
195 try {
196 if (getIgnoreProcesingInstructions()) return;
197
198 if (target.length() == 0) {
199 throw new SAXException(CommonResourceBundle.getInstance().
200 getString("message.processingInstructionTargetIsEmpty"));
201 }
202 encodeTermination();
203
204 encodeProcessingInstruction(target, data);
205 } catch (IOException e) {
206 throw new SAXException("processingInstruction", e);
207 }
208 }
209
210 public final void setDocumentLocator(org.xml.sax.Locator locator) {
211 }
212
213 public final void skippedEntity(String name) throws SAXException {
214 }
215
216
217
218 // LexicalHandler
219
220 public final void comment(char[] ch, int start, int length) throws SAXException {
221 try {
222 if (getIgnoreComments()) return;
223
224 encodeTermination();
225
226 encodeComment(ch, start, length);
227 } catch (IOException e) {
228 throw new SAXException("startElement", e);
229 }
230 }
231
232 public final void startCDATA() throws SAXException {
233 _charactersAsCDATA = true;
234 }
235
236 public final void endCDATA() throws SAXException {
237 _charactersAsCDATA = false;
238 }
239
240 public final void startDTD(String name, String publicId, String systemId) throws SAXException {
241 if (getIgnoreDTD()) return;
242
243 try {
244 encodeTermination();
245
246 encodeDocumentTypeDeclaration(publicId, systemId);
247 encodeElementTermination();
248 } catch (IOException e) {
249 throw new SAXException("startDTD", e);
250 }
251 }
252
253 public final void endDTD() throws SAXException {
254 }
255
256 public final void startEntity(String name) throws SAXException {
257 }
258
259 public final void endEntity(String name) throws SAXException {
260 }
261
262
263 // EncodingAlgorithmContentHandler
264
265 public final void octets(String URI, int id, byte[] b, int start, int length) throws SAXException {
266 if (length <= 0) {
267 return;
268 }
269
270 try {
271 encodeTermination();
272
273 encodeNonIdentifyingStringOnThirdBit(URI, id, b, start, length);
274 } catch (IOException e) {
275 throw new SAXException(e);
276 } catch (FastInfosetException e) {
277 throw new SAXException(e);
278 }
279 }
280
281 public final void object(String URI, int id, Object data) throws SAXException {
282 try {
283 encodeTermination();
284
285 encodeNonIdentifyingStringOnThirdBit(URI, id, data);
286 } catch (IOException e) {
287 throw new SAXException(e);
288 } catch (FastInfosetException e) {
289 throw new SAXException(e);
290 }
291 }
292
293
294 // PrimitiveTypeContentHandler
295
296 public final void bytes(byte[] b, int start, int length) throws SAXException {
297 if (length <= 0) {
298 return;
299 }
300
301 try {
302 encodeTermination();
303
304 encodeCIIOctetAlgorithmData(EncodingAlgorithmIndexes.BASE64, b, start, length);
305 } catch (IOException e) {
306 throw new SAXException(e);
307 }
308 }
309
310 public final void shorts(short[] s, int start, int length) throws SAXException {
311 if (length <= 0) {
312 return;
313 }
314
315 try {
316 encodeTermination();
317
318 encodeCIIBuiltInAlgorithmData(EncodingAlgorithmIndexes.SHORT, s, start, length);
319 } catch (IOException e) {
320 throw new SAXException(e);
321 } catch (FastInfosetException e) {
322 throw new SAXException(e);
323 }
324 }
325
326 public final void ints(int[] i, int start, int length) throws SAXException {
327 if (length <= 0) {
328 return;
329 }
330
331 try {
332 encodeTermination();
333
334 encodeCIIBuiltInAlgorithmData(EncodingAlgorithmIndexes.INT, i, start, length);
335 } catch (IOException e) {
336 throw new SAXException(e);
337 } catch (FastInfosetException e) {
338 throw new SAXException(e);
339 }
340 }
341
342 public final void longs(long[] l, int start, int length) throws SAXException {
343 if (length <= 0) {
344 return;
345 }
346
347 try {
348 encodeTermination();
349
350 encodeCIIBuiltInAlgorithmData(EncodingAlgorithmIndexes.LONG, l, start, length);
351 } catch (IOException e) {
352 throw new SAXException(e);
353 } catch (FastInfosetException e) {
354 throw new SAXException(e);
355 }
356 }
357
358 public final void booleans(boolean[] b, int start, int length) throws SAXException {
359 if (length <= 0) {
360 return;
361 }
362
363 try {
364 encodeTermination();
365
366 encodeCIIBuiltInAlgorithmData(EncodingAlgorithmIndexes.BOOLEAN, b, start, length);
367 } catch (IOException e) {
368 throw new SAXException(e);
369 } catch (FastInfosetException e) {
370 throw new SAXException(e);
371 }
372 }
373
374 public final void floats(float[] f, int start, int length) throws SAXException {
375 if (length <= 0) {
376 return;
377 }
378
379 try {
380 encodeTermination();
381
382 encodeCIIBuiltInAlgorithmData(EncodingAlgorithmIndexes.FLOAT, f, start, length);
383 } catch (IOException e) {
384 throw new SAXException(e);
385 } catch (FastInfosetException e) {
386 throw new SAXException(e);
387 }
388 }
389
390 public final void doubles(double[] d, int start, int length) throws SAXException {
391 if (length <= 0) {
392 return;
393 }
394
395 try {
396 encodeTermination();
397
398 encodeCIIBuiltInAlgorithmData(EncodingAlgorithmIndexes.DOUBLE, d, start, length);
399 } catch (IOException e) {
400 throw new SAXException(e);
401 } catch (FastInfosetException e) {
402 throw new SAXException(e);
403 }
404 }
405
406 public void uuids(long[] msblsb, int start, int length) throws SAXException {
407 if (length <= 0) {
408 return;
409 }
410
411 try {
412 encodeTermination();
413
414 encodeCIIBuiltInAlgorithmData(EncodingAlgorithmIndexes.UUID, msblsb, start, length);
415 } catch (IOException e) {
416 throw new SAXException(e);
417 } catch (FastInfosetException e) {
418 throw new SAXException(e);
419 }
420 }
421
422
423 // RestrictedAlphabetContentHandler
424
425 public void numericCharacters(char ch[], int start, int length) throws SAXException {
426 if (length <= 0) {
427 return;
428 }
429
430 try {
431 encodeTermination();
432
433 final boolean addToTable = isCharacterContentChunkLengthMatchesLimit(length);
434 encodeNumericFourBitCharacters(ch, start, length, addToTable);
435 } catch (IOException e) {
436 throw new SAXException(e);
437 } catch (FastInfosetException e) {
438 throw new SAXException(e);
439 }
440 }
441
442 public void dateTimeCharacters(char ch[], int start, int length) throws SAXException {
443 if (length <= 0) {
444 return;
445 }
446
447 try {
448 encodeTermination();
449
450 final boolean addToTable = isCharacterContentChunkLengthMatchesLimit(length);
451 encodeDateTimeFourBitCharacters(ch, start, length, addToTable);
452 } catch (IOException e) {
453 throw new SAXException(e);
454 } catch (FastInfosetException e) {
455 throw new SAXException(e);
456 }
457 }
458
459 public void alphabetCharacters(String alphabet, char ch[], int start, int length) throws SAXException {
460 if (length <= 0) {
461 return;
462 }
463
464 try {
465 encodeTermination();
466
467 final boolean addToTable = isCharacterContentChunkLengthMatchesLimit(length);
468 encodeAlphabetCharacters(alphabet, ch, start, length, addToTable);
469 } catch (IOException e) {
470 throw new SAXException(e);
471 } catch (FastInfosetException e) {
472 throw new SAXException(e);
473 }
474 }
475
476 // ExtendedContentHandler
477
478 public void characters(char[] ch, int start, int length, boolean index) throws SAXException {
479 if (length <= 0) {
480 return;
481 }
482
483 if (getIgnoreWhiteSpaceTextContent() &&
484 isWhiteSpace(ch, start, length)) return;
485
486 try {
487 encodeTermination();
488
489 if (!_charactersAsCDATA) {
490 encodeNonIdentifyingStringOnThirdBit(ch, start, length, _v.characterContentChunk, index, true);
491 } else {
492 encodeCIIBuiltInAlgorithmDataAsCDATA(ch, start, length);
493 }
494 } catch (IOException e) {
495 throw new SAXException(e);
496 } catch (FastInfosetException e) {
497 throw new SAXException(e);
498 }
499 }
500
501
502
503 protected final int countAttributes(Attributes atts) {
504 // Count attributes ignoring any in the XMLNS namespace
505 // Note, such attributes may be produced when transforming from a DOM node
506 int count = 0;
507 for (int i = 0; i < atts.getLength(); i++) {
508 final String uri = atts.getURI(i);
509 if (uri == "http://www.w3.org/2000/xmlns/" || uri.equals("http://www.w3.org/2000/xmlns/")) {
510 continue;
511 }
512 count++;
513 }
514 return count;
515 }
516
517 protected void encodeAttributes(Attributes atts) throws IOException, FastInfosetException {
518 boolean addToTable;
519 boolean mustBeAddedToTable;
520 String value;
521 if (atts instanceof EncodingAlgorithmAttributes) {
522 final EncodingAlgorithmAttributes eAtts = (EncodingAlgorithmAttributes)atts;
523 Object data;
524 String alphabet;
525 for (int i = 0; i < eAtts.getLength(); i++) {
526 if (encodeAttribute(atts.getURI(i), atts.getQName(i), atts.getLocalName(i))) {
527 data = eAtts.getAlgorithmData(i);
528 // If data is null then there is no algorithm data
529 if (data == null) {
530 value = eAtts.getValue(i);
531 addToTable = isAttributeValueLengthMatchesLimit(value.length());
532 mustBeAddedToTable = eAtts.getToIndex(i);
533
534 alphabet = eAtts.getAlpababet(i);
535 if (alphabet == null) {
536 encodeNonIdentifyingStringOnFirstBit(value, _v.attributeValue, addToTable, mustBeAddedToTable);
537 } else if (alphabet == RestrictedAlphabet.DATE_TIME_CHARACTERS) {
538 encodeDateTimeNonIdentifyingStringOnFirstBit(
539 value, addToTable, mustBeAddedToTable);
540 } else if (alphabet == RestrictedAlphabet.NUMERIC_CHARACTERS) {
541 encodeNumericNonIdentifyingStringOnFirstBit(
542 value, addToTable, mustBeAddedToTable);
543 } else {
544 encodeNonIdentifyingStringOnFirstBit(value, _v.attributeValue, addToTable, mustBeAddedToTable);
545 }
546 } else {
547 encodeNonIdentifyingStringOnFirstBit(eAtts.getAlgorithmURI(i),
548 eAtts.getAlgorithmIndex(i), data);
549 }
550 }
551 }
552 } else {
553 for (int i = 0; i < atts.getLength(); i++) {
554 if (encodeAttribute(atts.getURI(i), atts.getQName(i), atts.getLocalName(i))) {
555 value = atts.getValue(i);
556 addToTable = isAttributeValueLengthMatchesLimit(value.length());
557 encodeNonIdentifyingStringOnFirstBit(value, _v.attributeValue, addToTable, false);
558 }
559 }
560 }
561 _b = EncodingConstants.TERMINATOR;
562 _terminate = true;
563 }
564
565 protected void encodeElement(String namespaceURI, String qName, String localName) throws IOException {
566 LocalNameQualifiedNamesMap.Entry entry = _v.elementName.obtainEntry(qName);
567 if (entry._valueIndex > 0) {
568 QualifiedName[] names = entry._value;
569 for (int i = 0; i < entry._valueIndex; i++) {
570 final QualifiedName n = names[i];
571 if ((namespaceURI == n.namespaceName || namespaceURI.equals(n.namespaceName))) {
572 encodeNonZeroIntegerOnThirdBit(names[i].index);
573 return;
574 }
575 }
576 }
577
578 encodeLiteralElementQualifiedNameOnThirdBit(namespaceURI, getPrefixFromQualifiedName(qName),
579 localName, entry);
580 }
581
582 protected boolean encodeAttribute(String namespaceURI, String qName, String localName) throws IOException {
583 LocalNameQualifiedNamesMap.Entry entry = _v.attributeName.obtainEntry(qName);
584 if (entry._valueIndex > 0) {
585 QualifiedName[] names = entry._value;
586 for (int i = 0; i < entry._valueIndex; i++) {
587 if ((namespaceURI == names[i].namespaceName || namespaceURI.equals(names[i].namespaceName))) {
588 encodeNonZeroIntegerOnSecondBitFirstBitZero(names[i].index);
589 return true;
590 }
591 }
592 }
593
594 return encodeLiteralAttributeQualifiedNameOnSecondBit(namespaceURI, getPrefixFromQualifiedName(qName),
595 localName, entry);
596 }
597 }

mercurial