Author: jsorel
Date: Wed Feb 14 15:18:02 2018
New Revision: 1824245
URL: http://svn.apache.org/viewvc?rev=1824245&view=rev
Log:
Storage : improve folder store to support add and remove operations if a
specific provider is given
Added:
sis/branches/JDK8/storage/sis-storage/src/test/resources/org/apache/sis/internal/storage/folder/test-data/proj.prj
Modified:
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.java
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.properties
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources_fr.properties
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/URIDataStore.java
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/StoreProvider.java
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/FolderStoreProvider.java
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/Store.java
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/AbstractProvider.java
sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/folder/StoreTest.java
Modified:
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.java?rev=1824245&r1=1824244&r2=1824245&view=diff
==============================================================================
---
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.java
[UTF-8] (original)
+++
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.java
[UTF-8] Wed Feb 14 15:18:02 2018
@@ -158,6 +158,16 @@ public final class Resources extends Ind
public static final short FeatureNotFound_2 = 17;
/**
+ * Restricted store provider identifier to use for resource discovery
and creation.
+ */
+ public static final short FolderStoreProviderParameter = 40;
+
+ /**
+ * Unknown provider identifier {0}.
+ */
+ public static final short FolderStoreProviderUnknown_1 = 41;
+
+ /**
* Whether to assemble trajectory fragments (lines in CSV file) in a
single feature instance.
*/
public static final short FoliationRepresentation = 38;
Modified:
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.properties
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.properties?rev=1824245&r1=1824244&r2=1824245&view=diff
==============================================================================
---
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.properties
[ISO-8859-1] (original)
+++
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.properties
[ISO-8859-1] Wed Feb 14 15:18:02 2018
@@ -16,7 +16,7 @@
#
#
-# Resources in this file are for "sis-netcdf" usage only and should not be
used by any other module.
+# Resources in this file are for "sis-storage" usage only and should not be
used by any other module.
# For resources shared by all modules in the Apache SIS project, see
"org.apache.sis.util.resources" package.
#
AmbiguousName_4 = Name \u201c{3}\u201d is ambiguous because
it can be understood as either \u201c{1}\u201d or \u201c{2}\u201d in the
context of \u201c{0}\u201d data.
@@ -37,6 +37,8 @@ DataStoreTimeZone = Time
DirectoryContent_1 = Content of \u201c{0}\u201d directory.
FeatureAlreadyPresent_2 = A feature named \u201c{1}\u201d is already
present in the \u201c{0}\u201d data store.
FeatureNotFound_2 = Feature \u201c{1}\u201d has not been found
in the \u201c{0}\u201d data store.
+FolderStoreProviderParameter = Restricted store provider identifier to
use for resource discovery and creation.
+FolderStoreProviderUnknown_1 = Unknown provider identifier {0}.
FoliationRepresentation = Whether to assemble trajectory fragments
(lines in CSV file) in a single feature instance.
ExcessiveStringSize_3 = Character string in the \u201c{0}\u201d
file is too long. The string has {2} characters while the limit is {1}.
IllegalFeatureType_2 = The {0} data store does not accept
features of type \u201c{1}\u201d.
Modified:
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources_fr.properties
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources_fr.properties?rev=1824245&r1=1824244&r2=1824245&view=diff
==============================================================================
---
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources_fr.properties
[ISO-8859-1] (original)
+++
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources_fr.properties
[ISO-8859-1] Wed Feb 14 15:18:02 2018
@@ -43,6 +43,8 @@ DirectoryContent_1 = Cont
ExcessiveStringSize_3 = La cha\u00eene de caract\u00e8res dans le
fichier \u00ab\u202f{0}\u202f\u00bb est trop longue. La cha\u00eene fait {2}
caract\u00e8res alors que la limite est {1}.
FeatureAlreadyPresent_2 = Une entit\u00e9 nomm\u00e9e
\u00ab\u202f{1}\u202f\u00bb est d\u00e9j\u00e0 pr\u00e9sente dans les
donn\u00e9es de \u00ab\u202f{0}\u202f\u00bb.
FeatureNotFound_2 = L\u2019entit\u00e9
\u00ab\u202f{1}\u202f\u00bb n\u2019a pas \u00e9t\u00e9 trouv\u00e9e dans les
donn\u00e9es de \u00ab\u202f{0}\u202f\u00bb.
+FolderStoreProviderParameter = Identifiant du fournisseur de donn\u00e9es
unique \u00e0 utiliser pour la d\u00e9tection et la cr\u00e9ation.
+FolderStoreProviderUnknown_1 = L'identifiant de fournisseur de
donn\u00e9es {0} est inconnu.
FoliationRepresentation = Indique s\u2019il faut assembler les
fragments de trajectoires (lignes dans un fichier CSV) dans une entit\u00e9
unique.
IllegalFeatureType_2 = Le format {0} ne stocke pas de
donn\u00e9es de type \u00ab\u202f{1}\u202f\u00bb.
IllegalInputTypeForReader_2 = Le lecteur {0} n\u2019accepte pas des
entr\u00e9s de type \u2018{1}\u2019.
Modified:
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/URIDataStore.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/URIDataStore.java?rev=1824245&r1=1824244&r2=1824245&view=diff
==============================================================================
---
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/URIDataStore.java
[UTF-8] (original)
+++
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/URIDataStore.java
[UTF-8] Wed Feb 14 15:18:02 2018
@@ -18,6 +18,9 @@ package org.apache.sis.internal.storage;
import java.net.URI;
import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import org.opengis.parameter.ParameterValueGroup;
import org.opengis.parameter.ParameterDescriptor;
import org.opengis.parameter.ParameterDescriptorGroup;
@@ -29,6 +32,7 @@ import org.apache.sis.storage.DataStoreP
import org.apache.sis.storage.DataStoreException;
import org.apache.sis.storage.IllegalOpenParameterException;
import org.apache.sis.internal.storage.io.IOUtilities;
+import org.apache.sis.internal.util.UnmodifiableArrayList;
/**
@@ -123,6 +127,12 @@ public abstract class URIDataStore exten
private volatile ParameterDescriptorGroup openDescriptor;
/**
+ * List of main file suffixes used.
+ */
+ protected final List<String> suffix = new ArrayList<>();
+ private final List<String> unSuffix =
Collections.unmodifiableList(suffix);
+
+ /**
* Creates a new provider.
*/
protected Provider() {
@@ -145,6 +155,15 @@ public abstract class URIDataStore exten
}
/**
+ * Get the list of this format mainly used file suffixes.
+ *
+ * @return list of suffix, case insensitive, never null, can be empty.
+ */
+ public final List<String> getSuffix() {
+ return unSuffix;
+ }
+
+ /**
* Invoked by {@link #getOpenParameters()} the first time that a
parameter descriptor needs
* to be created. When invoked, the parameter group name is set to a
name derived from the
* {@link #getShortName()} value. The default implementation creates a
group containing only
Modified:
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/StoreProvider.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/StoreProvider.java?rev=1824245&r1=1824244&r2=1824245&view=diff
==============================================================================
---
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/StoreProvider.java
[UTF-8] (original)
+++
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/StoreProvider.java
[UTF-8] Wed Feb 14 15:18:02 2018
@@ -126,6 +126,7 @@ public final class StoreProvider extends
* Creates a new provider.
*/
public StoreProvider() {
+ suffix.add("csv");
}
/**
Modified:
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/FolderStoreProvider.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/FolderStoreProvider.java?rev=1824245&r1=1824244&r2=1824245&view=diff
==============================================================================
---
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/FolderStoreProvider.java
[UTF-8] (original)
+++
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/FolderStoreProvider.java
[UTF-8] Wed Feb 14 15:18:02 2018
@@ -39,7 +39,7 @@ import org.apache.sis.util.logging.Loggi
import org.apache.sis.internal.system.Modules;
import org.apache.sis.internal.storage.Resources;
import org.apache.sis.internal.storage.URIDataStore;
-import org.apache.sis.setup.OptionKey;
+import org.apache.sis.internal.storage.io.IOUtilities;
/**
@@ -60,33 +60,43 @@ public final class FolderStoreProvider e
private static final String NAME = "folder";
/**
+ * Description of the parameter for folder location.
+ */
+ static final ParameterDescriptor<Path> LOCATION;
+
+ /**
* Description of the parameter for formating conventions of dates and
numbers.
*/
- private static final ParameterDescriptor<Locale> LOCALE;
+ static final ParameterDescriptor<Locale> LOCALE;
/**
* Description of the parameter for timezone of dates in the data store.
*/
- private static final ParameterDescriptor<TimeZone> TIMEZONE;
+ static final ParameterDescriptor<TimeZone> TIMEZONE;
/**
* Description of the parameter for character encoding used by the data
store.
*/
- private static final ParameterDescriptor<Charset> ENCODING;
+ static final ParameterDescriptor<Charset> ENCODING;
+
+ /**
+ * Description of the parameter for restricting searched factories.
+ */
+ static final ParameterDescriptor<String> PROVIDER;
/**
* The group of parameter descriptors to be returned by {@link
#getOpenParameters()}.
*/
static final ParameterDescriptorGroup PARAMETERS;
static {
- final ParameterDescriptor<Path> location;
final ParameterBuilder builder = new ParameterBuilder();
final InternationalString remark =
Resources.formatInternational(Resources.Keys.UsedOnlyIfNotEncoded);
ENCODING = annotate(builder, URIDataStore.Provider.ENCODING, remark);
LOCALE = builder.addName("locale"
).setDescription(Resources.formatInternational(Resources.Keys.DataStoreLocale
)).setRemarks(remark).create(Locale.class, null);
TIMEZONE =
builder.addName("timezone").setDescription(Resources.formatInternational(Resources.Keys.DataStoreTimeZone)).setRemarks(remark).create(TimeZone.class,
null);
- location = new
ParameterBuilder(URIDataStore.Provider.LOCATION_PARAM).create(Path.class, null);
- PARAMETERS = builder.addName(NAME).createGroup(location, LOCALE,
TIMEZONE, ENCODING);
+ PROVIDER =
builder.addName("provider").setDescription(Resources.formatInternational(Resources.Keys.FolderStoreProviderParameter)).create(String.class,
null);
+ LOCATION = new
ParameterBuilder(URIDataStore.Provider.LOCATION_PARAM).create(Path.class, null);
+ PARAMETERS = builder.addName(NAME).createGroup(LOCATION, LOCALE,
TIMEZONE, ENCODING, PROVIDER);
}
/**
@@ -178,12 +188,17 @@ public final class FolderStoreProvider e
@Override
public DataStore open(final ParameterValueGroup parameters) throws
DataStoreException {
ArgumentChecks.ensureNonNull("parameter", parameters);
- final StorageConnector connector =
URIDataStore.Provider.connector(this, parameters);
- final Parameters pg = Parameters.castOrWrap(parameters);
- connector.setOption(OptionKey.LOCALE, pg.getValue(LOCALE));
- connector.setOption(OptionKey.TIMEZONE, pg.getValue(TIMEZONE));
- connector.setOption(OptionKey.ENCODING, pg.getValue(ENCODING));
- return open(connector);
+ final Parameters params = Parameters.castOrWrap(parameters);
+ try {
+ if (params.getValue(PROVIDER) != null) {
+ return new Store.Writable(this, params);
+ } else {
+ return new Store(this, params);
+ }
+ } catch (IOException e) {
+ throw new
DataStoreException(Resources.format(Resources.Keys.CanNotReadDirectory_1,
+ IOUtilities.filename(params.getValue(LOCATION))), e);
+ }
}
/**
Modified:
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/Store.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/Store.java?rev=1824245&r1=1824244&r2=1824245&view=diff
==============================================================================
---
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/Store.java
[UTF-8] (original)
+++
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/Store.java
[UTF-8] Wed Feb 14 15:18:02 2018
@@ -29,8 +29,15 @@ import java.nio.file.DirectoryStream;
import java.nio.file.DirectoryIteratorException;
import java.io.IOException;
import java.io.UncheckedIOException;
+import java.nio.file.FileVisitResult;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.Map.Entry;
import java.util.logging.Level;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
+import java.util.stream.Stream;
+import org.apache.sis.internal.storage.FileSystemResource;
import org.opengis.metadata.Metadata;
import org.opengis.metadata.maintenance.ScopeCode;
import org.opengis.parameter.ParameterValueGroup;
@@ -47,6 +54,16 @@ import org.apache.sis.util.collection.Ba
import org.apache.sis.internal.util.UnmodifiableArrayList;
import org.apache.sis.internal.storage.MetadataBuilder;
import org.apache.sis.internal.storage.Resources;
+import org.apache.sis.internal.storage.URIDataStore;
+import org.apache.sis.metadata.iso.citation.Citations;
+import org.apache.sis.parameter.Parameters;
+import org.apache.sis.storage.FeatureSet;
+import org.apache.sis.storage.ProbeResult;
+import org.apache.sis.storage.ReadOnlyStorageException;
+import org.apache.sis.storage.WritableAggregate;
+import org.apache.sis.storage.WritableFeatureSet;
+import org.opengis.feature.Feature;
+import org.opengis.metadata.identification.Identification;
/**
@@ -71,32 +88,55 @@ import org.apache.sis.internal.storage.R
* @since 0.8
* @module
*/
-final class Store extends DataStore implements Aggregate,
DirectoryStream.Filter<Path> {
+class Store extends DataStore implements Aggregate,
DirectoryStream.Filter<Path> {
+
+ /**
+ * File walker to delete file and folder recursively.
+ */
+ private static final SimpleFileVisitor<Path> FILE_DELETE = new
SimpleFileVisitor<Path>() {
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException {
+ Files.delete(file);
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult postVisitDirectory(Path dir, IOException exc)
throws IOException {
+ Files.delete(dir);
+ return FileVisitResult.CONTINUE;
+ }
+ };
+
/**
* The {@link FolderStoreProvider#LOCATION} parameter value, or {@code
null} if none.
*/
- private final Path location;
+ protected final Path location;
/**
* Formating conventions of dates and numbers, or {@code null} if
unspecified.
*/
- private final Locale locale;
+ protected final Locale locale;
/**
* Timezone of dates in the data store, or {@code null} if unspecified.
*/
- private final TimeZone timezone;
+ protected final TimeZone timezone;
/**
* Character encoding used by the data store, or {@code null} if
unspecified.
*/
- private final Charset encoding;
+ protected final Charset encoding;
+
+ /**
+ * Single provider to use in searches and creation operations, or {@code
null} if unspecified.
+ */
+ protected final String providerName;
/**
* All data stores (including sub-folders) found in the directory
structure, including the root directory.
* This is used for avoiding never-ending loop with symbolic links.
*/
- private final Map<Path,DataStore> children;
+ protected final Map<Path,DataStore> children;
/**
* Information about the data store as a whole, created when first needed.
@@ -110,7 +150,7 @@ final class Store extends DataStore impl
*
* @see #components()
*/
- private transient Collection<Resource> components;
+ protected transient Collection<Resource> components;
/**
* {@code true} if {@link #sharedRepository(Path)} has already been
invoked for {@link #location} path.
@@ -119,6 +159,11 @@ final class Store extends DataStore impl
private transient boolean sharedRepositoryReported;
/**
+ * Cached search and create provider to use.
+ */
+ private transient DataStoreProvider searchProvider;
+
+ /**
* Creates a new folder store from the given file, path or URI.
*
* @param provider the factory that created this {@code DataStore}
instance, or {@code null} if unspecified.
@@ -134,6 +179,18 @@ final class Store extends DataStore impl
encoding = connector.getOption(OptionKey.ENCODING);
children = new ConcurrentHashMap<>();
children.put(location.toRealPath(), this);
+ providerName = null;
+ }
+
+ Store(final DataStoreProvider provider, final Parameters params) throws
DataStoreException, IOException {
+ super(provider, new StorageConnector(params));
+ location = params.getValue(FolderStoreProvider.LOCATION);
+ locale = params.getValue(FolderStoreProvider.LOCALE);
+ timezone = params.getValue(FolderStoreProvider.TIMEZONE);
+ encoding = params.getValue(FolderStoreProvider.ENCODING);
+ providerName = params.getValue(FolderStoreProvider.PROVIDER);
+ children = new ConcurrentHashMap<>();
+ children.put(location.toRealPath(), this);
}
/**
@@ -145,11 +202,13 @@ final class Store extends DataStore impl
*/
private Store(final Store parent, final StorageConnector connector) throws
DataStoreException {
super(parent, connector);
- location = connector.getStorageAs(Path.class);
- locale = connector.getOption(OptionKey.LOCALE);
- timezone = connector.getOption(OptionKey.TIMEZONE);
- encoding = connector.getOption(OptionKey.ENCODING);
- children = parent.children;
+ location = connector.getStorageAs(Path.class);
+ locale = connector.getOption(OptionKey.LOCALE);
+ timezone = connector.getOption(OptionKey.TIMEZONE);
+ encoding = connector.getOption(OptionKey.ENCODING);
+ children = parent.children;
+ providerName = parent.providerName;
+ searchProvider = parent.searchProvider;
}
/**
@@ -158,10 +217,11 @@ final class Store extends DataStore impl
@Override
public ParameterValueGroup getOpenParameters() {
final ParameterValueGroup pg = (provider != null ?
provider.getOpenParameters() : FolderStoreProvider.PARAMETERS).createValue();
- pg.parameter(FolderStoreProvider.LOCATION).setValue(location);
- if (locale != null) pg.parameter("locale" ).setValue(locale );
- if (timezone != null) pg.parameter("timezone").setValue(timezone);
- if (encoding != null) pg.parameter("encoding").setValue(encoding);
+ pg.parameter(DataStoreProvider.LOCATION).setValue(location);
+ if (locale != null) pg.parameter("locale" ).setValue(locale );
+ if (timezone != null) pg.parameter("timezone").setValue(timezone);
+ if (encoding != null) pg.parameter("encoding").setValue(encoding);
+ if (providerName != null)
pg.parameter("provider").setValue(providerName);
return pg;
}
@@ -227,8 +287,20 @@ final class Store extends DataStore impl
connector.setOption(OptionKey.LOCALE, locale);
connector.setOption(OptionKey.TIMEZONE, timezone);
connector.setOption(OptionKey.ENCODING, encoding);
+
+ final DataStoreProvider provider =
getSearchAndCreateProvider();
try {
- next = DataStores.open(connector);
+ if (provider != null) {
+ final ProbeResult result =
provider.probeContent(connector);
+ if (result.isSupported()) {
+ next = provider.open(connector);
+ } else {
+ throw new UnsupportedStorageException();
+ }
+ } else {
+ next = DataStores.open(connector);
+ }
+
} catch (UnsupportedStorageException ex) {
if (!Files.isDirectory(candidate)) {
connector.closeAllExcept(null);
@@ -273,6 +345,25 @@ final class Store extends DataStore impl
}
/**
+ *
+ * @return search and create provider, can be null
+ * @throws DataStoreException
+ */
+ protected DataStoreProvider getSearchAndCreateProvider() throws
DataStoreException {
+ if (searchProvider == null && providerName != null) {
+ for (DataStoreProvider provider : DataStores.providers()) {
+ if (providerName.equals(provider.getShortName())) {
+ searchProvider = provider;
+ break;
+ }
+ }
+ if (searchProvider == null) {
+ throw new
DataStoreException(message(Resources.Keys.FolderStoreProviderUnknown_1,
providerName));
+ }
+ }
+ return searchProvider;
+ }
+ /**
* Builds an error message for an error occurring while reading files in
the directory.
*/
private String canNotRead() {
@@ -327,4 +418,160 @@ final class Store extends DataStore impl
}
}
}
+
+ /**
+ * Writable version of the store which rely on given datastore provider to
create new types.
+ *
+ * Note 1 : this implementation is experimental.
+ * Note 2 : it has not been tested since we do not have writable feature
sets yet.
+ */
+ static class Writable extends Store implements WritableAggregate {
+
+ public Writable(DataStoreProvider provider, Parameters params) throws
DataStoreException, IOException {
+ super(provider, params);
+ }
+
+ /**
+ * Create a new resource.
+ * This implementation uses the provider given in store creation
parameters.
+ *
+ * @param resource
+ * @return
+ * @throws DataStoreException
+ */
+ @Override
+ public synchronized Resource add(Resource resource) throws
DataStoreException {
+ if (!(resource instanceof FeatureSet)) {
+ throw new DataStoreException("Only FeatureSet resources can be
imported in this store.");
+ }
+
+ if (components().contains(resource)) {
+ throw new DataStoreException("Resource is already in this
aggregate.");
+ }
+
+ //we know it is not null in this instance
+ final DataStoreProvider provider = getSearchAndCreateProvider();
+ if (!(provider instanceof URIDataStore.Provider)) {
+ throw new DataStoreException("Resource creation is possible
only with URIProviders");
+ }
+
+ final URIDataStore.Provider p = (URIDataStore.Provider) provider;
+
+ //build location
+ String fileName = null;
+ for (Identification id :
resource.getMetadata().getIdentificationInfo()) {
+ fileName = Citations.getIdentifier(id.getCitation());
+ if (fileName!=null && !fileName.isEmpty()) break;
+ }
+ if (fileName == null || fileName.isEmpty()) {
+ throw new DataStoreException("Resource does not have an
identifier.");
+ }
+
+ //some format may have no suffix at all
+ if (!p.getSuffix().isEmpty()) {
+ fileName += "."+ p.getSuffix().get(0);
+ }
+
+ //create new store/resource
+ final Path location = this.location.resolve(fileName);
+ final StorageConnector connector = new StorageConnector(location);
+ connector.setOption(OptionKey.LOCALE, locale);
+ connector.setOption(OptionKey.TIMEZONE, timezone);
+ connector.setOption(OptionKey.ENCODING, encoding);
+ final DataStore store = p.open(connector);
+
+ //check we can write datas
+ if (!(store instanceof WritableFeatureSet)) {
+ try {
+ //remove any created file
+ if (resource instanceof FileSystemResource) {
+ //delete resource files
+ final Path[] resourcePaths = ((FileSystemResource)
resource).getResourcePaths();
+ for (Path path : resourcePaths) {
+ Files.walkFileTree(path, FILE_DELETE);
+ }
+ }
+ Files.deleteIfExists(location);
+ } catch(IOException ex) {
+ //do nothing
+ } finally {
+ store.close();
+ }
+ throw new DataStoreException("Created resource is not a
WritableFeatureSet.");
+ }
+
+ //copy datas between resources
+ children.put(location, store);
+ final FeatureSet source = (FeatureSet) resource;
+ final WritableFeatureSet target = (WritableFeatureSet) store;
+ target.updateType(source.getType());
+ try (Stream<Feature> stream = source.features(false)) {
+ target.add(stream.iterator());
+ }
+
+
+ //clear cache
+ components = null;
+
+ return store;
+ }
+
+ /**
+ * Note : in this implementation we clear the cache after closing the
stores and before deleting the files.
+ * This ensure in the worse case scenario a new store will be created
on the possible remaining files.
+ *
+ * @param resource
+ * @throws ReadOnlyStorageException
+ * @throws DataStoreException
+ */
+ @Override
+ public synchronized void remove(Resource resource) throws
ReadOnlyStorageException, DataStoreException {
+ if (!(components().contains(resource))) {
+ throw new DataStoreException("Unknown resource, verify it is
part of this aggregate.");
+ }
+
+ //clear cache
+ components = null;
+
+ if (resource instanceof Store) {
+ final Store store = (Store) resource;
+ store.close();
+ //clear cache
+ children.remove(store.location);
+
+ try {
+ Files.walkFileTree(store.location, FILE_DELETE);
+ } catch (IOException ex) {
+ throw new DataStoreException(ex.getMessage(), ex);
+ }
+ } else {
+ //resource is a datastore, we are sure of it
+ final DataStore store = (DataStore) resource;
+ store.close();
+
+ //clear cache, we need to do this loop in case the resource is
+ //not a FileSystemResource or wrongly declares the used files
+ for (Entry<Path,DataStore> entry : children.entrySet()) {
+ if (entry.getValue() == store) {
+ children.remove(entry.getKey());
+ break;
+ }
+ }
+
+ if (resource instanceof FileSystemResource) {
+ //delete resource files
+ final Path[] resourcePaths = ((FileSystemResource)
resource).getResourcePaths();
+ for (Path path : resourcePaths) {
+ try {
+ Files.walkFileTree(path, FILE_DELETE);
+ } catch (IOException ex) {
+ throw new DataStoreException(ex.getMessage(), ex);
+ }
+ }
+ }
+ }
+ }
+
+ }
+
}
Modified:
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/AbstractProvider.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/AbstractProvider.java?rev=1824245&r1=1824244&r2=1824245&view=diff
==============================================================================
---
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/AbstractProvider.java
[UTF-8] (original)
+++
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/AbstractProvider.java
[UTF-8] Wed Feb 14 15:18:02 2018
@@ -80,6 +80,7 @@ public abstract class AbstractProvider e
protected AbstractProvider(final String name, final int initialCapacity) {
super(name);
types = new HashMap<>(initialCapacity);
+ suffix.add("xml");
}
/**
Modified:
sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/folder/StoreTest.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/folder/StoreTest.java?rev=1824245&r1=1824244&r2=1824245&view=diff
==============================================================================
---
sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/folder/StoreTest.java
[UTF-8] (original)
+++
sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/folder/StoreTest.java
[UTF-8] Wed Feb 14 15:18:02 2018
@@ -26,6 +26,7 @@ import java.util.HashSet;
import java.util.Set;
import org.opengis.metadata.identification.Identification;
import org.apache.sis.metadata.iso.citation.Citations;
+import org.apache.sis.parameter.Parameters;
import org.apache.sis.storage.Aggregate;
import org.apache.sis.storage.Resource;
import org.apache.sis.storage.DataStoreException;
@@ -68,9 +69,9 @@ public final strictfp class StoreTest ex
*/
@Test
public void testComponents() throws URISyntaxException,
DataStoreException, IOException {
- final Set<String> identifiers = new HashSet<>(Arrays.asList("Sample
1", "Sample 2", "Sample 3", "data4"));
+ final Set<String> identifiers = new HashSet<>(Arrays.asList("proj",
"Sample 1", "Sample 2", "Sample 3", "data4"));
try (Store store = new Store(null, new
StorageConnector(testDirectory()))) {
- assertEquals("Expected three data stores.", 3,
store.components().size());
+ assertEquals("Expected three data stores.", 4,
store.components().size());
verifyContent(store, identifiers);
}
if (!identifiers.isEmpty()) {
@@ -78,6 +79,31 @@ public final strictfp class StoreTest ex
}
}
+ /**
+ * Verify that the restricting provider parameter is used.
+ *
+ * @throws URISyntaxException if the URL to test data can not be converted
to a path of the file system.
+ * @throws DataStoreException if an error occurred while reading the
resources.
+ * @throws IOException if an I/O error occurs.
+ */
+ @Test
+ public void testSearchProviderParameter() throws URISyntaxException,
DataStoreException, IOException {
+
+ {
+ final Set<String> identifiers = new
HashSet<>(Arrays.asList("Sample 1", "Sample 2", "Sample 3", "data4"));
+ final Parameters params =
Parameters.castOrWrap(FolderStoreProvider.PARAMETERS.createValue());
+ params.parameter("location").setValue(testDirectory());
+ params.parameter("provider").setValue("XML");
+ try (Store store = new Store(null, params)) {
+ assertEquals("Expected three data stores.", 3,
store.components().size());
+ verifyContent(store, identifiers);
+ }
+ if (!identifiers.isEmpty()) {
+ fail("Missing resources: " + identifiers);
+ }
+ }
+ }
+
/**
* Verifies that the given metadata contains one of the given identifiers.
* The identifiers that are found are removed from the given set.
Added:
sis/branches/JDK8/storage/sis-storage/src/test/resources/org/apache/sis/internal/storage/folder/test-data/proj.prj
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/test/resources/org/apache/sis/internal/storage/folder/test-data/proj.prj?rev=1824245&view=auto
==============================================================================
---
sis/branches/JDK8/storage/sis-storage/src/test/resources/org/apache/sis/internal/storage/folder/test-data/proj.prj
(added)
+++
sis/branches/JDK8/storage/sis-storage/src/test/resources/org/apache/sis/internal/storage/folder/test-data/proj.prj
Wed Feb 14 15:18:02 2018
@@ -0,0 +1 @@
+GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.0174532925199433]]
\ No newline at end of file