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

org.enhydra.xml.io.ClosingInputSource Maven / Gradle / Ivy

The newest version!
/*
 * Enhydra Java Application Server Project
 * 
 * The contents of this file are subject to the Enhydra Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License on
 * the Enhydra web site ( http://www.enhydra.org/ ).
 * 
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 
 * the License for the specific terms governing rights and limitations
 * under the License.
 * 
 * The Initial Developer of the Enhydra Application Server is Lutris
 * Technologies, Inc. The Enhydra Application Server and portions created
 * by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
 * All Rights Reserved.
 * 
 * Contributor(s):
 * 
 * $Id: ClosingInputSource.java,v 1.2 2005/01/26 08:29:24 jkjome Exp $
 */

package org.enhydra.xml.io;

import java.io.FilterInputStream;
import java.io.FilterReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;

import org.xml.sax.InputSource;

/**
 * Input source that automatically close its InputStream when EOF is reached
 * or an error occurs.  This works around a flaw in the SAX API where there is
 * not method of an entity handler that opens a stream to be informed when the
 * stream is no longer needed.
 */
public class ClosingInputSource extends InputSource {
    /**
     * InputStream that closes on EOF or read error.
     */
    private class ClosingInputStream extends FilterInputStream {
        /**
         * Constructor
         */
        public ClosingInputStream(InputStream stream) {
            super(stream);
        }

        /**
         * Read a byte from the stream.
         */
        public int read() throws IOException {
            try {
                int bt = super.read();
                if (bt < 0) {
                    close();
                }
                return bt;
            } catch (IOException except) {
                close();
                throw except;
            }
        }

        /**
         * Read bytes from the stream.
         */
        public int read(byte[] bBuf, int off, int len) throws IOException {
            try {
                int readLen = super.read(bBuf, off, len);
                if (readLen < 0) {
                    close();
                }
                return readLen;
            } catch (IOException except) {
                close();
                throw except;
            }
        }
    }
 
    /**
     * Reader that closes on EOF or read error.
     */
    private class ClosingReader extends FilterReader {
        /**
         * Constructor
         */
        public ClosingReader(Reader stream) {
            super(stream);
        }

        /**
         * Read a character from the stream.
         */
        public int read() throws IOException {
            try {
                int ch = super.read();
                if (ch < 0) {
                    close();
                }
                return ch;
            } catch (IOException except) {
                close();
                throw except;
            }
        }

        /**
         * Read characters from the stream.
         */
        public int read(char[] cBuf, int off, int len) throws IOException {
            try {
                int readLen = super.read(cBuf, off, len);
                if (readLen < 0) {
                    close();
                }
                return readLen;
            } catch (IOException except) {
                close();
                throw except;
            }
        }
    }
 
    /**
     * If the resource is specified by system id, open it now as a byte
     * stream.  If the resource is specified by byte or character stream, this
     * does nothing.
     */
    public void open() throws IOException {
        if ((getByteStream() == null) && (getCharacterStream() == null)) {
            String systemId = getSystemId();
            if (systemId == null) {
                throw new IOException("systemId is not set");
            }
            setByteStream(InputSourceOps.openSystemId(systemId));
        }
    }

    /**
     * Zero-argument default constructor.
     * @see InputSource#InputSource
     */
    public ClosingInputSource() {
        super();
    }
    
    /**
     * Create a new input source from another input source.
     *
     * @param inputSource Input source specification to clone
     * @param openNow If true, the input source is opened immediatly 
     *        if specified as a system id.
     * @see InputSource
     */
    public ClosingInputSource(InputSource inputSource,
                              boolean openNow) throws IOException {
        if (inputSource.getByteStream() != null) {
            super.setByteStream(new ClosingInputStream(inputSource.getByteStream()));
        } else if (inputSource.getCharacterStream() != null) {
            super.setCharacterStream(new ClosingReader(inputSource.getCharacterStream()));
        } else if (inputSource.getSystemId() != null) {
            super.setSystemId(inputSource.getSystemId());
            if (openNow) {
                open();
            }
        } else {
            throw new IOException("InputSource does not specify an external source of input");
        }

        // Fill in public and system ids and encoding
        if (inputSource.getPublicId() != null) {
            super.setPublicId(inputSource.getPublicId());
        }
        if (inputSource.getSystemId() != null) {
            super.setSystemId(inputSource.getSystemId());
        }
    }

    /**
     * Create a new input source with a system identifier.
     *
     * @param systemId The system identifier.
     * @see InputSource#InputSource(String)
     */
    public ClosingInputSource(String systemId) {
        super(systemId);
    }

    /**
     * Create a new input source with a system identifier.
     *
     * @param systemId The system identifier.
     * @param openNow If true, the input source is opened immediatly 
     *        if specified as a system id.
     * @exception IOException If an error occures opening the stream.
     * @see InputSource#InputSource(String)
     */
    public ClosingInputSource(String systemId,
                              boolean openNow) throws IOException {
        super(systemId);
        if (openNow) {
            open();
        }
    }

    /**
     * Create a new input source with a byte stream.
     * @see InputSource#InputSource(InputStream)
     */
    public ClosingInputSource(InputStream byteStream) {
        super();
        setByteStream(byteStream);
    }
    
    /**
     * Create a new input source with a character stream.
     * @see InputSource#InputSource(Reader)
     */
    public ClosingInputSource(Reader characterStream) {
        super();
        setCharacterStream(characterStream);
    }

    /**
     * Set the byte stream, copying it to a buffer.
     * @see InputSource#setByteStream
     */
    public void setByteStream(InputStream byteStream) {
        super.setByteStream(new ClosingInputStream(byteStream));
    }

    /**
     * Set the character stream, copying it to a buffer.
     * @see InputSource#setCharacterStream
     */
    public void setCharacterStream(Reader characterStream) {
        super.setCharacterStream(new ClosingReader(characterStream));
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy