Search in sources :

Example 1 with DataStoreException

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

the class FolderStoreProvider method open.

/**
 * Shared implementation of public {@code open(…)} methods.
 * Note that this method may modify the given {@code options} set for its own purpose.
 *
 * @param  connector  information about the storage (URL, path, <i>etc</i>).
 * @param  format     format name for directory content, or {@code null} if unspecified.
 * @param  options    whether to create a new directory, overwrite existing content, <i>etc</i>.
 */
private DataStore open(final StorageConnector connector, final String format, final EnumSet<StandardOpenOption> options) throws DataStoreException {
    /*
         * Determine now the provider to use for directory content. We do that for determining if the component
         * has write capability. If not, then the WRITE, CREATE and related options will be ignored.  If we can
         * not determine whether the component store has write capabilities (i.e. if canWrite(…) returns null),
         * assume that the answer is "yes".
         */
    final DataStoreProvider componentProvider;
    if (format != null) {
        componentProvider = StoreUtilities.providerByFormatName(format.trim());
        if (Boolean.FALSE.equals(StoreUtilities.canWrite(componentProvider.getClass()))) {
            // No write capability.
            options.clear();
        }
    } else {
        componentProvider = null;
        // Can not write if we don't know the components format.
        options.clear();
    }
    final Path path = connector.getStorageAs(Path.class);
    final Store store;
    try {
        /*
             * If the user asked to create a new directory, we need to perform this task before
             * to create the Store (otherwise constructor will fail with NoSuchFileException).
             * In the particular case of CREATE_NEW, we unconditionally attempt to create the
             * directory in order to rely on the atomic check performed by Files.createDirectory(…).
             */
        boolean isNew = false;
        if (options.contains(StandardOpenOption.CREATE)) {
            if (options.contains(StandardOpenOption.CREATE_NEW) || Files.notExists(path)) {
                // IOException if the directory already exists.
                Files.createDirectory(path);
                isNew = true;
            }
        }
        if (isNew || (options.contains(StandardOpenOption.WRITE) && Files.isWritable(path))) {
            // May throw NoSuchFileException.
            store = new WritableStore(this, connector, path, componentProvider);
        } else {
            // May throw NoSuchFileException.
            store = new Store(this, connector, path, componentProvider);
        }
        /*
             * If there is a destructive operation to perform (TRUNCATE_EXISTING), do it last only
             * after we have successfully created the data store. The check for directory existence
             * is also done after creation to be sure to check the path used by the store.
             */
        if (!Files.isDirectory(path)) {
            throw new DataStoreException(Resources.format(Resources.Keys.FileIsNotAResourceDirectory_1, path));
        }
        if (options.contains(StandardOpenOption.TRUNCATE_EXISTING)) {
            WritableStore.deleteRecursively(path, false);
        }
    } catch (IOException e) {
        /*
             * In case of error, Java FileSystem implementation tries to throw a specific exception
             * (NoSuchFileException or FileAlreadyExistsException), but this is not guaranteed.
             */
        int isDirectory = 0;
        final short errorKey;
        if (e instanceof FileAlreadyExistsException) {
            if (path != null && Files.isDirectory(path)) {
                isDirectory = 1;
            }
            errorKey = Resources.Keys.FileAlreadyExists_2;
        } else if (e instanceof NoSuchFileException) {
            errorKey = Resources.Keys.NoSuchResourceDirectory_1;
        } else {
            errorKey = Resources.Keys.CanNotCreateFolderStore_1;
        }
        throw new DataStoreException(Resources.format(errorKey, (path != null) ? path : connector.getStorageName(), isDirectory), e);
    }
    return store;
}
Also used : Path(java.nio.file.Path) DataStoreException(org.apache.sis.storage.DataStoreException) FileAlreadyExistsException(java.nio.file.FileAlreadyExistsException) DataStoreProvider(org.apache.sis.storage.DataStoreProvider) NoSuchFileException(java.nio.file.NoSuchFileException) URIDataStore(org.apache.sis.internal.storage.URIDataStore) DataStore(org.apache.sis.storage.DataStore) IOException(java.io.IOException)

