Package javolution.xml.sax

Source Code of javolution.xml.sax.XMLReaderImpl

/*
* Javolution - Java(TM) Solution for Real-Time and Embedded Systems
* Copyright (C) 2012 - Javolution (http://javolution.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javolution.xml.sax;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.net.URL;
import javolution.text.CharArray;
import javolution.xml.internal.stream.XMLStreamReaderImpl;
import javolution.xml.stream.XMLStreamConstants;
import javolution.xml.stream.XMLStreamException;
import org.xml.sax.DTDHandler;
import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;

/**
* <p> This class provides a real-time SAX2-like XML parser; this parser is
*     <i>extremely</i> fast and <b>does not create temporary objects</b>
*     (no garbage generated and no GC interruption).</p>
*    
* <p> The parser is implemented as a SAX2 wrapper around 
*     {@link XMLStreamReaderImpl} and share the same characteristics.</p>
*
* <p><i> Note: This parser is a <b>SAX2-like</b> parser with the
*        <code>java.lang.String</code> type replaced by
*        {@link CharArray}/{@link CharSequence} in the {@link ContentHandler},
*       {@link Attributes} interfaces and {@link DefaultHandler} base class.
*       If a standard SAX2 or JAXP parser is required, you may consider using
*       the wrapping class {@link SAX2ReaderImpl}. Fast but not as fast as
*       <code>java.lang.String</code> instances are dynamically allocated
*       while parsing.</i></p>
*
* @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 4.0, June 16, 2006
*/
public class XMLReaderImpl implements XMLReader {

    /**
     * Holds the default handler instance.
     */
    private static DefaultHandler DEFAULT_HANDLER = new DefaultHandler();

    /**
     * Holds the content handler.
     */
    private ContentHandler _contentHandler;

    /**
     * Holds the error handler.
     */
    private ErrorHandler _errorHandler;

    /**
     * Holds reusable StAX reader.
     */
    private final XMLStreamReaderImpl _xmlReader = new XMLStreamReaderImpl();

    /**
     * Default constructor.
     */
    public XMLReaderImpl() {
        // Sets default handlers.
        setContentHandler(DEFAULT_HANDLER);
        setErrorHandler(DEFAULT_HANDLER);
    }

    /**
     * Parses an XML document from the specified input stream
     * (encoding retrieved from input source and the XML prolog if any).
     *
     * @param in the input stream with unknown encoding.
     * @throws org.xml.sax.SAXException any SAX exception, possibly
     *         wrapping another exception.
     * @throws IOException an IO exception from the parser,
     *         possibly from a byte stream or character stream
     *         supplied by the application.
     */
    public void parse(InputStream in) throws IOException, SAXException {
        try {
            _xmlReader.setInput(in);
            parseAll();
        } catch (XMLStreamException e) {
            if (e.getNestedException() instanceof IOException)
                throw (IOException) e.getNestedException();
            throw new SAXException(e.getMessage());
        } finally {
            _xmlReader.reset();
        }
    }

    /**
     * Parses an XML document from the specified input stream and encoding.
     *
     * @param in the input stream.
     * @param encoding the input stream encoding.
     * @throws org.xml.sax.SAXException any SAX exception, possibly
     *         wrapping another exception.
     * @throws IOException an IO exception from the parser,
     *         possibly from a byte stream or character stream
     *         supplied by the application.
     */
    public void parse(InputStream in, String encoding) throws IOException,
            SAXException {
        try {
            _xmlReader.setInput(in, encoding);
            parseAll();
        } catch (XMLStreamException e) {
            if (e.getNestedException() instanceof IOException)
                throw (IOException) e.getNestedException();
            throw new SAXException(e.getMessage());
        } finally {
            _xmlReader.reset();
        }
    }

    /**
     * Parses an XML document using the specified reader.
     *
     * @param  reader the document reader.
     * @throws SAXException any SAX exception, possibly wrapping another
     *         exception.
     * @throws IOException an IO exception from the parser, possibly from
     *         a byte stream or character stream supplied by the application.
     * @see    javolution.io.UTF8StreamReader
     * @see    javolution.io.UTF8ByteBufferReader
     * @see    javolution.io.CharSequenceReader
     */
    public void parse(Reader reader) throws IOException, SAXException {
        try {
            _xmlReader.setInput(reader);
            parseAll();
        } catch (XMLStreamException e) {
            if (e.getNestedException() instanceof IOException)
                throw (IOException) e.getNestedException();
            throw new SAXException(e.getMessage());
        } finally {
            _xmlReader.reset();
        }
    }

    // Implements XMLReader interface.
    public void parse(InputSource input) throws IOException, SAXException {
        Reader reader = input.getCharacterStream();
        if (reader != null) {
            parse(reader);
        } else {
            InputStream inStream = input.getByteStream();
            if (inStream != null) {
                parse(inStream, input.getEncoding());
            } else {
                parse(input.getSystemId());
            }
        }
    }

    // Implements XMLReader interface.
    public void parse(String systemId) throws IOException, SAXException {
        InputStream inStream;
        try {
            URL url = new URL(systemId);
            inStream = url.openStream();
        } catch (Exception urlException) { // Try as filename.
            try {
                inStream = new FileInputStream(systemId);
            } catch (Exception fileException) {
                throw new UnsupportedOperationException("Cannot parse "
                        + systemId);
            }
        }
        parse(inStream);
    }

    // Implements XMLReader interface.
    public void setContentHandler(ContentHandler handler) {
        if (handler != null) {
            _contentHandler = handler;
        } else {
            throw new NullPointerException();
        }
    }

    // Implements XMLReader interface.
    public ContentHandler getContentHandler() {
        return (_contentHandler == DEFAULT_HANDLER) ? null : _contentHandler;
    }

    // Implements XMLReader interface.
    public void setErrorHandler(ErrorHandler handler) {
        if (handler != null) {
            _errorHandler = handler;
        } else {
            throw new NullPointerException();
        }
    }

    // Implements XMLReader interface.
    public ErrorHandler getErrorHandler() {
        return (_errorHandler == DEFAULT_HANDLER) ? null : _errorHandler;
    }

    // Implements XMLReader interface.
    public boolean getFeature(String name) throws SAXNotRecognizedException,
            SAXNotSupportedException {
        if (name.equals("http://xml.org/sax/features/namespaces")) {
            return true;
        } else if (name
                .equals("http://xml.org/sax/features/namespace-prefixes")) {
            return true;
        } else {
            throw new SAXNotRecognizedException("Feature " + name
                    + " not recognized");
        }
    }

    public void setFeature(String name, boolean value)
            throws SAXNotRecognizedException, SAXNotSupportedException {
        if (name.equals("http://xml.org/sax/features/namespaces")
                || name.equals("http://xml.org/sax/features/namespace-prefixes")) {
            return; // Ignores, these features are always set.
        } else {
            throw new SAXNotRecognizedException("Feature " + name
                    + " not recognized");
        }
    }

    public Object getProperty(String name) throws SAXNotRecognizedException,
            SAXNotSupportedException {
        throw new SAXNotRecognizedException("Property " + name
                + " not recognized");
    }

    public void setProperty(String name, Object value)
            throws SAXNotRecognizedException, SAXNotSupportedException {
        throw new SAXNotRecognizedException("Property " + name
                + " not recognized");
    }

    public void setEntityResolver(EntityResolver resolver) {
        _entityResolver = resolver;
    }

    private EntityResolver _entityResolver;

    public EntityResolver getEntityResolver() {
        return _entityResolver;
    }

    public void setDTDHandler(DTDHandler handler) {
        _dtdHandler = handler;
    }

    private DTDHandler _dtdHandler;

    public DTDHandler getDTDHandler() {
        return _dtdHandler;
    }

    // Implements Reusable.
    public void reset() {
        setContentHandler(DEFAULT_HANDLER);
        setErrorHandler(DEFAULT_HANDLER);
        _xmlReader.reset();
    }

    /**
     * Parses the whole document using the real-time pull parser.
     *
     * @throws SAXException any SAX exception, possibly wrapping another
     *         exception.
     * @throws IOException an IO exception from the parser, possibly from
     *         a byte stream or character stream supplied by the application.
     */
    private void parseAll() throws XMLStreamException, SAXException {
        int eventType = _xmlReader.getEventType();
        if (eventType != XMLStreamConstants.START_DOCUMENT)
            throw new SAXException("Currently parsing");
        _contentHandler.startDocument();

        boolean doContinue = true;
        while (doContinue) {
            CharArray uri, localName, qName, prefix, text;
            switch (_xmlReader.next()) {
                case XMLStreamConstants.START_ELEMENT:

                    // Start prefix mapping.
                    for (int i = 0, count = _xmlReader.getNamespaceCount(); i < count; i++) {
                        prefix = _xmlReader.getNamespacePrefix(i);
                        prefix = (prefix == null) ? NO_CHAR : prefix; // Default namespace is ""
                        uri = _xmlReader.getNamespaceURI(i);
                        _contentHandler.startPrefixMapping(prefix, uri);
                    }

                    // Start element.
                    uri = _xmlReader.getNamespaceURI();
                    uri = (uri == null) ? NO_CHAR : uri;
                    localName = _xmlReader.getLocalName();
                    qName = _xmlReader.getQName();
                    _contentHandler.startElement(uri, localName, qName,
                            _xmlReader.getAttributes());
                    break;

                case XMLStreamConstants.END_ELEMENT:

                    // End element.
                    uri = _xmlReader.getNamespaceURI();
                    uri = (uri == null) ? NO_CHAR : uri;
                    localName = _xmlReader.getLocalName();
                    qName = _xmlReader.getQName();
                    _contentHandler.endElement(uri, localName, qName);

                    // End prefix mapping.
                    for (int i = 0, count = _xmlReader.getNamespaceCount(); i < count; i++) {
                        prefix = _xmlReader.getNamespacePrefix(i);
                        prefix = (prefix == null) ? NO_CHAR : prefix; // Default namespace is ""
                        _contentHandler.endPrefixMapping(prefix);
                    }
                    break;

                case XMLStreamConstants.CDATA:
                case XMLStreamConstants.CHARACTERS:
                    text = _xmlReader.getText();
                    _contentHandler.characters(text.array(), text.offset(),
                            text.length());
                    break;

                case XMLStreamConstants.SPACE:
                    text = _xmlReader.getText();
                    _contentHandler.ignorableWhitespace(text.array(),
                            text.offset(), text.length());
                    break;

                case XMLStreamConstants.PROCESSING_INSTRUCTION:
                    _contentHandler.processingInstruction(
                            _xmlReader.getPITarget(), _xmlReader.getPIData());
                    break;

                case XMLStreamConstants.COMMENT:
                    // Ignores.
                    break;

                case XMLStreamConstants.END_DOCUMENT:
                    doContinue = false;
                    _xmlReader.close();
                    break;

            }
        }
    }

    private static final CharArray NO_CHAR = new CharArray("");
}
TOP

Related Classes of javolution.xml.sax.XMLReaderImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.