Search in sources :

Example 1 with ConcurrentWriteException

use of org.apache.sis.storage.ConcurrentWriteException in project sis by apache.

the class StaxDataStore method createWriter.

/**
 * Creates a new XML stream writer for writing the XML document.
 * If another {@code XMLStreamWriter} has already been created before this method call,
 * whether this method will succeed in creating a new writer depends on the storage type
 * (e.g. file or output stream).
 *
 * @param  target  the writer which will store the {@code XMLStreamWriter} reference.
 * @return a new writer for writing the XML data.
 * @throws DataStoreException if the output type is not recognized or the data store is closed.
 * @throws XMLStreamException if an error occurred while opening the XML file.
 * @throws IOException if an error occurred while preparing the output stream.
 */
final synchronized XMLStreamWriter createWriter(final StaxStreamWriter target) throws DataStoreException, XMLStreamException, IOException {
    Object outputOrFile = storage;
    if (outputOrFile == null) {
        throw new DataStoreClosedException(getLocale(), getFormatName(), StandardOpenOption.WRITE);
    }
    switch(state) {
        default:
            throw new AssertionError(state);
        case READING:
            throw new ConcurrentReadException(getLocale(), getDisplayName());
        case WRITING:
            throw new ConcurrentWriteException(getLocale(), getDisplayName());
        // Stream already at the data start; nothing to do.
        case START:
            break;
        case FINISHED:
            {
                if (reset())
                    break;
                throw new ForwardOnlyStorageException(getLocale(), getDisplayName(), StandardOpenOption.WRITE);
            }
    }
    /*
         * If the storage given by the user was not one of OutputStream, Writer or other type recognized
         * by OutputType, then maybe that storage was a Path, File or URL, in which case the constructor
         * should have opened an InputStream (not an OutputStream) for it. In some cases (e.g. reading a
         * channel opened on a file), the input stream can be converted to an output stream.
         */
    AutoCloseable output = stream;
    OutputType type = storageToWriter;
    if (type == null) {
        type = OutputType.STREAM;
        output = IOUtilities.toOutputStream(output);
        if (output == null) {
            throw new UnsupportedStorageException(getLocale(), getFormatName(), storage, StandardOpenOption.WRITE);
        }
        outputOrFile = output;
        if (output != stream) {
            stream = output;
            mark();
        }
    }
    XMLStreamWriter writer = type.create(this, outputOrFile);
    if (indentation >= 0) {
        writer = new FormattedWriter(writer, indentation);
    }
    target.stream = output;
    state = WRITING;
    return writer;
}
Also used : ConcurrentWriteException(org.apache.sis.storage.ConcurrentWriteException) DataStoreClosedException(org.apache.sis.storage.DataStoreClosedException) XMLStreamWriter(javax.xml.stream.XMLStreamWriter) ForwardOnlyStorageException(org.apache.sis.storage.ForwardOnlyStorageException) UnsupportedStorageException(org.apache.sis.storage.UnsupportedStorageException) ConcurrentReadException(org.apache.sis.storage.ConcurrentReadException)

Example 2 with ConcurrentWriteException

use of org.apache.sis.storage.ConcurrentWriteException in project sis by apache.

the class StaxDataStore method createReader.

/**
 * Creates a new XML stream reader for reading the document from its position at {@code StaxDataStore}
 * creation time. If another {@code XMLStreamReader} has already been created before this method call,
 * whether this method will succeed in creating a new reader depends on the storage type (e.g. file or
 * input stream) or on whether the previous reader has been closed.
 *
 * @param  target  the reader which will store the {@code XMLStreamReader} reference.
 * @return a new reader for reading the XML data.
 * @throws DataStoreException if the input type is not recognized or the data store is closed.
 * @throws XMLStreamException if an error occurred while opening the XML file.
 * @throws IOException if an error occurred while preparing the input stream.
 * @throws Exception if another kind of error occurred while closing a previous stream.
 */