Example 2 with DataStoreException

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

the class Store method components.

/**
 * Returns all resources found in the folder given at construction time.
 * Only the resources recognized by a {@link DataStore} will be included.
 * This includes sub-folders. Resources are in no particular order.
 */
@Override
@SuppressWarnings("ReturnOfCollectionOrArrayField")
public synchronized Collection<Resource> components() throws DataStoreException {
    if (components == null) {
        final List<DataStore> resources = new ArrayList<>();
        try (DirectoryStream<Path> stream = Files.newDirectoryStream(location, this)) {
            for (final Path candidate : stream) {
                /*
                     * The candidate path may be a symbolic link to a file that we have previously read.
                     * In such case, use the existing data store.   A use case is a directory containing
                     * hundred of GeoTIFF files all accompanied by ".prj" files having identical content.
                     * (Note: those ".prj" files should be invisible since they should be identified as
                     * GeoTIFF auxiliary files, but current Store implementation does not know that).
                     */
                final Path real = candidate.toRealPath();
                DataStore next = children.get(real);
                if (next instanceof Store) {
                    // Warn about directories only.
                    ((Store) next).sharedRepository(real);
                }
                if (next == null) {
                    /*
                         * The candidate file has never been read before. Try to read it now.
                         * If the file format is unknown (UnsupportedStorageException), we will
                         * check if we can open it as a child folder store before to skip it.
                         */
                    final StorageConnector connector = new StorageConnector(candidate);
                    connector.setOption(OptionKey.LOCALE, locale);
                    connector.setOption(OptionKey.TIMEZONE, timezone);
                    connector.setOption(OptionKey.ENCODING, encoding);
                    try {
                        if (componentProvider == null) {
                            // May throw UnsupportedStorageException.
                            next = DataStores.open(connector);
                        } else if (componentProvider.probeContent(connector).isSupported()) {
                            // Open a file of specified format.
                            next = componentProvider.open(connector);
                        } else if (Files.isDirectory(candidate)) {
                            // Open a sub-directory.
                            next = new Store(this, connector);
                        } else {
                            // Not the format specified at construction time.
                            connector.closeAllExcept(null);
                            continue;
                        }
                    } catch (UnsupportedStorageException ex) {
                        if (!Files.isDirectory(candidate)) {
                            connector.closeAllExcept(null);
                            listeners.warning(Level.FINE, null, ex);
                            continue;
                        }
                        next = new Store(this, connector);
                    } catch (DataStoreException ex) {
                        try {
                            connector.closeAllExcept(null);
                        } catch (DataStoreException s) {
                            ex.addSuppressed(s);
                        }
                        throw ex;
                    }
                    /*
                         * At this point we got the data store. It could happen that a store for
                         * the same file has been added concurrently, so we need to check again.
                         */
                    final DataStore existing = children.putIfAbsent(real, next);
                    if (existing != null) {
                        next.close();
                        next = existing;
                        if (next instanceof Store) {
                            // Warn about directories only.
                            ((Store) next).sharedRepository(real);
                        }
                    }
                }
                resources.add(next);
            }
        } catch (DirectoryIteratorException | UncheckedIOException ex) {
            // The cause is an IOException (no other type allowed).
            throw new DataStoreException(canNotRead(), ex.getCause());
        } catch (IOException ex) {
            throw new DataStoreException(canNotRead(), ex);
        } catch (BackingStoreException ex) {
            throw ex.unwrapOrRethrow(DataStoreException.class);
        }
        components = UnmodifiableArrayList.wrap(resources.toArray(new Resource[resources.size()]));
    }
    // Safe because unmodifiable list.
    return components;
}
Also used : Path(java.nio.file.Path) DirectoryIteratorException(java.nio.file.DirectoryIteratorException) StorageConnector(org.apache.sis.storage.StorageConnector) DataStoreException(org.apache.sis.storage.DataStoreException) ArrayList(java.util.ArrayList) UnmodifiableArrayList(org.apache.sis.internal.util.UnmodifiableArrayList) BackingStoreException(org.apache.sis.util.collection.BackingStoreException) DataStore(org.apache.sis.storage.DataStore) UncheckedIOException(java.io.UncheckedIOException) IOException(java.io.IOException) UncheckedIOException(java.io.UncheckedIOException) DataStore(org.apache.sis.storage.DataStore) UnsupportedStorageException(org.apache.sis.storage.UnsupportedStorageException)

