You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2023/11/22 16:30:46 UTC
(sis) 01/03: Partial support of `WritableAggregate` in GeoTIFF store. For now, only adding resources is supported, not removing them.
This is an automated email from the ASF dual-hosted git repository.
desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git
commit c13e1339eb942fb05a764219d7dadf3043703b8c
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Wed Nov 22 11:23:39 2023 +0100
Partial support of `WritableAggregate` in GeoTIFF store.
For now, only adding resources is supported, not removing them.
---
.../apache/sis/storage/geotiff/GeoTiffStore.java | 36 ++++++-
.../sis/storage/geotiff/GeoTiffStoreProvider.java | 5 +-
.../org/apache/sis/storage/geotiff/Reader.java | 8 ++
.../apache/sis/storage/geotiff/WritableStore.java | 83 +++++++++++++++
.../org/apache/sis/storage/geotiff/Writer.java | 16 +++
.../apache/sis/storage/base/SimpleAggregate.java | 57 ++++++++++
.../sis/storage/base/WritableAggregateSupport.java | 118 +++++++++++++++++++++
.../WritableGridCoverageSupport.java} | 29 +++--
.../org/apache/sis/storage/esri/WritableStore.java | 6 +-
.../apache/sis/storage/image/WritableResource.java | 6 +-
.../org/apache/sis/storage/internal/Resources.java | 6 ++
.../sis/storage/internal/Resources.properties | 1 +
.../sis/storage/internal/Resources_fr.properties | 1 +
13 files changed, 346 insertions(+), 26 deletions(-)
diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/GeoTiffStore.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/GeoTiffStore.java
index 55befa758f..50abb3c10c 100644
--- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/GeoTiffStore.java
+++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/GeoTiffStore.java
@@ -50,6 +50,7 @@ import org.apache.sis.storage.IllegalNameException;
import org.apache.sis.storage.base.MetadataBuilder;
import org.apache.sis.storage.base.StoreUtilities;
import org.apache.sis.storage.base.URIDataStore;
+import org.apache.sis.storage.base.GridResourceWrapper;
import org.apache.sis.storage.event.StoreEvent;
import org.apache.sis.storage.event.StoreListener;
import org.apache.sis.storage.event.StoreListeners;
@@ -513,13 +514,15 @@ public class GeoTiffStore extends DataStore implements Aggregate {
*/
private Writer writer() throws DataStoreException, IOException {
assert Thread.holdsLock(this);
+ final Reader r = reader;
Writer w = writer;
if (w == null) {
- final Reader r = reader;
if (r == null) {
throw new DataStoreClosedException(getLocale(), Constants.GEOTIFF, StandardOpenOption.WRITE);
}
writer = w = new Writer(r);
+ } else if (r != null) {
+ w.moveAfterExisting(r);
}
return w;
}
@@ -677,15 +680,17 @@ public class GeoTiffStore extends DataStore implements Aggregate {
* @param image the image to encode.
* @param grid mapping from pixel coordinates to "real world" coordinates, or {@code null} if none.
* @param metadata title, author and other information, or {@code null} if none.
+ * @return the effectively added resource. Using this resource may cause data to be reloaded.
* @throws ReadOnlyStorageException if this data store is read-only.
* @throws DataStoreException if the given {@code image} has a property which is not supported by this writer,
* or if an error occurred while writing to the output stream.
*
* @since 1.5
*/
- public synchronized void append(final RenderedImage image, final GridGeometry grid, final Metadata metadata)
+ public synchronized GridCoverageResource append(final RenderedImage image, final GridGeometry grid, final Metadata metadata)
throws DataStoreException
{
+ final int index;
try {
@SuppressWarnings("LocalVariableHidesMemberVariable") final Writer writer = writer();
@SuppressWarnings("LocalVariableHidesMemberVariable") final Reader reader = this.reader;
@@ -700,12 +705,34 @@ public class GeoTiffStore extends DataStore implements Aggregate {
if (reader != null) {
reader.offsetOfWrittenIFD(offsetIFD);
}
+ index = writer.imageIndex++;
} catch (IOException e) {
throw new DataStoreException(errors().getString(Errors.Keys.CanNotWriteFile_2, Constants.GEOTIFF, getDisplayName()), e);
}
if (components != null) {
components.incrementSize(1);
}
+ /*
+ * Returns a thin wrapper with only a reference to this store and the image index.
+ * The actual loading of the effectively added resource will be done only if requested.
+ */
+ return new GridResourceWrapper() {
+ /** The lock to use for synchronization purposes. */
+ @Override protected Object getSynchronizationLock() {
+ return GeoTiffStore.this;
+ }
+
+ /** Loads the effectively added resource when first requested. */
+ @Override protected GridCoverageResource createSource() throws DataStoreException {
+ try {
+ synchronized (GeoTiffStore.this) {
+ return reader().getImage(index);
+ }
+ } catch (IOException e) {
+ throw new DataStoreException(errorIO(e));
+ }
+ }
+ };
}
/**
@@ -715,6 +742,7 @@ public class GeoTiffStore extends DataStore implements Aggregate {
*
* @param coverage the grid coverage to encode.
* @param metadata title, author and other information, or {@code null} if none.
+ * @return the effectively added resource. Using this resource may cause data to be reloaded.
* @throws SubspaceNotSpecifiedException if the given grid coverage is not a two-dimensional slice.
* @throws ReadOnlyStorageException if this data store is read-only.
* @throws DataStoreException if the given {@code image} has a property which is not supported by this writer,
@@ -722,8 +750,8 @@ public class GeoTiffStore extends DataStore implements Aggregate {
*
* @since 1.5
*/
- public void append(final GridCoverage coverage, final Metadata metadata) throws DataStoreException {
- append(coverage.render(null), coverage.getGridGeometry(), metadata);
+ public GridCoverageResource append(final GridCoverage coverage, final Metadata metadata) throws DataStoreException {
+ return append(coverage.render(null), coverage.getGridGeometry(), metadata);
}
/**
diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/GeoTiffStoreProvider.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/GeoTiffStoreProvider.java
index e8fa8bb3bc..573b40de9f 100644
--- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/GeoTiffStoreProvider.java
+++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/GeoTiffStoreProvider.java
@@ -53,7 +53,7 @@ import org.apache.sis.parameter.ParameterBuilder;
*/
@StoreMetadata(formatName = Constants.GEOTIFF,
fileSuffixes = {"tiff", "tif"},
- capabilities = {Capability.READ, Capability.WRITE},
+ capabilities = {Capability.READ, Capability.WRITE, Capability.CREATE},
resourceTypes = {Aggregate.class, GridCoverageResource.class})
public class GeoTiffStoreProvider extends DataStoreProvider {
/**
@@ -162,6 +162,9 @@ public class GeoTiffStoreProvider extends DataStoreProvider {
*/
@Override
public DataStore open(final StorageConnector connector) throws DataStoreException {
+ if (URIDataStore.Provider.isWritable(connector, false)) {
+ return new WritableStore(this, connector);
+ }
return new GeoTiffStore(this, connector);
}
diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/Reader.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/Reader.java
index cbc96163e9..c6f7f390aa 100644
--- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/Reader.java
+++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/Reader.java
@@ -394,6 +394,14 @@ final class Reader extends IOBase {
}
}
+ /**
+ * Returns the number of images currently in the cache. This is not necessarily
+ * the total number of images in the TIFF file, unless {@link #endOfFile} is true.
+ */
+ final int getImageCacheSize() {
+ return images.size();
+ }
+
/**
* Returns the potentially pyramided <cite>Image File Directories</cite> (IFDs) at the given index.
* If the pyramid has already been initialized, then it is returned.
diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/WritableStore.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/WritableStore.java
new file mode 100644
index 0000000000..b7a7ea79d8
--- /dev/null
+++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/WritableStore.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.storage.geotiff;
+
+import org.apache.sis.storage.Resource;
+import org.apache.sis.storage.Aggregate;
+import org.apache.sis.storage.WritableAggregate;
+import org.apache.sis.storage.GridCoverageResource;
+import org.apache.sis.storage.StorageConnector;
+import org.apache.sis.storage.DataStoreException;
+import org.apache.sis.storage.base.WritableAggregateSupport;
+
+
+/**
+ * A GeoTIFF data store with write capabilities.
+ *
+ * @author Erwan Roussel (Geomatys)
+ * @author Martin Desruisseaux (Geomatys)
+ */
+final class WritableStore extends GeoTiffStore implements WritableAggregate {
+ /**
+ * Creates a new GeoTIFF store from the given file, URL or stream object.
+ * This constructor invokes {@link StorageConnector#closeAllExcept(Object)},
+ * keeping open only the needed resource.
+ *
+ * @param provider the factory that created this {@code WritableStore} instance, or {@code null} if unspecified.
+ * @param connector information about the storage (URL, stream, <i>etc</i>).
+ * @throws DataStoreException if an error occurred while opening the GeoTIFF file.
+ */
+ public WritableStore(final GeoTiffStoreProvider provider, final StorageConnector connector) throws DataStoreException {
+ super(provider, connector);
+ }
+
+ /**
+ * Adds a new {@code GridCoverageResource} in this {@code Aggregate}.
+ * The given {@link Resource} will be copied, and the <cite>effectively added</cite> resource returned.
+ *
+ * @param resource the resource to copy in this {@code Aggregate}.
+ * @return the effectively added resource. Using this resource may cause data to be reloaded.
+ * @throws DataStoreException if the given resource cannot be stored in this {@code Aggregate}.
+ */
+ @Override
+ public Resource add(final Resource resource) throws DataStoreException {
+ final var helper = new WritableAggregateSupport(this);
+ if (resource instanceof Aggregate) {
+ return helper.writeComponents((Aggregate) resource);
+ }
+ final GridCoverageResource gr = helper.asGridCoverage(resource);
+ return append(gr.read(null, null), gr.getMetadata());
+ }
+
+ /**
+ * Removes a {@code Resource} from this {@code Aggregate}.
+ * The given resource should be one of the instances returned by {@link #components()}.
+ * This operation is destructive in two aspects:
+ *
+ * <ul>
+ * <li>The {@link Resource} and it's data will be deleted from the {@link DataStore}.</li>
+ * <li>The given resource may become invalid and should not be used anymore after this method call.</li>
+ * </ul>
+ *
+ * @param resource child resource to remove from this {@code Aggregate}.
+ * @throws DataStoreException if the given resource could not be removed.
+ */
+ @Override
+ public void remove(Resource resource) throws DataStoreException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+}
diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/Writer.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/Writer.java
index 95d3d27a08..fd15ba2fcf 100644
--- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/Writer.java
+++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/Writer.java
@@ -133,6 +133,12 @@ final class Writer extends IOBase implements Flushable {
*/
private final boolean isBigTIFF;
+ /**
+ * Index of the image to write. This information is not needed by the writer, but is
+ * needed by {@link WritableStore} for determining the "effectively added resource".
+ */
+ int imageIndex;
+
/**
* Offset where to write the next image, or {@code null} if writing a mandatory image (the first one).
* If null, the IFD offset is assumed already written and the {@linkplain #output} already at that position.
@@ -209,8 +215,18 @@ final class Writer extends IOBase implements Flushable {
} catch (ClassCastException e) {
throw new ReadOnlyStorageException(store.readOrWriteOnly(0), e);
}
+ moveAfterExisting(reader);
+ }
+
+ /**
+ * Prepares the writer to write after the last images.
+ *
+ * @param reader the reader of images.
+ */
+ final void moveAfterExisting(final Reader reader) throws IOException, DataStoreException {
Class<? extends Number> type = isBigTIFF ? Long.class : Integer.class;
nextIFD = UpdatableWrite.ofZeroAt(reader.offsetOfWritableIFD(), type);
+ imageIndex = reader.getImageCacheSize();
}
/**
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/SimpleAggregate.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/SimpleAggregate.java
new file mode 100644
index 0000000000..203e936da8
--- /dev/null
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/SimpleAggregate.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.storage.base;
+
+import java.util.List;
+import java.util.Collection;
+import org.apache.sis.storage.Resource;
+import org.apache.sis.storage.Aggregate;
+import org.apache.sis.storage.AbstractResource;
+import org.apache.sis.util.internal.UnmodifiableArrayList;
+
+
+/**
+ * An aggregate with a list of components determined in advance.
+ *
+ * @author Martin Desruisseaux (Geomatys)
+ */
+final class SimpleAggregate extends AbstractResource implements Aggregate {
+ /**
+ * Components of this aggregate as an unmodifiable collection.
+ */
+ private final List<Resource> components;
+
+ /**
+ * Creates a new resource, potentially as a child of another resource.
+ *
+ * @param parent the parent resource, or {@code null} if none.
+ * @param components components of this aggregate. This collection is copied.
+ */
+ public SimpleAggregate(final Resource parent, final Collection<? extends Resource> components) {
+ super(parent);
+ this.components = UnmodifiableArrayList.wrap(components.toArray(Resource[]::new));
+ }
+
+ /**
+ * {@return the components of this aggregate}.
+ */
+ @Override
+ @SuppressWarnings("ReturnOfCollectionOrArrayField")
+ public Collection<Resource> components() {
+ return components;
+ }
+}
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/WritableAggregateSupport.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/WritableAggregateSupport.java
new file mode 100644
index 0000000000..651a8666ef
--- /dev/null
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/WritableAggregateSupport.java
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.storage.base;
+
+import java.util.Locale;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.lang.reflect.Modifier;
+import org.apache.sis.storage.Aggregate;
+import org.opengis.util.GenericName;
+import org.apache.sis.util.Classes;
+import org.apache.sis.util.Localized;
+import org.apache.sis.util.ArgumentChecks;
+import org.apache.sis.storage.Resource;
+import org.apache.sis.storage.WritableAggregate;
+import org.apache.sis.storage.GridCoverageResource;
+import org.apache.sis.storage.DataStoreException;
+import org.apache.sis.storage.IncompatibleResourceException;
+import org.apache.sis.storage.internal.Resources;
+import org.apache.sis.util.collection.BackingStoreException;
+
+
+/**
+ * Helper classes for the management of {@link WritableAggregate}.
+ *
+ * @author Martin Desruisseaux (Geomatys)
+ */
+public final class WritableAggregateSupport implements Localized {
+ /**
+ * The resource where to write.
+ */
+ private final WritableAggregate target;
+
+ /**
+ * Creates a new helper class.
+ *
+ * @param target the resource where to write.
+ */
+ public WritableAggregateSupport(final WritableAggregate target) {
+ this.target = target;
+ }
+
+ /**
+ * {@return the locale used by the targetresource for error messages, or {@code null} if unknown}.
+ */
+ @Override
+ public final Locale getLocale() {
+ return (target instanceof Localized) ? ((Localized) target).getLocale() : null;
+ }
+
+ /**
+ * Writes the components of the given aggregate.
+ *
+ * @param resource the aggregate to write.
+ * @return the effectively added aggregate.
+ * @throws DataStoreException if an error occurred while writing a component.
+ */
+ public Resource writeComponents(final Aggregate resource) throws DataStoreException {
+ try {
+ final Collection<? extends Resource> components = resource.components();
+ final var effectives = new ArrayList<Resource>(components.size());
+ for (final Resource component : components) {
+ effectives.add(target.add(component));
+ }
+ return new SimpleAggregate(target, effectives);
+ } catch (BackingStoreException e) {
+ throw e.unwrapOrRethrow(DataStoreException.class);
+ }
+ }
+
+ /**
+ * Returns the given resource as a grid coverage, or throws an exception if it cannot be cast.
+ *
+ * @param resource the resource which is required to be a grid coverage resource.
+ * @return the given resource after cast.
+ * @throws IncompatibleResourceException if the given resource is not for a grid coverage.
+ */
+ public GridCoverageResource asGridCoverage(final Resource resource) throws DataStoreException {
+ ArgumentChecks.ensureNonNull("resource", resource);
+ if (resource instanceof GridCoverageResource) {
+ return (GridCoverageResource) resource;
+ }
+ throw new IncompatibleResourceException(message(GridCoverageResource.class, resource));
+ }
+
+ /**
+ * Returns the error message for a resource that cannot be added to an aggregate.
+ *
+ * @param expected the expected type of resource.
+ * @param actual the actual resource.
+ * @return the error message to give to the exception to be thrown.
+ */
+ private String message(final Class<? extends Resource> expected, final Resource actual) throws DataStoreException {
+ Class<? extends Resource> type = actual.getClass();
+ for (Class<? extends Resource> t : Classes.getLeafInterfaces(type, Resource.class)) {
+ if (Modifier.isPublic(t.getModifiers())) {
+ type = t;
+ break;
+ }
+ }
+ return Resources.forLocale(getLocale()).getString(Resources.Keys.IllegalResourceTypeForAggregate_3,
+ target.getIdentifier().map(GenericName::toString).orElse(Classes.getShortName(actual.getClass())), expected, type);
+ }
+}
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/internal/WritableResourceSupport.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/WritableGridCoverageSupport.java
similarity index 91%
rename from endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/internal/WritableResourceSupport.java
rename to endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/WritableGridCoverageSupport.java
index a36e06002e..02f9b86e97 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/internal/WritableResourceSupport.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/WritableGridCoverageSupport.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.sis.storage.internal;
+package org.apache.sis.storage.base;
import java.util.Locale;
import java.io.IOException;
@@ -34,6 +34,7 @@ import org.apache.sis.storage.ReadOnlyStorageException;
import org.apache.sis.storage.ResourceAlreadyExistsException;
import org.apache.sis.storage.IncompatibleResourceException;
import org.apache.sis.storage.WritableGridCoverageResource;
+import org.apache.sis.storage.internal.Resources;
import org.apache.sis.io.stream.ChannelDataInput;
import org.apache.sis.io.stream.ChannelDataOutput;
import org.apache.sis.referencing.operation.matrix.AffineTransforms2D;
@@ -52,11 +53,11 @@ import org.opengis.coverage.CannotEvaluateException;
*
* @author Martin Desruisseaux (Geomatys)
*/
-public final class WritableResourceSupport implements Localized {
+public final class WritableGridCoverageSupport implements Localized {
/**
* The resource where to write.
*/
- private final GridCoverageResource resource;
+ private final GridCoverageResource target;
/**
* {@code true} if the {@link WritableGridCoverageResource.CommonOption.REPLACE} option has been specified.
@@ -73,11 +74,11 @@ public final class WritableResourceSupport implements Localized {
/**
* Creates a new helper class for the given options.
*
- * @param resource the resource where to write.
- * @param options configuration of the write operation.
+ * @param target the resource where to write.
+ * @param options configuration of the write operation.
*/
- public WritableResourceSupport(final GridCoverageResource resource, final WritableGridCoverageResource.Option[] options) {
- this.resource = resource;
+ public WritableGridCoverageSupport(final GridCoverageResource target, final WritableGridCoverageResource.Option[] options) {
+ this.target = target;
ArgumentChecks.ensureNonNull("options", options);
for (final WritableGridCoverageResource.Option option : options) {
replace |= WritableGridCoverageResource.CommonOption.REPLACE.equals(option);
@@ -91,13 +92,11 @@ public final class WritableResourceSupport implements Localized {
}
/**
- * Returns the locale used by the resource for error messages, or {@code null} if unknown.
- *
- * @return the locale used by the resource for error messages, or {@code null} if unknown.
+ * {@return the locale used by the target resource for error messages, or {@code null} if unknown}.
*/
@Override
public final Locale getLocale() {
- return (resource instanceof Localized) ? ((Localized) resource).getLocale() : null;
+ return (target instanceof Localized) ? ((Localized) target).getLocale() : null;
}
/**
@@ -144,7 +143,7 @@ public final class WritableResourceSupport implements Localized {
} else if (replace || isEmpty(input)) {
return true;
} else {
- Object identifier = resource.getIdentifier().orElse(null);
+ Object identifier = target.getIdentifier().orElse(null);
if (identifier == null && input != null) identifier = input.filename;
throw new ResourceAlreadyExistsException(Resources.forLocale(getLocale())
.getString(Resources.Keys.ResourceAlreadyExists_1, identifier));
@@ -175,7 +174,7 @@ public final class WritableResourceSupport implements Localized {
* @throws DataStoreException if an error occurred while reading or updating the coverage.
*/
public final GridCoverage update(final GridCoverage coverage) throws DataStoreException {
- final GridCoverage existing = resource.read(null, null);
+ final GridCoverage existing = target.read(null, null);
final CoverageCombiner combiner = new CoverageCombiner(existing);
try {
if (!combiner.acceptAll(coverage)) {
@@ -217,8 +216,8 @@ public final class WritableResourceSupport implements Localized {
* @throws DataStoreException if an error occurred while preparing the error message.
*/
public final String canNotWrite() throws DataStoreException {
- Object identifier = resource.getIdentifier().orElse(null);
- if (identifier == null) identifier = Classes.getShortClassName(resource);
+ Object identifier = target.getIdentifier().orElse(null);
+ if (identifier == null) identifier = Classes.getShortClassName(target);
return Resources.forLocale(getLocale()).getString(Resources.Keys.CanNotWriteResource_1, identifier);
}
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/WritableStore.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/WritableStore.java
index 0ecbda3df3..b0eaced8f3 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/WritableStore.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/WritableStore.java
@@ -33,7 +33,7 @@ import org.apache.sis.storage.DataStoreException;
import org.apache.sis.storage.DataStoreReferencingException;
import org.apache.sis.storage.WritableGridCoverageResource;
import org.apache.sis.storage.IncompatibleResourceException;
-import org.apache.sis.storage.internal.WritableResourceSupport;
+import org.apache.sis.storage.base.WritableGridCoverageSupport;
import org.apache.sis.io.stream.ChannelDataOutput;
import org.apache.sis.referencing.operation.matrix.Matrices;
import org.apache.sis.referencing.operation.transform.MathTransforms;
@@ -114,7 +114,7 @@ final class WritableStore extends AsciiGridStore implements WritableGridCoverage
*/
private static SequenceType getAffineCoefficients(
final Map<String,Object> header, final GridGeometry gg,
- final WritableResourceSupport h) throws DataStoreException
+ final WritableGridCoverageSupport h) throws DataStoreException
{
String xll = XLLCORNER;
String yll = YLLCORNER;
@@ -190,7 +190,7 @@ final class WritableStore extends AsciiGridStore implements WritableGridCoverage
*/
@Override
public synchronized void write(GridCoverage coverage, final Option... options) throws DataStoreException {
- final WritableResourceSupport h = new WritableResourceSupport(this, options); // Does argument validation.
+ final var h = new WritableGridCoverageSupport(this, options); // Does argument validation.
final int band = 0; // May become configurable in a future version.
try {
/*
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/image/WritableResource.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/image/WritableResource.java
index 761efdb517..18999f115b 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/image/WritableResource.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/image/WritableResource.java
@@ -23,7 +23,7 @@ import org.apache.sis.coverage.grid.GridCoverage;
import org.apache.sis.coverage.grid.GridGeometry;
import org.apache.sis.storage.DataStoreException;
import org.apache.sis.storage.WritableGridCoverageResource;
-import org.apache.sis.storage.internal.WritableResourceSupport;
+import org.apache.sis.storage.base.WritableGridCoverageSupport;
import org.apache.sis.storage.internal.Resources;
import org.apache.sis.storage.event.StoreListeners;
@@ -53,8 +53,8 @@ final class WritableResource extends WorldFileResource implements WritableGridCo
*/
@Override
public void write(GridCoverage coverage, final Option... options) throws DataStoreException {
- final WritableResourceSupport h = new WritableResourceSupport(this, options); // Does argument validation.
- final WritableStore store = (WritableStore) store();
+ final var h = new WritableGridCoverageSupport(this, options); // Does argument validation.
+ final var store = (WritableStore) store();
try {
synchronized (store) {
if (getImageIndex() != WorldFileStore.MAIN_IMAGE || (store.isMultiImages() != 0 && !h.replace(null))) {
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/internal/Resources.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/internal/Resources.java
index 4c22d38232..63506fd42f 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/internal/Resources.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/internal/Resources.java
@@ -275,6 +275,12 @@ public class Resources extends IndexedResourceBundle {
*/
public static final short IllegalOutputTypeForWriter_2 = 9;
+ /**
+ * The aggregate “{0}” does not accept resources of type ‘{2}’. An instance of ‘{1}’ was
+ * expected.
+ */
+ public static final short IllegalResourceTypeForAggregate_3 = 80;
+
/**
* All coverages must have the same grid geometry.
*/
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/internal/Resources.properties b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/internal/Resources.properties
index 977693931c..f76fb8118f 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/internal/Resources.properties
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/internal/Resources.properties
@@ -62,6 +62,7 @@ IllegalEventType_1 = This resource should not fire events of type
IllegalFeatureType_2 = The {0} data store does not accept features of type \u201c{1}\u201d.
IllegalInputTypeForReader_2 = The {0} reader does not accept inputs of type \u2018{1}\u2019.
IllegalOutputTypeForWriter_2 = The {0} writer does not accept outputs of type \u2018{1}\u2019.
+IllegalResourceTypeForAggregate_3 = The aggregate \u201c{0}\u201d does not accept resources of type \u2018{2}\u2019. An instance of \u2018{1}\u2019 was expected.
IncompatibleGridGeometry = All coverages must have the same grid geometry.
InconsistentNameComponents_2 = Components of the \u201c{1}\u201d name are inconsistent with those of the name previously binded in \u201c{0}\u201d data store.
InvalidExpression_2 = Invalid or unsupported \u201c{1}\u201d expression at index {0}.
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/internal/Resources_fr.properties b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/internal/Resources_fr.properties
index c096e18dfc..b950c2eb63 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/internal/Resources_fr.properties
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/internal/Resources_fr.properties
@@ -67,6 +67,7 @@ IllegalEventType_1 = Cette ressource ne devrait pas lancer des \u
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.
IllegalOutputTypeForWriter_2 = L\u2019encodeur {0} n\u2019accepte pas des sorties de type \u2018{1}\u2019.
+IllegalResourceTypeForAggregate_3 = L\u2019agr\u00e9gat \u00ab\u202f{0}\u202f\u00bb n\u2019accepte pas des ressources de type \u2018{2}\u2019. Une instance de \u2018{1}\u2019 \u00e9tait attendue.
IncompatibleGridGeometry = Toutes les couvertures de donn\u00e9es doivent avoir la m\u00eame g\u00e9om\u00e9trie de grille.
InvalidExpression_2 = Expression \u00ab\u202f{1}\u202f\u00bb invalide ou non-support\u00e9e \u00e0 l\u2019index {0}.
InconsistentNameComponents_2 = Les \u00e9l\u00e9ments qui composent le nom \u00ab\u202f{1}\u202f\u00bb ne sont pas coh\u00e9rents avec ceux du nom qui avait \u00e9t\u00e9 pr\u00e9c\u00e9demment li\u00e9 dans les donn\u00e9es de \u00ab\u202f{0}\u202f\u00bb.