@SuppressWarnings("fallthrough")
final synchronized XMLStreamReader createReader(final StaxStreamReader target) throws Exception {
    Object inputOrFile = storage;
    if (inputOrFile == null) {
        throw new DataStoreClosedException(getLocale(), getFormatName(), StandardOpenOption.READ);
    }
    AutoCloseable input = stream;
    InputType type = storageToReader;
    /*
         * If the stream has already been used by a previous read operation, then we need to rewind
         * it to the start position determined at construction time. It the stream does not support
         * mark, then we can not re-read the data unless we know how to create new input streams.
         */
    switch(state) {
        default:
            throw new AssertionError(state);
        case WRITING:
            throw new ConcurrentWriteException(getLocale(), getDisplayName());
        // Stream already at the data start; nothing to do.
        case START:
            break;
        case FINISHED:
            {
                // If we can reuse existing stream, nothing more to do.
                if (reset())
                    break;
                if (input != null) {
                    // Cleared first in case of error during 'close()' call.
                    stream = null;
                    input.close();
                    input = null;
                }
            // Fall through for trying to create a new input stream.
            }
        case READING:
            {
                /*
                 * If the input stream is in use, or if we finished to use it but were unable to reset its position,
                 * then we need to create a new input stream (except if the input was a DOM in memory, which we can
                 * share). The 'target' StaxStreamReader will be in charge of closing that stream.
                 */
                if (type != InputType.NODE) {
                    final String name = getDisplayName();
                    if (channelFactory == null) {
                        throw new ForwardOnlyStorageException(getLocale(), name, StandardOpenOption.READ);
                    }
                    inputOrFile = input = channelFactory.inputStream(name, listeners);
                    type = InputType.STREAM;
                    if (stream == null) {
                        stream = input;
                        state = START;
                        mark();
                    }
                }
                break;
            }
    }
    /*
         * At this point we verified there is no write operation in progress and that the input stream (if not null)
         * is available for our use. Now we need to build a XMLStreamReader from that input. This is InputType work,
         * but that type may be null if the storage given by the user was not an InputStream, Reader or other types
         * recognized by InputType. In such case there is two possibilities:
         *
         *   - It may be an OutputStream, Writer or other types recognized by OutputType.
         *   - It may be a Path, File, URL or URI, which are intentionally not handled by Input/OutputType.
         */
    if (type == null) {
        if (storageToWriter != null) {
            final Closeable snapshot = storageToWriter.snapshot(inputOrFile);
            if (snapshot != null) {
                // Do not set state to READING since the input in this block is a copy of data.
                final XMLStreamReader reader = storageToWriter.inputType.create(this, snapshot);
                target.stream = snapshot;
                return reader;
            }
        }
        /*
             * Maybe that storage was a Path, File or URL, in which case the constructor should have opened an
             * InputStream for it. If not, then this was an unsupported storage type. However the input stream
             * may have been converted to an output stream during a write operation, in which case we need to
             * convert it back to an input stream.
             */
        type = InputType.STREAM;
        input = IOUtilities.toInputStream(input);
        if (input == null) {
            throw new UnsupportedStorageException(getLocale(), getFormatName(), storage, StandardOpenOption.READ);
        }
        inputOrFile = input;
        if (input != stream) {
            stream = input;
            mark();
        }
    }
    final XMLStreamReader reader = type.create(this, inputOrFile);
    target.stream = input;
    state = READING;
    return reader;
}
Also used : ConcurrentWriteException(org.apache.sis.storage.ConcurrentWriteException) XMLStreamReader(javax.xml.stream.XMLStreamReader) DataStoreClosedException(org.apache.sis.storage.DataStoreClosedException) Closeable(java.io.Closeable) ForwardOnlyStorageException(org.apache.sis.storage.ForwardOnlyStorageException) UnsupportedStorageException(org.apache.sis.storage.UnsupportedStorageException)

Aggregations

ConcurrentWriteException (org.apache.sis.storage.ConcurrentWriteException)2 DataStoreClosedException (org.apache.sis.storage.DataStoreClosedException)2 ForwardOnlyStorageException (org.apache.sis.storage.ForwardOnlyStorageException)2 UnsupportedStorageException (org.apache.sis.storage.UnsupportedStorageException)2 Closeable (java.io.Closeable)1 XMLStreamReader (javax.xml.stream.XMLStreamReader)1 XMLStreamWriter (javax.xml.stream.XMLStreamWriter)1 ConcurrentReadException (org.apache.sis.storage.ConcurrentReadException)1