Example 3 with DataStoreException

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

the class Store method close.

/**
 * Closes all children resources.
 */
@Override
public synchronized void close() throws DataStoreException {
    final Collection<Resource> resources = components;
    if (resources != null) {
        // Clear first in case of failure.
        components = null;
        DataStoreException failure = null;
        for (final Resource r : resources) {
            if (r instanceof DataStore)
                try {
                    ((DataStore) r).close();
                } catch (DataStoreException ex) {
                    if (failure == null) {
                        failure = ex;
                    } else {
                        failure.addSuppressed(ex);
                    }
                }
        }
        if (failure != null) {
            throw failure;
        }
    }
}
Also used : DataStoreException(org.apache.sis.storage.DataStoreException) DataStore(org.apache.sis.storage.DataStore) Resource(org.apache.sis.storage.Resource)

Example 4 with DataStoreException

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

the class WritableStore method remove.

/**
 * Removes a {@code Resource} from this store. The resource must be a part of this {@code Aggregate}.
 * For a folder store, this means that the resource must be a direct children of the directory managed
 * by this store.
 *
 * This operation is destructive: the {@link Resource} and it's related files will be deleted.
 */
@Override
public synchronized void remove(final Resource resource) throws DataStoreException {
    if (resource instanceof DataStore)
        try {
            if (resource instanceof Store) {
                final Path path = ((Store) resource).location;
                if (Files.isSameFile(path.getParent(), location)) {
                    ((Store) resource).close();
                    deleteRecursively(path, true);
                    children.remove(path);
                    return;
                }
            } else if (resource instanceof ResourceOnFileSystem) {
                final Path[] componentPaths = ((ResourceOnFileSystem) resource).getComponentFiles().clone();
                for (Path root : componentPaths) {
                    root = root.getParent();
                    if (Files.isSameFile(root, location)) {
                        /*
                         * If we enter in this block, we have determined that at least one file is located in the
                         * directory managed by this store - NOT in a subdirectory since they could be managed by
                         * different folder stores. We assume that this root file is the "main" file. Other files
                         * could be in subdirectories, but we need to verify - we do not delete files outside.
                         */
                        for (final Path path : componentPaths) {
                            if (path.startsWith(root)) {
                                Files.delete(path);
                            }
                        }
                        children.values().removeIf((e) -> e == resource);
                        // Clear cache. TODO: we should do something more efficient.
                        components = null;
                        return;
                    }
                }
            }
        } catch (IOException e) {
            throw new DataStoreException(messages().getString(Resources.Keys.CanNotRemoveResource_2, getDisplayName(), ((DataStore) resource).getDisplayName()), e);
        }
    throw new DataStoreException(messages().getString(Resources.Keys.NoSuchResourceInAggregate_2, getDisplayName(), StoreUtilities.getLabel(resource)));
}
Also used : Path(java.nio.file.Path) ResourceOnFileSystem(org.apache.sis.internal.storage.ResourceOnFileSystem) DataStoreException(org.apache.sis.storage.DataStoreException) DataStore(org.apache.sis.storage.DataStore) DataStore(org.apache.sis.storage.DataStore) IOException(java.io.IOException)

Example 5 with DataStoreException

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

the class FirstKeywordPeek method probeContent.

