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 d4a11f9abcfb2257ed24dcf542f12976da4b7b2e Author: Martin Desruisseaux <martin.desruisse...@geomatys.com> AuthorDate: Fri Sep 16 11:54:17 2022 +0200 Retrofit `MergeStrategy.update(…)` method as a method of `AggregatedResource` interface. The latter is not public yet, but a future evolution could retrofit in some public API. --- .../org/apache/sis/gui/dataset/ResourceItem.java | 2 +- .../sis/storage/aggregate/AggregatedResource.java | 22 ++++++++++++ .../aggregate/ConcatenatedGridResource.java | 37 ++++++++++++-------- .../sis/storage/aggregate/GroupAggregate.java | 39 ++++++++++++++-------- .../sis/storage/aggregate/MergeStrategy.java | 13 +++----- 5 files changed, 76 insertions(+), 37 deletions(-) diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/ResourceItem.java b/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/ResourceItem.java index de7d55a133..f0dd403600 100644 --- a/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/ResourceItem.java +++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/ResourceItem.java @@ -391,7 +391,7 @@ final class ResourceItem extends TreeItem<Resource> { case AGGREGATION: { if (resource instanceof UnstructuredAggregate) { result = ((UnstructuredAggregate) resource).getStructuredView(); - result = MergeStrategy.selectByTimeThenArea(null).update(result); + result = MergeStrategy.selectByTimeThenArea(null).apply(result); } break; } diff --git a/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/AggregatedResource.java b/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/AggregatedResource.java index 6dbbdecbe0..dbb3424521 100644 --- a/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/AggregatedResource.java +++ b/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/AggregatedResource.java @@ -16,6 +16,8 @@ */ package org.apache.sis.storage.aggregate; +import org.apache.sis.storage.Resource; + /** * The result of an aggregation computed by {@link CoverageAggregator}. @@ -28,8 +30,28 @@ package org.apache.sis.storage.aggregate; interface AggregatedResource { /** * Sets the name of the resource. + * This method is invoked by {@link GroupAggregate#simplify(CoverageAggregator)} when + * a aggregate node is excluded and we want to inherit the name of the excluded node. + * It should happen before the resource is published. * * @param name new name of the resource. */ void setName(String name); + + /** + * Returns a resource with the same data but the specified merge strategy. + * If this resource already uses the given strategy, then returns {@code this}. + * Otherwise returns a new resource. This resource is not modified by this method + * call because this method can be invoked after this resource has been published. + * + * <div class="note"><b>API design note:</b> + * we could try to design a common API for {@link org.apache.sis.storage.RasterLoadingStrategy} + * and {@link MergeStrategy}. But the former changes the state of the resource while the latter + * returns a new resource. This is because {@code RasterLoadingStrategy} does not change data, + * while {@link MergeStrategy} can change the data obtained from the resource.</div> + * + * @param strategy the new merge strategy to apply. + * @return resource using the specified strategy (may be {@code this}). + */ + Resource apply(MergeStrategy strategy); } diff --git a/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/ConcatenatedGridResource.java b/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/ConcatenatedGridResource.java index 16398e76d2..1194d5d210 100644 --- a/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/ConcatenatedGridResource.java +++ b/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/ConcatenatedGridResource.java @@ -18,6 +18,7 @@ package org.apache.sis.storage.aggregate; import java.util.List; import java.util.Arrays; +import java.util.Objects; import java.util.Optional; import org.opengis.geometry.Envelope; import org.opengis.metadata.Metadata; @@ -29,6 +30,7 @@ import org.apache.sis.coverage.grid.GridExtent; import org.apache.sis.coverage.grid.GridGeometry; import org.apache.sis.coverage.grid.GridRoundingMode; import org.apache.sis.geometry.ImmutableEnvelope; +import org.apache.sis.storage.Resource; import org.apache.sis.storage.AbstractGridCoverageResource; import org.apache.sis.storage.DataStoreException; import org.apache.sis.storage.GridCoverageResource; @@ -181,23 +183,30 @@ final class ConcatenatedGridResource extends AbstractGridCoverageResource implem * @param source the resource to copy. * @param strategy the new merge strategy. */ - ConcatenatedGridResource(final ConcatenatedGridResource source, final MergeStrategy strategy) { - super(source.listeners, false); - synchronized (source) { - name = source.name; - gridGeometry = source.gridGeometry; - sampleDimensions = source.sampleDimensions; - isConverted = source.isConverted; - slices = source.slices; - deferredLoading = source.deferredLoading; - locator = source.locator; - envelope = source.envelope; - envelopeIsEvaluated = source.envelopeIsEvaluated; - resolutions = source.resolutions; - } + private ConcatenatedGridResource(final ConcatenatedGridResource source, final MergeStrategy strategy) { + super(source.listeners, true); + name = source.name; + gridGeometry = source.gridGeometry; + sampleDimensions = source.sampleDimensions; + isConverted = source.isConverted; + slices = source.slices; + deferredLoading = source.deferredLoading; + locator = source.locator; + envelope = source.envelope; + envelopeIsEvaluated = source.envelopeIsEvaluated; + resolutions = source.resolutions; this.strategy = strategy; } + /** + * Returns a coverage with the same data than this coverage but a different merge strategy. + */ + @Override + public final synchronized Resource apply(final MergeStrategy s) { + if (Objects.equals(strategy, s)) return this; + return new ConcatenatedGridResource(this, s); + } + /** * Modifies the name of the resource. * This information is used for metadata. diff --git a/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/GroupAggregate.java b/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/GroupAggregate.java index 1b7e9aa6eb..f1921f617a 100644 --- a/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/GroupAggregate.java +++ b/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/GroupAggregate.java @@ -114,24 +114,37 @@ final class GroupAggregate extends AbstractResource implements Aggregate, Aggreg this.name = name; } + /** + * Creates a new resource with the same data than given resource but a different merge strategy. + * + * @param source the resource to copy. + * @param components components with the new merge strategy. + */ + private GroupAggregate(final GroupAggregate source, final Resource[] components) { + super(source.listeners, true); + name = source.name; + envelope = source.envelope; + envelopeIsEvaluated = source.envelopeIsEvaluated; + sampleDimensions = source.sampleDimensions; + componentsAreLeaves = source.componentsAreLeaves; + this.components = components; + } + /** * Returns an aggregate with the same data than this aggregate but a different merge strategy. */ - final synchronized GroupAggregate update(final MergeStrategy strategy) { + @Override + public final synchronized Resource apply(final MergeStrategy strategy) { boolean changed = false; - final GroupAggregate copy = new GroupAggregate(listeners, name, components.length); - for (int i=0; i < components.length; i++) { - final Resource component = components[i]; - changed |= ((copy.components[i] = strategy.update(component)) != component); - } - if (!changed) { - return this; + final Resource[] copy = components.clone(); + for (int i=0; i < copy.length; i++) { + final Resource c = copy[i]; + if (c instanceof AggregatedResource) { + final AggregatedResource component = (AggregatedResource) c; + changed |= ((copy[i] = component.apply(strategy)) != component); + } } - copy.componentsAreLeaves = componentsAreLeaves; - copy.envelope = envelope; - copy.envelopeIsEvaluated = envelopeIsEvaluated; - copy.sampleDimensions = sampleDimensions; - return copy; + return changed ? new GroupAggregate(this, copy) : this; } /** diff --git a/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/MergeStrategy.java b/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/MergeStrategy.java index 14d4dd8c66..6c80c7d835 100644 --- a/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/MergeStrategy.java +++ b/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/MergeStrategy.java @@ -155,7 +155,7 @@ public final class MergeStrategy { } /** - * Updates the merge strategy of the specified resource. + * Returns a resource with same data than specified resource but using this merge strategy. * If the given resource is an instance created by {@link CoverageAggregator} and uses a different strategy, * then a new resource using this merge strategy is returned. Otherwise the given resource is returned as-is. * The returned resource will share the same resources and caches than the given resource. @@ -163,14 +163,9 @@ public final class MergeStrategy { * @param resource the resource for which to update the merge strategy, or {@code null}. * @return resource with updated merge strategy, or {@code null} if the given resource was null. */ - public Resource update(Resource resource) { - if (resource instanceof ConcatenatedGridResource) { - final ConcatenatedGridResource c = (ConcatenatedGridResource) resource; - if (!equals(c.strategy)) { - resource = new ConcatenatedGridResource(c, this); - } - } else if (resource instanceof GroupAggregate) { - resource = ((GroupAggregate) resource).update(this); + public Resource apply(Resource resource) { + if (resource instanceof AggregatedResource) { + return ((AggregatedResource) resource).apply(this); } return resource; }