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

org.eigenbase.xom.wrappers.GenericDOMParser Maven / Gradle / Ivy

The newest version!
/*
// Licensed to Julian Hyde under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// Julian Hyde licenses this file to you 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.eigenbase.xom.wrappers;

import org.eigenbase.xom.*;
import org.w3c.dom.*;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import java.io.*;
import java.net.URL;

/**
 * A GenericDOMParser is an abstract base class for {@link
 * XercesDOMParser} and {@link JaxpDOMParser}.
 *
 * @author jhyde
 */
abstract class GenericDOMParser
    implements ErrorHandler, org.eigenbase.xom.Parser, Locator
{

    // Used for capturing error messages as they occur.
    StringWriter errorBuffer = null;
    PrintWriter errorOut = null;

    /** The document which spawns elements. The constructor of the derived
     * class must set this. */
    protected Document document;

    static final String LOAD_EXTERNAL_DTD_FEATURE =
            "http://apache.org/xml/features/nonvalidating/load-external-dtd";
    static final String VALIDATION_FEATURE =
            "http://xml.org/sax/features/validation";
    private boolean keepPositions;
    private Annotator annotator;

    public DOMWrapper create(String tagName) {
        Element element = document.createElement(tagName);
        return new W3CDOMWrapper(element, this);
    }

    public DOMWrapper parse(InputStream is) throws XOMException {
        TeeInputStream tis = new TeeInputStream(is);
        InputSource source = new InputSource(tis);
        Document document = parseInputSource(source);
        final W3CDOMWrapper wrapper =
            new W3CDOMWrapper(document.getDocumentElement(), this);
        if (keepPositions) {
            String xmlString = new String(tis.getBytes());
            annotator = new Annotator(xmlString, wrapper);
        }
        return wrapper;
    }

    public void setKeepPositions(boolean keepPositions) {
        this.keepPositions = keepPositions;
    }

    public boolean isKeepPositions() {
        return keepPositions;
    }

    public DOMWrapper parse(String xmlString) throws XOMException {
        final DOMWrapper wrapper = parse(new StringReader(xmlString));
        if (keepPositions) {
            annotator = new Annotator(xmlString, wrapper);
        }
        return wrapper;
    }

    public DOMWrapper parse(Reader reader) throws XOMException {
        Document document = parseInputSource(new InputSource(reader));
        return new W3CDOMWrapper(document.getDocumentElement(), this);
    }

    /**
     * Parses the specified URI and returns the document.
     * @param in Input source
     * @return Document
     * @throws org.eigenbase.xom.XOMException on error
     */
    protected abstract Document parseInputSource(InputSource in)
            throws XOMException;

    /** Warning. */
    public void warning(SAXParseException ex) {
        errorOut.println("[Warning] " +
                getLocationString(ex) + ": " +
                ex.getMessage());
    }

    /** Error. */
    public void error(SAXParseException ex) {
        errorOut.println("[Error] " +
                getLocationString(ex) + ": " +
                ex.getMessage());
    }

    /** Fatal error. */
    public void fatalError(SAXParseException ex)
            throws SAXException {
        errorOut.println("[Fatal Error] " +
                getLocationString(ex) + ": " +
                ex.getMessage());
        throw ex;
    }

    /** Returns a string of the location.
     * @param ex Exception
     * @return Location string, e.g. "file.xml:4:72"
     */
    private String getLocationString(SAXParseException ex) {
        StringBuffer str = new StringBuffer();

        String systemId = ex.getSystemId();
        if (systemId != null) {
            int index = systemId.lastIndexOf('/');
            if (index != -1) {
                systemId = systemId.substring(index + 1);
            }
            str.append(systemId);
        }
        str.append(':');
        str.append(ex.getLineNumber());
        str.append(':');
        str.append(ex.getColumnNumber());
        return str.toString();
    }

    // implement Parser
    public DOMWrapper parse(URL url)
            throws XOMException {
        try {
            return parse(new BufferedInputStream(url.openStream()));
        } catch (IOException ex) {
            throw new XOMException(ex, "Document parse failed");
        }
    }

    // Helper: reset the error buffer to prepare for a new parse.
    protected void prepareParse() {
        errorBuffer = new StringWriter();
        errorOut = new PrintWriter(errorBuffer);
    }

    // Helper: throw an exception with messages of any errors
    // accumulated during the parse.
    protected void handleErrors() throws XOMException {
        errorOut.flush();
        String errorStr = errorBuffer.toString();
        if (errorStr.length() > 0) {
            throw new XOMException("Document parse failed: " + errorStr);
        }
    }

    // implement Locator
    public Location getLocation(DOMWrapper wrapper) {
        return annotator.getLocation(wrapper);
    }

    /**
     * Input stream that keeps a copy of every byte that flows through it.
     */
    private static class TeeInputStream extends FilterInputStream {
        private final ByteArrayOutputStream baos = new ByteArrayOutputStream();

        TeeInputStream(InputStream in) {
            super(in);
        }

        public int read() throws IOException {
            int x = super.read();
            baos.write(x);
            return x;
        }

        /**
         * Returns the bytes that have been read from this stream.
         *
         * @return Array of bytes that have been read from this stream
         */
        public byte[] getBytes() {
            return baos.toByteArray();
        }
    }
}

// End GenericDOMParser.java




© 2015 - 2024 Weber Informatics LLC | Privacy Policy