diff -r 000000000000 -r 373ffda63c9a src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/output/FastInfosetStreamWriterOutput.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/output/FastInfosetStreamWriterOutput.java Wed Apr 27 01:27:09 2016 +0800 @@ -0,0 +1,463 @@ +/* + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.xml.internal.bind.v2.runtime.output; + +import com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl; +import com.sun.xml.internal.bind.v2.runtime.Name; +import com.sun.xml.internal.bind.v2.runtime.XMLSerializer; +import javax.xml.stream.XMLStreamException; + +import com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data; +import com.sun.xml.internal.fastinfoset.EncodingConstants; +import com.sun.xml.internal.fastinfoset.stax.StAXDocumentSerializer; +import java.io.IOException; +import java.util.Collection; +import java.util.Map; +import java.util.WeakHashMap; +import javax.xml.bind.JAXBContext; +import com.sun.xml.internal.org.jvnet.fastinfoset.VocabularyApplicationData; +import org.xml.sax.SAXException; + +/** + * {@link XmlOutput} for {@link LowLevelStAXDocumentSerializer}. + *
+ * This class is responsible for managing the indexing of elements, attributes + * and local names that are known to JAXB by way of the JAXBContext (generated + * from JAXB beans or schema). The pre-encoded UTF-8 representations of known + * local names are also utilized. + *
+ * The lookup of elements, attributes and local names with respect to a context + * is very efficient. It relies on an incrementing base line so that look up is + * performed in O(1) time and only uses static memory. When the base line reaches + * a point where integer overflow will occur the arrays and base line are reset + * (such an event is rare and will have little impact on performance). + *
+ * A weak map of JAXB contexts to optimized tables for attributes, elements and + * local names is utilized and stored on the LowLevel StAX serializer. Thus, + * optimized serializing can work other multiple serializing of JAXB beans using + * the same LowLevel StAX serializer instance. This approach works best when JAXB + * contexts are only created once per schema or JAXB beans (which is the recommended + * practice as the creation JAXB contexts are expensive, they are thread safe and + * can be reused). + * + * @author Paul.Sandoz@Sun.Com + */ +public final class FastInfosetStreamWriterOutput extends XMLStreamWriterOutput { + private final StAXDocumentSerializer fiout; + private final Encoded[] localNames; + private final TablesPerJAXBContext tables; + + /** + * Holder for the optimzed element, attribute and + * local name tables. + */ + final static class TablesPerJAXBContext { + final int[] elementIndexes; + final int[] elementIndexPrefixes; + + final int[] attributeIndexes; + final int[] localNameIndexes; + + /** + * The offset of the index + */ + int indexOffset; + + /** + * The the maximum known value of an index + */ + int maxIndex; + + /** + * True if the tables require clearing + */ + boolean requiresClear; + + /** + * Create a new set of tables for a JAXB context. + *
+ * @param content the JAXB context. + * @param initialIndexOffset the initial index offset to calculate + * the maximum possible index + * + */ + TablesPerJAXBContext(JAXBContextImpl context, int initialIndexOffset) { + elementIndexes = new int[context.getNumberOfElementNames()]; + elementIndexPrefixes = new int[context.getNumberOfElementNames()]; + attributeIndexes = new int[context.getNumberOfAttributeNames()]; + localNameIndexes = new int[context.getNumberOfLocalNames()]; + + indexOffset = 1; + maxIndex = initialIndexOffset + elementIndexes.length + attributeIndexes.length; + } + + /** + * Require that tables are cleared. + */ + public void requireClearTables() { + requiresClear = true; + } + + /** + * Clear or reset the tables. + *
+ * @param initialIndexOffset the initial index offset to calculate + * the maximum possible index + */ + public void clearOrResetTables(int intialIndexOffset) { + if (requiresClear) { + requiresClear = false; + + // Increment offset to new position + indexOffset += maxIndex; + // Reset the maximum known value of an index + maxIndex = intialIndexOffset + elementIndexes.length + attributeIndexes.length; + // Check if there is enough free space + // If overflow + if ((indexOffset + maxIndex) < 0) { + clearAll(); + } + } else { + // Reset the maximum known value of an index + maxIndex = intialIndexOffset + elementIndexes.length + attributeIndexes.length; + // Check if there is enough free space + // If overflow + if ((indexOffset + maxIndex) < 0) { + resetAll(); + } + } + } + + private void clearAll() { + clear(elementIndexes); + clear(attributeIndexes); + clear(localNameIndexes); + indexOffset = 1; + } + + private void clear(int[] array) { + for (int i = 0; i < array.length; i++) { + array[i] = 0; + } + } + + /** + * Increment the maximum know index value + *
+ * The indexes are preserved. + */ + public void incrementMaxIndexValue() { + // Increment the maximum value of an index + maxIndex++; + // Check if there is enough free space + // If overflow + if ((indexOffset + maxIndex) < 0) { + resetAll(); + } + } + + private void resetAll() { + clear(elementIndexes); + clear(attributeIndexes); + clear(localNameIndexes); + indexOffset = 1; + } + + private void reset(int[] array) { + for (int i = 0; i < array.length; i++) { + if (array[i] > indexOffset) { + array[i] = array[i] - indexOffset + 1; + } else { + array[i] = 0; + } + } + } + + } + + /** + * Holder of JAXB contexts -> tables. + *
+ * An instance will be registered with the
+ * {@link LowLevelStAXDocumentSerializer}.
+ */
+ final static class AppData implements VocabularyApplicationData {
+ final Map