1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/jaxws_classes/com/sun/xml/internal/fastinfoset/sax/SAXDocumentSerializer.java Tue Mar 06 16:09:35 2012 -0800 1.3 @@ -0,0 +1,597 @@ 1.4 +/* 1.5 + * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. Oracle designates this 1.11 + * particular file as subject to the "Classpath" exception as provided 1.12 + * by Oracle in the LICENSE file that accompanied this code. 1.13 + * 1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.17 + * version 2 for more details (a copy is included in the LICENSE file that 1.18 + * accompanied this code). 1.19 + * 1.20 + * You should have received a copy of the GNU General Public License version 1.21 + * 2 along with this work; if not, write to the Free Software Foundation, 1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.23 + * 1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.25 + * or visit www.oracle.com if you need additional information or have any 1.26 + * questions. 1.27 + * 1.28 + * THIS FILE WAS MODIFIED BY SUN MICROSYSTEMS, INC. 1.29 + */ 1.30 + 1.31 +package com.sun.xml.internal.fastinfoset.sax; 1.32 + 1.33 +import com.sun.xml.internal.fastinfoset.Encoder; 1.34 +import com.sun.xml.internal.fastinfoset.EncodingConstants; 1.35 +import com.sun.xml.internal.fastinfoset.QualifiedName; 1.36 +import com.sun.xml.internal.org.jvnet.fastinfoset.sax.FastInfosetWriter; 1.37 +import com.sun.xml.internal.fastinfoset.util.LocalNameQualifiedNamesMap; 1.38 +import java.io.IOException; 1.39 +import com.sun.xml.internal.org.jvnet.fastinfoset.EncodingAlgorithmIndexes; 1.40 +import com.sun.xml.internal.org.jvnet.fastinfoset.FastInfosetException; 1.41 +import com.sun.xml.internal.org.jvnet.fastinfoset.RestrictedAlphabet; 1.42 +import com.sun.xml.internal.org.jvnet.fastinfoset.sax.EncodingAlgorithmAttributes; 1.43 +import org.xml.sax.Attributes; 1.44 +import org.xml.sax.SAXException; 1.45 +import com.sun.xml.internal.fastinfoset.CommonResourceBundle; 1.46 + 1.47 +/** 1.48 + * The Fast Infoset SAX serializer. 1.49 + * <p> 1.50 + * Instantiate this serializer to serialize a fast infoset document in accordance 1.51 + * with the SAX API. 1.52 + * <p> 1.53 + * This utilizes the SAX API in a reverse manner to that of parsing. It is the 1.54 + * responsibility of the client to call the appropriate event methods on the 1.55 + * SAX handlers, and to ensure that such a sequence of methods calls results 1.56 + * in the production well-formed fast infoset documents. The 1.57 + * SAXDocumentSerializer performs no well-formed checks. 1.58 + * 1.59 + * <p> 1.60 + * More than one fast infoset document may be encoded to the 1.61 + * {@link java.io.OutputStream}. 1.62 + */ 1.63 +public class SAXDocumentSerializer extends Encoder implements FastInfosetWriter { 1.64 + protected boolean _elementHasNamespaces = false; 1.65 + 1.66 + protected boolean _charactersAsCDATA = false; 1.67 + 1.68 + protected SAXDocumentSerializer(boolean v) { 1.69 + super(v); 1.70 + } 1.71 + 1.72 + public SAXDocumentSerializer() { 1.73 + } 1.74 + 1.75 + 1.76 + public void reset() { 1.77 + super.reset(); 1.78 + 1.79 + _elementHasNamespaces = false; 1.80 + _charactersAsCDATA = false; 1.81 + } 1.82 + 1.83 + // ContentHandler 1.84 + 1.85 + public final void startDocument() throws SAXException { 1.86 + try { 1.87 + reset(); 1.88 + encodeHeader(false); 1.89 + encodeInitialVocabulary(); 1.90 + } catch (IOException e) { 1.91 + throw new SAXException("startDocument", e); 1.92 + } 1.93 + } 1.94 + 1.95 + public final void endDocument() throws SAXException { 1.96 + try { 1.97 + encodeDocumentTermination(); 1.98 + } catch (IOException e) { 1.99 + throw new SAXException("endDocument", e); 1.100 + } 1.101 + } 1.102 + 1.103 + public void startPrefixMapping(String prefix, String uri) throws SAXException { 1.104 + try { 1.105 + if (_elementHasNamespaces == false) { 1.106 + encodeTermination(); 1.107 + 1.108 + // Mark the current buffer position to flag attributes if necessary 1.109 + mark(); 1.110 + _elementHasNamespaces = true; 1.111 + 1.112 + // Write out Element byte with namespaces 1.113 + write(EncodingConstants.ELEMENT | EncodingConstants.ELEMENT_NAMESPACES_FLAG); 1.114 + } 1.115 + 1.116 + encodeNamespaceAttribute(prefix, uri); 1.117 + } catch (IOException e) { 1.118 + throw new SAXException("startElement", e); 1.119 + } 1.120 + } 1.121 + 1.122 + public final void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException { 1.123 + // TODO consider using buffer for encoding of attributes, then pre-counting is not necessary 1.124 + final int attributeCount = (atts != null && atts.getLength() > 0) 1.125 + ? countAttributes(atts) : 0; 1.126 + try { 1.127 + if (_elementHasNamespaces) { 1.128 + _elementHasNamespaces = false; 1.129 + 1.130 + if (attributeCount > 0) { 1.131 + // Flag the marked byte with attributes 1.132 + _octetBuffer[_markIndex] |= EncodingConstants.ELEMENT_ATTRIBUTE_FLAG; 1.133 + } 1.134 + resetMark(); 1.135 + 1.136 + write(EncodingConstants.TERMINATOR); 1.137 + 1.138 + _b = 0; 1.139 + } else { 1.140 + encodeTermination(); 1.141 + 1.142 + _b = EncodingConstants.ELEMENT; 1.143 + if (attributeCount > 0) { 1.144 + _b |= EncodingConstants.ELEMENT_ATTRIBUTE_FLAG; 1.145 + } 1.146 + } 1.147 + 1.148 + encodeElement(namespaceURI, qName, localName); 1.149 + 1.150 + if (attributeCount > 0) { 1.151 + encodeAttributes(atts); 1.152 + } 1.153 + } catch (IOException e) { 1.154 + throw new SAXException("startElement", e); 1.155 + } catch (FastInfosetException e) { 1.156 + throw new SAXException("startElement", e); 1.157 + } 1.158 + } 1.159 + 1.160 + public final void endElement(String namespaceURI, String localName, String qName) throws SAXException { 1.161 + try { 1.162 + encodeElementTermination(); 1.163 + } catch (IOException e) { 1.164 + throw new SAXException("endElement", e); 1.165 + } 1.166 + } 1.167 + 1.168 + public final void characters(char[] ch, int start, int length) throws SAXException { 1.169 + if (length <= 0) { 1.170 + return; 1.171 + } 1.172 + 1.173 + if (getIgnoreWhiteSpaceTextContent() && 1.174 + isWhiteSpace(ch, start, length)) return; 1.175 + 1.176 + try { 1.177 + encodeTermination(); 1.178 + 1.179 + if (!_charactersAsCDATA) { 1.180 + encodeCharacters(ch, start, length); 1.181 + } else { 1.182 + encodeCIIBuiltInAlgorithmDataAsCDATA(ch, start, length); 1.183 + } 1.184 + } catch (IOException e) { 1.185 + throw new SAXException(e); 1.186 + } catch (FastInfosetException e) { 1.187 + throw new SAXException(e); 1.188 + } 1.189 + } 1.190 + 1.191 + public final void ignorableWhitespace(char[] ch, int start, int length) throws SAXException { 1.192 + if (getIgnoreWhiteSpaceTextContent()) return; 1.193 + 1.194 + characters(ch, start, length); 1.195 + } 1.196 + 1.197 + public final void processingInstruction(String target, String data) throws SAXException { 1.198 + try { 1.199 + if (getIgnoreProcesingInstructions()) return; 1.200 + 1.201 + if (target.length() == 0) { 1.202 + throw new SAXException(CommonResourceBundle.getInstance(). 1.203 + getString("message.processingInstructionTargetIsEmpty")); 1.204 + } 1.205 + encodeTermination(); 1.206 + 1.207 + encodeProcessingInstruction(target, data); 1.208 + } catch (IOException e) { 1.209 + throw new SAXException("processingInstruction", e); 1.210 + } 1.211 + } 1.212 + 1.213 + public final void setDocumentLocator(org.xml.sax.Locator locator) { 1.214 + } 1.215 + 1.216 + public final void skippedEntity(String name) throws SAXException { 1.217 + } 1.218 + 1.219 + 1.220 + 1.221 + // LexicalHandler 1.222 + 1.223 + public final void comment(char[] ch, int start, int length) throws SAXException { 1.224 + try { 1.225 + if (getIgnoreComments()) return; 1.226 + 1.227 + encodeTermination(); 1.228 + 1.229 + encodeComment(ch, start, length); 1.230 + } catch (IOException e) { 1.231 + throw new SAXException("startElement", e); 1.232 + } 1.233 + } 1.234 + 1.235 + public final void startCDATA() throws SAXException { 1.236 + _charactersAsCDATA = true; 1.237 + } 1.238 + 1.239 + public final void endCDATA() throws SAXException { 1.240 + _charactersAsCDATA = false; 1.241 + } 1.242 + 1.243 + public final void startDTD(String name, String publicId, String systemId) throws SAXException { 1.244 + if (getIgnoreDTD()) return; 1.245 + 1.246 + try { 1.247 + encodeTermination(); 1.248 + 1.249 + encodeDocumentTypeDeclaration(publicId, systemId); 1.250 + encodeElementTermination(); 1.251 + } catch (IOException e) { 1.252 + throw new SAXException("startDTD", e); 1.253 + } 1.254 + } 1.255 + 1.256 + public final void endDTD() throws SAXException { 1.257 + } 1.258 + 1.259 + public final void startEntity(String name) throws SAXException { 1.260 + } 1.261 + 1.262 + public final void endEntity(String name) throws SAXException { 1.263 + } 1.264 + 1.265 + 1.266 + // EncodingAlgorithmContentHandler 1.267 + 1.268 + public final void octets(String URI, int id, byte[] b, int start, int length) throws SAXException { 1.269 + if (length <= 0) { 1.270 + return; 1.271 + } 1.272 + 1.273 + try { 1.274 + encodeTermination(); 1.275 + 1.276 + encodeNonIdentifyingStringOnThirdBit(URI, id, b, start, length); 1.277 + } catch (IOException e) { 1.278 + throw new SAXException(e); 1.279 + } catch (FastInfosetException e) { 1.280 + throw new SAXException(e); 1.281 + } 1.282 + } 1.283 + 1.284 + public final void object(String URI, int id, Object data) throws SAXException { 1.285 + try { 1.286 + encodeTermination(); 1.287 + 1.288 + encodeNonIdentifyingStringOnThirdBit(URI, id, data); 1.289 + } catch (IOException e) { 1.290 + throw new SAXException(e); 1.291 + } catch (FastInfosetException e) { 1.292 + throw new SAXException(e); 1.293 + } 1.294 + } 1.295 + 1.296 + 1.297 + // PrimitiveTypeContentHandler 1.298 + 1.299 + public final void bytes(byte[] b, int start, int length) throws SAXException { 1.300 + if (length <= 0) { 1.301 + return; 1.302 + } 1.303 + 1.304 + try { 1.305 + encodeTermination(); 1.306 + 1.307 + encodeCIIOctetAlgorithmData(EncodingAlgorithmIndexes.BASE64, b, start, length); 1.308 + } catch (IOException e) { 1.309 + throw new SAXException(e); 1.310 + } 1.311 + } 1.312 + 1.313 + public final void shorts(short[] s, int start, int length) throws SAXException { 1.314 + if (length <= 0) { 1.315 + return; 1.316 + } 1.317 + 1.318 + try { 1.319 + encodeTermination(); 1.320 + 1.321 + encodeCIIBuiltInAlgorithmData(EncodingAlgorithmIndexes.SHORT, s, start, length); 1.322 + } catch (IOException e) { 1.323 + throw new SAXException(e); 1.324 + } catch (FastInfosetException e) { 1.325 + throw new SAXException(e); 1.326 + } 1.327 + } 1.328 + 1.329 + public final void ints(int[] i, int start, int length) throws SAXException { 1.330 + if (length <= 0) { 1.331 + return; 1.332 + } 1.333 + 1.334 + try { 1.335 + encodeTermination(); 1.336 + 1.337 + encodeCIIBuiltInAlgorithmData(EncodingAlgorithmIndexes.INT, i, start, length); 1.338 + } catch (IOException e) { 1.339 + throw new SAXException(e); 1.340 + } catch (FastInfosetException e) { 1.341 + throw new SAXException(e); 1.342 + } 1.343 + } 1.344 + 1.345 + public final void longs(long[] l, int start, int length) throws SAXException { 1.346 + if (length <= 0) { 1.347 + return; 1.348 + } 1.349 + 1.350 + try { 1.351 + encodeTermination(); 1.352 + 1.353 + encodeCIIBuiltInAlgorithmData(EncodingAlgorithmIndexes.LONG, l, start, length); 1.354 + } catch (IOException e) { 1.355 + throw new SAXException(e); 1.356 + } catch (FastInfosetException e) { 1.357 + throw new SAXException(e); 1.358 + } 1.359 + } 1.360 + 1.361 + public final void booleans(boolean[] b, int start, int length) throws SAXException { 1.362 + if (length <= 0) { 1.363 + return; 1.364 + } 1.365 + 1.366 + try { 1.367 + encodeTermination(); 1.368 + 1.369 + encodeCIIBuiltInAlgorithmData(EncodingAlgorithmIndexes.BOOLEAN, b, start, length); 1.370 + } catch (IOException e) { 1.371 + throw new SAXException(e); 1.372 + } catch (FastInfosetException e) { 1.373 + throw new SAXException(e); 1.374 + } 1.375 + } 1.376 + 1.377 + public final void floats(float[] f, int start, int length) throws SAXException { 1.378 + if (length <= 0) { 1.379 + return; 1.380 + } 1.381 + 1.382 + try { 1.383 + encodeTermination(); 1.384 + 1.385 + encodeCIIBuiltInAlgorithmData(EncodingAlgorithmIndexes.FLOAT, f, start, length); 1.386 + } catch (IOException e) { 1.387 + throw new SAXException(e); 1.388 + } catch (FastInfosetException e) { 1.389 + throw new SAXException(e); 1.390 + } 1.391 + } 1.392 + 1.393 + public final void doubles(double[] d, int start, int length) throws SAXException { 1.394 + if (length <= 0) { 1.395 + return; 1.396 + } 1.397 + 1.398 + try { 1.399 + encodeTermination(); 1.400 + 1.401 + encodeCIIBuiltInAlgorithmData(EncodingAlgorithmIndexes.DOUBLE, d, start, length); 1.402 + } catch (IOException e) { 1.403 + throw new SAXException(e); 1.404 + } catch (FastInfosetException e) { 1.405 + throw new SAXException(e); 1.406 + } 1.407 + } 1.408 + 1.409 + public void uuids(long[] msblsb, int start, int length) throws SAXException { 1.410 + if (length <= 0) { 1.411 + return; 1.412 + } 1.413 + 1.414 + try { 1.415 + encodeTermination(); 1.416 + 1.417 + encodeCIIBuiltInAlgorithmData(EncodingAlgorithmIndexes.UUID, msblsb, start, length); 1.418 + } catch (IOException e) { 1.419 + throw new SAXException(e); 1.420 + } catch (FastInfosetException e) { 1.421 + throw new SAXException(e); 1.422 + } 1.423 + } 1.424 + 1.425 + 1.426 + // RestrictedAlphabetContentHandler 1.427 + 1.428 + public void numericCharacters(char ch[], int start, int length) throws SAXException { 1.429 + if (length <= 0) { 1.430 + return; 1.431 + } 1.432 + 1.433 + try { 1.434 + encodeTermination(); 1.435 + 1.436 + final boolean addToTable = isCharacterContentChunkLengthMatchesLimit(length); 1.437 + encodeNumericFourBitCharacters(ch, start, length, addToTable); 1.438 + } catch (IOException e) { 1.439 + throw new SAXException(e); 1.440 + } catch (FastInfosetException e) { 1.441 + throw new SAXException(e); 1.442 + } 1.443 + } 1.444 + 1.445 + public void dateTimeCharacters(char ch[], int start, int length) throws SAXException { 1.446 + if (length <= 0) { 1.447 + return; 1.448 + } 1.449 + 1.450 + try { 1.451 + encodeTermination(); 1.452 + 1.453 + final boolean addToTable = isCharacterContentChunkLengthMatchesLimit(length); 1.454 + encodeDateTimeFourBitCharacters(ch, start, length, addToTable); 1.455 + } catch (IOException e) { 1.456 + throw new SAXException(e); 1.457 + } catch (FastInfosetException e) { 1.458 + throw new SAXException(e); 1.459 + } 1.460 + } 1.461 + 1.462 + public void alphabetCharacters(String alphabet, char ch[], int start, int length) throws SAXException { 1.463 + if (length <= 0) { 1.464 + return; 1.465 + } 1.466 + 1.467 + try { 1.468 + encodeTermination(); 1.469 + 1.470 + final boolean addToTable = isCharacterContentChunkLengthMatchesLimit(length); 1.471 + encodeAlphabetCharacters(alphabet, ch, start, length, addToTable); 1.472 + } catch (IOException e) { 1.473 + throw new SAXException(e); 1.474 + } catch (FastInfosetException e) { 1.475 + throw new SAXException(e); 1.476 + } 1.477 + } 1.478 + 1.479 + // ExtendedContentHandler 1.480 + 1.481 + public void characters(char[] ch, int start, int length, boolean index) throws SAXException { 1.482 + if (length <= 0) { 1.483 + return; 1.484 + } 1.485 + 1.486 + if (getIgnoreWhiteSpaceTextContent() && 1.487 + isWhiteSpace(ch, start, length)) return; 1.488 + 1.489 + try { 1.490 + encodeTermination(); 1.491 + 1.492 + if (!_charactersAsCDATA) { 1.493 + encodeNonIdentifyingStringOnThirdBit(ch, start, length, _v.characterContentChunk, index, true); 1.494 + } else { 1.495 + encodeCIIBuiltInAlgorithmDataAsCDATA(ch, start, length); 1.496 + } 1.497 + } catch (IOException e) { 1.498 + throw new SAXException(e); 1.499 + } catch (FastInfosetException e) { 1.500 + throw new SAXException(e); 1.501 + } 1.502 + } 1.503 + 1.504 + 1.505 + 1.506 + protected final int countAttributes(Attributes atts) { 1.507 + // Count attributes ignoring any in the XMLNS namespace 1.508 + // Note, such attributes may be produced when transforming from a DOM node 1.509 + int count = 0; 1.510 + for (int i = 0; i < atts.getLength(); i++) { 1.511 + final String uri = atts.getURI(i); 1.512 + if (uri == "http://www.w3.org/2000/xmlns/" || uri.equals("http://www.w3.org/2000/xmlns/")) { 1.513 + continue; 1.514 + } 1.515 + count++; 1.516 + } 1.517 + return count; 1.518 + } 1.519 + 1.520 + protected void encodeAttributes(Attributes atts) throws IOException, FastInfosetException { 1.521 + boolean addToTable; 1.522 + boolean mustBeAddedToTable; 1.523 + String value; 1.524 + if (atts instanceof EncodingAlgorithmAttributes) { 1.525 + final EncodingAlgorithmAttributes eAtts = (EncodingAlgorithmAttributes)atts; 1.526 + Object data; 1.527 + String alphabet; 1.528 + for (int i = 0; i < eAtts.getLength(); i++) { 1.529 + if (encodeAttribute(atts.getURI(i), atts.getQName(i), atts.getLocalName(i))) { 1.530 + data = eAtts.getAlgorithmData(i); 1.531 + // If data is null then there is no algorithm data 1.532 + if (data == null) { 1.533 + value = eAtts.getValue(i); 1.534 + addToTable = isAttributeValueLengthMatchesLimit(value.length()); 1.535 + mustBeAddedToTable = eAtts.getToIndex(i); 1.536 + 1.537 + alphabet = eAtts.getAlpababet(i); 1.538 + if (alphabet == null) { 1.539 + encodeNonIdentifyingStringOnFirstBit(value, _v.attributeValue, addToTable, mustBeAddedToTable); 1.540 + } else if (alphabet == RestrictedAlphabet.DATE_TIME_CHARACTERS) { 1.541 + encodeDateTimeNonIdentifyingStringOnFirstBit( 1.542 + value, addToTable, mustBeAddedToTable); 1.543 + } else if (alphabet == RestrictedAlphabet.NUMERIC_CHARACTERS) { 1.544 + encodeNumericNonIdentifyingStringOnFirstBit( 1.545 + value, addToTable, mustBeAddedToTable); 1.546 + } else { 1.547 + encodeNonIdentifyingStringOnFirstBit(value, _v.attributeValue, addToTable, mustBeAddedToTable); 1.548 + } 1.549 + } else { 1.550 + encodeNonIdentifyingStringOnFirstBit(eAtts.getAlgorithmURI(i), 1.551 + eAtts.getAlgorithmIndex(i), data); 1.552 + } 1.553 + } 1.554 + } 1.555 + } else { 1.556 + for (int i = 0; i < atts.getLength(); i++) { 1.557 + if (encodeAttribute(atts.getURI(i), atts.getQName(i), atts.getLocalName(i))) { 1.558 + value = atts.getValue(i); 1.559 + addToTable = isAttributeValueLengthMatchesLimit(value.length()); 1.560 + encodeNonIdentifyingStringOnFirstBit(value, _v.attributeValue, addToTable, false); 1.561 + } 1.562 + } 1.563 + } 1.564 + _b = EncodingConstants.TERMINATOR; 1.565 + _terminate = true; 1.566 + } 1.567 + 1.568 + protected void encodeElement(String namespaceURI, String qName, String localName) throws IOException { 1.569 + LocalNameQualifiedNamesMap.Entry entry = _v.elementName.obtainEntry(qName); 1.570 + if (entry._valueIndex > 0) { 1.571 + QualifiedName[] names = entry._value; 1.572 + for (int i = 0; i < entry._valueIndex; i++) { 1.573 + final QualifiedName n = names[i]; 1.574 + if ((namespaceURI == n.namespaceName || namespaceURI.equals(n.namespaceName))) { 1.575 + encodeNonZeroIntegerOnThirdBit(names[i].index); 1.576 + return; 1.577 + } 1.578 + } 1.579 + } 1.580 + 1.581 + encodeLiteralElementQualifiedNameOnThirdBit(namespaceURI, getPrefixFromQualifiedName(qName), 1.582 + localName, entry); 1.583 + } 1.584 + 1.585 + protected boolean encodeAttribute(String namespaceURI, String qName, String localName) throws IOException { 1.586 + LocalNameQualifiedNamesMap.Entry entry = _v.attributeName.obtainEntry(qName); 1.587 + if (entry._valueIndex > 0) { 1.588 + QualifiedName[] names = entry._value; 1.589 + for (int i = 0; i < entry._valueIndex; i++) { 1.590 + if ((namespaceURI == names[i].namespaceName || namespaceURI.equals(names[i].namespaceName))) { 1.591 + encodeNonZeroIntegerOnSecondBitFirstBitZero(names[i].index); 1.592 + return true; 1.593 + } 1.594 + } 1.595 + } 1.596 + 1.597 + return encodeLiteralAttributeQualifiedNameOnSecondBit(namespaceURI, getPrefixFromQualifiedName(qName), 1.598 + localName, entry); 1.599 + } 1.600 +}