All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.harmony.xml.ExpatReader Maven / Gradle / Ivy

/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.harmony.xml;

import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import libcore.io.IoUtils;
import org.xml.sax.ContentHandler;
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;
import org.xml.sax.XMLReader;
import org.xml.sax.ext.LexicalHandler;

/**
 * SAX wrapper around Expat. Interns strings. Does not support validation.
 * Does not support {@link DTDHandler}.
 */
public class ExpatReader implements XMLReader {
    /*
     * ExpatParser accesses these fields directly during parsing. The user
     * should be able to safely change them during parsing.
     */
    /*package*/ ContentHandler contentHandler;
    /*package*/ DTDHandler dtdHandler;
    /*package*/ EntityResolver entityResolver;
    /*package*/ ErrorHandler errorHandler;
    /*package*/ LexicalHandler lexicalHandler;

    private boolean processNamespaces = true;
    private boolean processNamespacePrefixes = false;

    private static final String LEXICAL_HANDLER_PROPERTY
            = "http://xml.org/sax/properties/lexical-handler";

    private static class Feature {
        private static final String BASE_URI = "http://xml.org/sax/features/";
        private static final String VALIDATION = BASE_URI + "validation";
        private static final String NAMESPACES = BASE_URI + "namespaces";
        private static final String NAMESPACE_PREFIXES = BASE_URI + "namespace-prefixes";
        private static final String STRING_INTERNING = BASE_URI + "string-interning";
        private static final String EXTERNAL_GENERAL_ENTITIES
                = BASE_URI + "external-general-entities";
        private static final String EXTERNAL_PARAMETER_ENTITIES
                = BASE_URI + "external-parameter-entities";
    }

    public boolean getFeature(String name)
            throws SAXNotRecognizedException, SAXNotSupportedException {
        if (name == null) {
            throw new NullPointerException("name == null");
        }

        if (name.equals(Feature.VALIDATION)
                || name.equals(Feature.EXTERNAL_GENERAL_ENTITIES)
                || name.equals(Feature.EXTERNAL_PARAMETER_ENTITIES)) {
            return false;
        }

        if (name.equals(Feature.NAMESPACES)) {
            return processNamespaces;
        }

        if (name.equals(Feature.NAMESPACE_PREFIXES)) {
            return processNamespacePrefixes;
        }

        if (name.equals(Feature.STRING_INTERNING)) {
            return true;
        }

        throw new SAXNotRecognizedException(name);
    }

    public void setFeature(String name, boolean value)
            throws SAXNotRecognizedException, SAXNotSupportedException {
        if (name == null) {
            throw new NullPointerException("name == null");
        }

        if (name.equals(Feature.VALIDATION)
                || name.equals(Feature.EXTERNAL_GENERAL_ENTITIES)
                || name.equals(Feature.EXTERNAL_PARAMETER_ENTITIES)) {
            if (value) {
                throw new SAXNotSupportedException("Cannot enable " + name);
            } else {
                // Default.
                return;
            }
        }

        if (name.equals(Feature.NAMESPACES)) {
            processNamespaces = value;
            return;
        }

        if (name.equals(Feature.NAMESPACE_PREFIXES)) {
            processNamespacePrefixes = value;
            return;
        }

        if (name.equals(Feature.STRING_INTERNING)) {
            if (value) {
                // Default.
                return;
            } else {
                throw new SAXNotSupportedException("Cannot disable " + name);
            }
        }

        throw new SAXNotRecognizedException(name);
    }

    public Object getProperty(String name)
            throws SAXNotRecognizedException, SAXNotSupportedException {
        if (name == null) {
            throw new NullPointerException("name == null");
        }

        if (name.equals(LEXICAL_HANDLER_PROPERTY)) {
            return lexicalHandler;
        }

        throw new SAXNotRecognizedException(name);
    }

    public void setProperty(String name, Object value)
            throws SAXNotRecognizedException, SAXNotSupportedException {
        if (name == null) {
            throw new NullPointerException("name == null");
        }

        if (name.equals(LEXICAL_HANDLER_PROPERTY)) {
            // The object must implement LexicalHandler
            if (value instanceof LexicalHandler || value == null) {
                this.lexicalHandler = (LexicalHandler) value;
                return;
            }
            throw new SAXNotSupportedException("value doesn't implement " +
                    "org.xml.sax.ext.LexicalHandler");
        }

        throw new SAXNotRecognizedException(name);
    }

