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.sax;
021:
022: import com.sun.xml.stream.buffer.AbstractCreator;
023: import org.xml.sax.Attributes;
024: import org.xml.sax.SAXException;
025: import com.sun.xml.stream.buffer.MutableXMLStreamBuffer;
026: import java.io.IOException;
027: import java.io.InputStream;
028: import org.xml.sax.ContentHandler;
029: import org.xml.sax.DTDHandler;
030: import org.xml.sax.EntityResolver;
031: import org.xml.sax.ErrorHandler;
032: import org.xml.sax.InputSource;
033: import org.xml.sax.Locator;
034: import org.xml.sax.SAXParseException;
035: import org.xml.sax.XMLReader;
036: import org.xml.sax.ext.LexicalHandler;
037:
038: /**
039: * Writes into {@link MutableXMLStreamBuffer} from SAX.
040: *
041: * TODO
042: * Implement the marking the stream on the element when an ID
043: * attribute on the element is defined
044: */
045: public class SAXBufferCreator extends AbstractCreator implements
046: EntityResolver, DTDHandler, ContentHandler, ErrorHandler,
047: LexicalHandler {
048: protected String[] _namespaceAttributes;
049:
050: protected int _namespaceAttributesPtr;
051:
052: private int depth = 0;
053:
054: public SAXBufferCreator() {
055: _namespaceAttributes = new String[16 * 2];
056: }
057:
058: public SAXBufferCreator(MutableXMLStreamBuffer buffer) {
059: this ();
060: setBuffer(buffer);
061: }
062:
063: public MutableXMLStreamBuffer create(XMLReader reader,
064: InputStream in) throws IOException, SAXException {
065: return create(reader, in, null);
066: }
067:
068: public MutableXMLStreamBuffer create(XMLReader reader,
069: InputStream in, String systemId) throws IOException,
070: SAXException {
071: if (_buffer == null) {
072: createBuffer();
073: }
074: _buffer.setSystemId(systemId);
075: reader.setContentHandler(this );
076: reader.setProperty(Properties.LEXICAL_HANDLER_PROPERTY, this );
077:
078: try {
079: setHasInternedStrings(reader
080: .getFeature(Features.STRING_INTERNING_FEATURE));
081: } catch (SAXException e) {
082: }
083:
084: if (systemId != null) {
085: InputSource s = new InputSource(systemId);
086: s.setByteStream(in);
087: reader.parse(s);
088: } else {
089: reader.parse(new InputSource(in));
090: }
091:
092: return getXMLStreamBuffer();
093: }
094:
095: public void reset() {
096: _buffer = null;
097: _namespaceAttributesPtr = 0;
098: depth = 0;
099: }
100:
101: public void startDocument() throws SAXException {
102: storeStructure(T_DOCUMENT);
103: }
104:
105: public void endDocument() throws SAXException {
106: storeStructure(T_END);
107: }
108:
109: public void startPrefixMapping(String prefix, String uri)
110: throws SAXException {
111: cacheNamespaceAttribute(prefix, uri);
112: }
113:
114: public void startElement(String uri, String localName,
115: String qName, Attributes attributes) throws SAXException {
116: storeQualifiedName(T_ELEMENT_LN, uri, localName, qName);
117:
118: // Has namespaces attributes
119: if (_namespaceAttributesPtr > 0) {
120: storeNamespaceAttributes();
121: }
122:
123: // Has attributes
124: if (attributes.getLength() > 0) {
125: storeAttributes(attributes);
126: }
127: depth++;
128: }
129:
130: public void endElement(String uri, String localName, String qName)
131: throws SAXException {
132: storeStructure(T_END);
133: if (--depth == 0)
134: increaseTreeCount(); // one tree processed
135: }
136:
137: public void characters(char ch[], int start, int length)
138: throws SAXException {
139: storeContentCharacters(T_TEXT_AS_CHAR_ARRAY, ch, start, length);
140: }
141:
142: public void ignorableWhitespace(char ch[], int start, int length)
143: throws SAXException {
144: characters(ch, start, length);
145: }
146:
147: public void processingInstruction(String target, String data)
148: throws SAXException {
149: storeStructure(T_PROCESSING_INSTRUCTION);
150: storeStructureString(target);
151: storeStructureString(data);
152: }
153:
154: public void comment(char[] ch, int start, int length)
155: throws SAXException {
156: storeContentCharacters(T_COMMENT_AS_CHAR_ARRAY, ch, start,
157: length);
158: }
159:
160: //
161:
162: private void cacheNamespaceAttribute(String prefix, String uri) {
163: _namespaceAttributes[_namespaceAttributesPtr++] = prefix;
164: _namespaceAttributes[_namespaceAttributesPtr++] = uri;
165:
166: if (_namespaceAttributesPtr == _namespaceAttributes.length) {
167: final String[] namespaceAttributes = new String[_namespaceAttributesPtr * 2];
168: System.arraycopy(_namespaceAttributes, 0,
169: namespaceAttributes, 0, _namespaceAttributesPtr);
170: _namespaceAttributes = namespaceAttributes;
171: }
172: }
173:
174: private void storeNamespaceAttributes() {
175: for (int i = 0; i < _namespaceAttributesPtr; i += 2) {
176: int item = T_NAMESPACE_ATTRIBUTE;
177: if (_namespaceAttributes[i].length() > 0) {
178: item |= FLAG_PREFIX;
179: storeStructureString(_namespaceAttributes[i]);
180: }
181: if (_namespaceAttributes[i + 1].length() > 0) {
182: item |= FLAG_URI;
183: storeStructureString(_namespaceAttributes[i + 1]);
184: }
185: storeStructure(item);
186: }
187: _namespaceAttributesPtr = 0;
188: }
189:
190: private void storeAttributes(Attributes attributes) {
191: for (int i = 0; i < attributes.getLength(); i++) {
192: storeQualifiedName(T_ATTRIBUTE_LN, attributes.getURI(i),
193: attributes.getLocalName(i), attributes.getQName(i));
194:
195: storeStructureString(attributes.getType(i));
196: storeContentString(attributes.getValue(i));
197: }
198: }
199:
200: private void storeQualifiedName(int item, String uri,
201: String localName, String qName) {
202: if (uri.length() > 0) {
203: item |= FLAG_URI;
204: storeStructureString(uri);
205: }
206:
207: storeStructureString(localName);
208:
209: if (qName.indexOf(':') >= 0) {
210: item |= FLAG_QUALIFIED_NAME;
211: storeStructureString(qName);
212: }
213:
214: storeStructure(item);
215: }
216:
217: // Empty methods for SAX handlers
218:
219: // Entity resolver handler
220:
221: public InputSource resolveEntity(String publicId, String systemId)
222: throws IOException, SAXException {
223: return null;
224: }
225:
226: // DTD handler
227:
228: public void notationDecl(String name, String publicId,
229: String systemId) throws SAXException {
230: }
231:
232: public void unparsedEntityDecl(String name, String publicId,
233: String systemId, String notationName) throws SAXException {
234: }
235:
236: // Content handler
237:
238: public void setDocumentLocator(Locator locator) {
239: }
240:
241: public void endPrefixMapping(String prefix) throws SAXException {
242: }
243:
244: public void skippedEntity(String name) throws SAXException {
245: }
246:
247: // Lexical handler
248:
249: public void startDTD(String name, String publicId, String systemId)
250: throws SAXException {
251: }
252:
253: public void endDTD() throws SAXException {
254: }
255:
256: public void startEntity(String name) throws SAXException {
257: }
258:
259: public void endEntity(String name) throws SAXException {
260: }
261:
262: public void startCDATA() throws SAXException {
263: }
264:
265: public void endCDATA() throws SAXException {
266: }
267:
268: // Error handler
269:
270: public void warning(SAXParseException e) throws SAXException {
271: }
272:
273: public void error(SAXParseException e) throws SAXException {
274: }
275:
276: public void fatalError(SAXParseException e) throws SAXException {
277: throw e;
278: }
279: }
|