/**
 * Returns {@link ProbeResult#SUPPORTED} if the given storage appears to begin with an expected keyword
 * Returning {@code SUPPORTED} from this method does not guarantee that reading or writing will succeed,
 * only that there appears to be a reasonable chance of success based on a brief inspection of the storage
 * header.
 *
 * @param  connector information about the storage (URL, stream, JDBC connection, <i>etc</i>).
 * @return {@link ProbeResult#SUPPORTED} if the given storage seems to be readable.
 * @throws DataStoreException if an I/O or SQL error occurred.
 */
@SuppressWarnings("null")
public final ProbeResult probeContent(final StorageConnector connector) throws DataStoreException {
    char[] keyword = null;
    int pos = 0;
    try {
        final ByteBuffer buffer = connector.getStorageAs(ByteBuffer.class);
        final Reader reader;
        if (buffer != null) {
            buffer.mark();
            reader = null;
        } else {
            // User gave us explicitely a Reader (e.g. a StringReader wrapping a String instance).
            reader = connector.getStorageAs(Reader.class);
            if (reader == null) {
                return ProbeResult.UNSUPPORTED_STORAGE;
            }
            reader.mark(READ_AHEAD_LIMIT);
        }
        /*
             * Ignore leading spaces and comments if any, then get a keyword no longer than 'maxLength'.
             * That keyword shall be followed by [ or (, ignoring whitespaces.
             */
        int c;
        while ((c = nextAfterSpaces(buffer, reader)) == COMMENT) {
            toEndOfLine(buffer, reader);
        }
        int s;
        if ((s = isKeywordChar(c)) >= ACCEPT) {
            keyword = new char[maxLength];
            do {
                if (s == ACCEPT) {
                    if (pos >= keyword.length) {
                        // Keyword too long.
                        pos = 0;
                        break;
                    }
                    keyword[pos++] = (char) c;
                }
                c = (buffer == null) ? IOUtilities.readCodePoint(reader) : buffer.hasRemaining() ? (char) buffer.get() : -1;
            } while ((s = isKeywordChar(c)) >= ACCEPT);
            /*
                 * At this point we finished to read and store the keyword.
                 * Verify if the keyword is followed by a character that indicate a keyword end.
                 */
            if (Character.isWhitespace(c)) {
                c = nextAfterSpaces(buffer, reader);
            }
            if (!isPostKeyword(c)) {
                pos = 0;
            }
        }
        if (buffer != null) {
            buffer.reset();
        } else {
            reader.reset();
        }
        if (c < 0) {
            return ProbeResult.INSUFFICIENT_BYTES;
        }
    } catch (IOException e) {
        throw new DataStoreException(e);
    }
    return forKeyword(keyword, pos);
}
Also used : DataStoreException(org.apache.sis.storage.DataStoreException) Reader(java.io.Reader) IOException(java.io.IOException) ByteBuffer(java.nio.ByteBuffer)

Aggregations

DataStoreException (org.apache.sis.storage.DataStoreException)22 IOException (java.io.IOException)11 DataStore (org.apache.sis.storage.DataStore)6 Path (java.nio.file.Path)4 FactoryException (org.opengis.util.FactoryException)4 Reader (java.io.Reader)3 UncheckedIOException (java.io.UncheckedIOException)3 ByteBuffer (java.nio.ByteBuffer)3 DataStoreContentException (org.apache.sis.storage.DataStoreContentException)3 ProbeResult (org.apache.sis.storage.ProbeResult)3 BackingStoreException (org.apache.sis.util.collection.BackingStoreException)3 Closeable (java.io.Closeable)2 InvocationTargetException (java.lang.reflect.InvocationTargetException)2 URISyntaxException (java.net.URISyntaxException)2 NoSuchFileException (java.nio.file.NoSuchFileException)2 ConcurrentReadException (org.apache.sis.storage.ConcurrentReadException)2 IllegalNameException (org.apache.sis.storage.IllegalNameException)2 StorageConnector (org.apache.sis.storage.StorageConnector)2 UnsupportedStorageException (org.apache.sis.storage.UnsupportedStorageException)2 BufferedReader (java.io.BufferedReader)1