    public void setEntityResolver(EntityResolver resolver) {
        this.entityResolver = resolver;
    }

    public EntityResolver getEntityResolver() {
        return entityResolver;
    }

    public void setDTDHandler(DTDHandler dtdHandler) {
        this.dtdHandler = dtdHandler;
    }

    public DTDHandler getDTDHandler() {
        return dtdHandler;
    }

    public void setContentHandler(ContentHandler handler) {
        this.contentHandler = handler;
    }

    public ContentHandler getContentHandler() {
        return this.contentHandler;
    }

    public void setErrorHandler(ErrorHandler handler) {
        this.errorHandler = handler;
    }

    public ErrorHandler getErrorHandler() {
        return errorHandler;
    }

    /**
     * Returns the current lexical handler.
     *
     * @return the current lexical handler, or null if none has been registered
     * @see #setLexicalHandler
     */
    public LexicalHandler getLexicalHandler() {
        return lexicalHandler;
    }

    /**
     * Registers a lexical event handler. Supports neither
     * {@link LexicalHandler#startEntity(String)} nor
     * {@link LexicalHandler#endEntity(String)}.
     *
     * 

If the application does not register a lexical handler, all * lexical events reported by the SAX parser will be silently * ignored.

* *

Applications may register a new or different handler in the * middle of a parse, and the SAX parser must begin using the new * handler immediately.

* * @param lexicalHandler listens for lexical events * @see #getLexicalHandler() */ public void setLexicalHandler(LexicalHandler lexicalHandler) { this.lexicalHandler = lexicalHandler; } /** * Returns true if this SAX parser processes namespaces. * * @see #setNamespaceProcessingEnabled(boolean) */ public boolean isNamespaceProcessingEnabled() { return processNamespaces; } /** * Enables or disables namespace processing. Set to true by default. If you * enable namespace processing, the parser will invoke * {@link ContentHandler#startPrefixMapping(String, String)} and * {@link ContentHandler#endPrefixMapping(String)}, and it will filter * out namespace declarations from element attributes. * * @see #isNamespaceProcessingEnabled() */ public void setNamespaceProcessingEnabled(boolean processNamespaces) { this.processNamespaces = processNamespaces; } public void parse(InputSource input) throws IOException, SAXException { if (processNamespacePrefixes && processNamespaces) { /* * Expat has XML_SetReturnNSTriplet, but that still doesn't * include xmlns attributes like this feature requires. We may * have to implement namespace processing ourselves if we want * this (not too difficult). We obviously "support" namespace * prefixes if namespaces are disabled. */ throw new SAXNotSupportedException("The 'namespace-prefix' " + "feature is not supported while the 'namespaces' " + "feature is enabled."); } // Try the character stream. Reader reader = input.getCharacterStream(); if (reader != null) { try { parse(reader, input.getPublicId(), input.getSystemId()); } finally { IoUtils.closeQuietly(reader); } return; } // Try the byte stream. InputStream in = input.getByteStream(); String encoding = input.getEncoding(); if (in != null) { try { parse(in, encoding, input.getPublicId(), input.getSystemId()); } finally { IoUtils.closeQuietly(in); } return; } String systemId = input.getSystemId(); if (systemId == null) { throw new SAXException("No input specified."); } // Try the system id. in = ExpatParser.openUrl(systemId); try { parse(in, encoding, input.getPublicId(), systemId); } finally { IoUtils.closeQuietly(in); } } private void parse(Reader in, String publicId, String systemId) throws IOException, SAXException { ExpatParser parser = new ExpatParser( ExpatParser.CHARACTER_ENCODING, this, processNamespaces, publicId, systemId ); parser.parseDocument(in); } private void parse(InputStream in, String charsetName, String publicId, String systemId) throws IOException, SAXException { ExpatParser parser = new ExpatParser(charsetName, this, processNamespaces, publicId, systemId); parser.parseDocument(in); } public void parse(String systemId) throws IOException, SAXException { parse(new InputSource(systemId)); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy