use of org.apache.sis.storage.DataStoreException in project sis by apache.
the class GridResourceWrapper method addListener.
/*
* Do not override `subset(Query)`. We want the subset to delegate to this wrapper.
*/
/**
* Registers a listener to notify when the specified kind of event occurs in this resource or in children.
* The default implementation delegates to the source.
*
* @param <T> compile-time value of the {@code eventType} argument.
* @param listener listener to notify about events.
* @param eventType type of {@link StoreEvent} to listen (can not be {@code null}).
*/
@Override
public <T extends StoreEvent> void addListener(Class<T> eventType, StoreListener<? super T> listener) {
final GridCoverageResource source;
try {
source = source();
} catch (DataStoreException e) {
throw new BackingStoreException(e);
}
source.addListener(eventType, listener);
}
use of org.apache.sis.storage.DataStoreException in project sis by apache.
the class AbstractGridResource method canNotRead.
/**
* Creates an exception for a failure to load data. If the failure may be caused by an envelope
* outside the resource domain, that envelope will be inferred from the {@code request} argument.
*
* @param filename some identification (typically a file name) of the data that can not be read.
* @param request the requested domain, or {@code null} if unspecified.
* @param cause the cause of the failure, or {@code null} if none.
* @return the exception to throw.
*/
protected final DataStoreException canNotRead(final String filename, final GridGeometry request, Throwable cause) {
final int DOMAIN = 1, REFERENCING = 2, CONTENT = 3;
// One of above constants, with 0 for "none of above".
int type = 0;
Envelope bounds = null;
if (cause instanceof DisjointExtentException) {
type = DOMAIN;
if (request != null && request.isDefined(GridGeometry.ENVELOPE)) {
bounds = request.getEnvelope();
}
} else if (cause instanceof RuntimeException) {
Throwable c = cause.getCause();
if (isReferencing(c)) {
type = REFERENCING;
cause = c;
} else if (cause instanceof ArithmeticException || cause instanceof RasterFormatException) {
type = CONTENT;
}
} else if (isReferencing(cause)) {
type = REFERENCING;
}
final String message = createExceptionMessage(filename, bounds);
switch(type) {
case DOMAIN:
return new NoSuchDataException(message, cause);
case REFERENCING:
return new DataStoreReferencingException(message, cause);
case CONTENT:
return new DataStoreContentException(message, cause);
default:
return new DataStoreException(message, cause);
}
}
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.
* Sub-folders are represented by other folder {@code Store} instances;
* their resources are available by invoking {@link Aggregate#components()}
* on them (this method does not traverse sub-folders recursively by itself).
* 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<>();
final NameFactory nameFactory = DefaultFactories.forBuildin(NameFactory.class);
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, nameFactory);
} 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, nameFactory);
} 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;
}
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;
}
}
}
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)));
}
Aggregations