001: /*
002: * The contents of this file are subject to the terms
003: * of the Common Development and Distribution License
004: * (the "License"). You may not use this file except
005: * in compliance with the License.
006: *
007: * You can obtain a copy of the license at
008: * https://jwsdp.dev.java.net/CDDLv1.0.html
009: * See the License for the specific language governing
010: * permissions and limitations under the License.
011: *
012: * When distributing Covered Code, include this CDDL
013: * HEADER in each file and include the License file at
014: * https://jwsdp.dev.java.net/CDDLv1.0.html If applicable,
015: * add the following below this CDDL HEADER, with the
016: * fields enclosed by brackets "[]" replaced with your
017: * own identifying information: Portions Copyright [yyyy]
018: * [name of copyright owner]
019: */
020: package com.sun.xml.stream.buffer;
021:
022: import com.sun.xml.stream.buffer.sax.Properties;
023: import com.sun.xml.stream.buffer.sax.SAXBufferCreator;
024: import com.sun.xml.stream.buffer.stax.StreamReaderBufferCreator;
025: import com.sun.xml.stream.buffer.stax.StreamWriterBufferCreator;
026: import org.xml.sax.ContentHandler;
027: import org.xml.sax.SAXException;
028: import org.xml.sax.XMLReader;
029:
030: import javax.xml.stream.XMLStreamException;
031: import javax.xml.stream.XMLStreamReader;
032: import javax.xml.stream.XMLStreamWriter;
033: import java.io.IOException;
034: import java.io.InputStream;
035:
036: /**
037: *
038: * A mutable stream-based buffer of an XML infoset.
039: *
040: * <p>
041: * A MutableXMLStreamBuffer is created using specific SAX and StAX-based
042: * creators. Utility methods on MutableXMLStreamBuffer are provided for
043: * such functionality that utilize SAX and StAX-based creators.
044: *
045: * <p>
046: * Once instantiated the same instance of a MutableXMLStreamBuffer may be reused for
047: * creation to reduce the amount of Objects instantiated and garbage
048: * collected that are required for internally representing an XML infoset.
049: *
050: * <p>
051: * A MutableXMLStreamBuffer is not designed to be created and processed
052: * concurrently. If done so unspecified behaviour may occur.
053: */
054: public class MutableXMLStreamBuffer extends XMLStreamBuffer {
055: /**
056: * The default array size for the arrays used in internal representation
057: * of the XML infoset.
058: */
059: public static final int DEFAULT_ARRAY_SIZE = 512;
060:
061: /**
062: * Create a new MutableXMLStreamBuffer using the
063: * {@link MutableXMLStreamBuffer#DEFAULT_ARRAY_SIZE}.
064: */
065: public MutableXMLStreamBuffer() {
066: this (DEFAULT_ARRAY_SIZE);
067: }
068:
069: /**
070: * Set the system identifier for this buffer.
071: * @param systemId The system identifier.
072: */
073: public void setSystemId(String systemId) {
074: this .systemId = systemId;
075: }
076:
077: /**
078: * Create a new MutableXMLStreamBuffer.
079: *
080: * @param size
081: * The size of the arrays used in the internal representation
082: * of the XML infoset.
083: * @throws NegativeArraySizeException
084: * If the <code>size</code> argument is less than <code>0</code>.
085: */
086: public MutableXMLStreamBuffer(int size) {
087: _structure = new FragmentedArray<byte[]>(new byte[size]);
088: _structureStrings = new FragmentedArray<String[]>(
089: new String[size]);
090: _contentCharactersBuffer = new FragmentedArray<char[]>(
091: new char[4096]);
092: _contentObjects = new FragmentedArray<Object[]>(
093: new Object[size]);
094:
095: // Set the first element of structure array to indicate an empty buffer
096: // that has not been created
097: _structure.getArray()[0] = AbstractCreatorProcessor.T_END;
098: }
099:
100: /**
101: * Create contents of a buffer from a XMLStreamReader.
102: *
103: * <p>
104: * The MutableXMLStreamBuffer is reset (see {@link #reset}) before creation.
105: *
106: * <p>
107: * The MutableXMLStreamBuffer is created by consuming the events on the XMLStreamReader using
108: * an instance of {@link StreamReaderBufferCreator}.
109: *
110: * @param reader
111: * A XMLStreamReader to read from to create.
112: */
113: public void createFromXMLStreamReader(XMLStreamReader reader)
114: throws XMLStreamException {
115: reset();
116: StreamReaderBufferCreator c = new StreamReaderBufferCreator(
117: this );
118: c.create(reader);
119: }
120:
121: /**
122: * Create contents of a buffer from a XMLStreamWriter.
123: *
124: * <p>
125: * The MutableXMLStreamBuffer is reset (see {@link #reset}) before creation.
126: *
127: * <p>
128: * The MutableXMLStreamBuffer is created by consuming events on a XMLStreamWriter using
129: * an instance of {@link StreamWriterBufferCreator}.
130: */
131: public XMLStreamWriter createFromXMLStreamWriter() {
132: reset();
133: return new StreamWriterBufferCreator(this );
134: }
135:
136: /**
137: * Create contents of a buffer from a {@link SAXBufferCreator}.
138: *
139: * <p>
140: * The MutableXMLStreamBuffer is reset (see {@link #reset}) before creation.
141: *
142: * <p>
143: * The MutableXMLStreamBuffer is created by consuming events from a {@link ContentHandler} using
144: * an instance of {@link SAXBufferCreator}.
145: *
146: * @return The {@link SAXBufferCreator} to create from.
147: */
148: public SAXBufferCreator createFromSAXBufferCreator() {
149: reset();
150: SAXBufferCreator c = new SAXBufferCreator();
151: c.setBuffer(this );
152: return c;
153: }
154:
155: /**
156: * Create contents of a buffer from a {@link XMLReader} and {@link InputStream}.
157: *
158: * <p>
159: * The MutableXMLStreamBuffer is reset (see {@link #reset}) before creation.
160: *
161: * <p>
162: * The MutableXMLStreamBuffer is created by using an instance of {@link SAXBufferCreator}
163: * and registering associated handlers on the {@link XMLReader}.
164: *
165: * @param reader
166: * The {@link XMLReader} to use for parsing.
167: * @param in
168: * The {@link InputStream} to be parsed.
169: */
170: public void createFromXMLReader(XMLReader reader, InputStream in)
171: throws SAXException, IOException {
172: createFromXMLReader(reader, in, null);
173: }
174:
175: /**
176: * Create contents of a buffer from a {@link XMLReader} and {@link InputStream}.
177: *
178: * <p>
179: * The MutableXMLStreamBuffer is reset (see {@link #reset}) before creation.
180: *
181: * <p>
182: * The MutableXMLStreamBuffer is created by using an instance of {@link SAXBufferCreator}
183: * and registering associated handlers on the {@link XMLReader}.
184: *
185: * @param reader
186: * The {@link XMLReader} to use for parsing.
187: * @param in
188: * The {@link InputStream} to be parsed.
189: * @param systemId
190: * The system ID of the input stream.
191: */
192: public void createFromXMLReader(XMLReader reader, InputStream in,
193: String systemId) throws SAXException, IOException {
194: reset();
195: SAXBufferCreator c = new SAXBufferCreator(this );
196:
197: reader.setContentHandler(c);
198: reader.setDTDHandler(c);
199: reader.setProperty(Properties.LEXICAL_HANDLER_PROPERTY, c);
200:
201: c.create(reader, in, systemId);
202: }
203:
204: /**
205: * Reset the MutableXMLStreamBuffer.
206: *
207: * <p>
208: * This method will reset the MutableXMLStreamBuffer to a state of being "uncreated"
209: * similar to the state of a newly instantiated MutableXMLStreamBuffer.
210: *
211: * <p>
212: * As many Objects as possible will be retained for reuse in future creation.
213: */
214: public void reset() {
215: // Reset the ptrs in arrays to 0
216: _structurePtr = _structureStringsPtr = _contentCharactersBufferPtr = _contentObjectsPtr = 0;
217:
218: // Set the first element of structure array to indicate an empty buffer
219: // that has not been created
220: _structure.getArray()[0] = AbstractCreatorProcessor.T_END;
221:
222: // Clean up content objects
223: _contentObjects.setNext(null);
224: final Object[] o = _contentObjects.getArray();
225: for (int i = 0; i < o.length; i++) {
226: if (o[i] != null) {
227: o[i] = null;
228: } else {
229: break;
230: }
231: }
232:
233: treeCount = 0;
234:
235: /*
236: * TODO consider truncating the size of _structureStrings and
237: * _contentCharactersBuffer to limit the memory used by the buffer
238: */
239: }
240:
241: protected void setHasInternedStrings(boolean hasInternedStrings) {
242: _hasInternedStrings = hasInternedStrings;
243: }
244: }
|