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
The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
new 342db9c59d Register an adapter for redirecting warnings from
filter/expression to data store listeners.
342db9c59d is described below
commit 342db9c59da1ba574d928614504fdea025f9c0b9
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Wed Oct 29 00:33:54 2025 +0100
Register an adapter for redirecting warnings from filter/expression to data
store listeners.
---
.../org/apache/sis/storage/AbstractFeatureSet.java | 27 ++++++++
.../storage/aggregate/ConcatenatedFeatureSet.java | 2 +-
.../apache/sis/storage/base/WarningAdapter.java | 77 ++++++++++++++++++++++
.../apache/sis/storage/event/StoreListeners.java | 2 +-
.../sis/storage/shapefile/ShapefileStore.java | 17 +++--
5 files changed, 119 insertions(+), 6 deletions(-)
diff --git
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/AbstractFeatureSet.java
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/AbstractFeatureSet.java
index b3a0c166ca..c3fb323315 100644
---
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/AbstractFeatureSet.java
+++
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/AbstractFeatureSet.java
@@ -16,12 +16,16 @@
*/
package org.apache.sis.storage;
+import java.util.Objects;
import java.util.Optional;
import java.util.OptionalLong;
+import java.util.function.Consumer;
import org.opengis.util.GenericName;
import org.opengis.metadata.Metadata;
import org.apache.sis.storage.event.StoreListeners;
import org.apache.sis.storage.base.MetadataBuilder;
+import org.apache.sis.storage.base.WarningAdapter;
+import org.apache.sis.filter.internal.shared.WarningEvent;
// Specific to the geoapi-3.1 and geoapi-4.0 branches:
import org.opengis.feature.FeatureType;
@@ -100,6 +104,29 @@ public abstract class AbstractFeatureSet extends
AbstractResource implements Fea
return OptionalLong.empty();
}
+ /**
+ * Requests a subset of features and/or feature properties from this
resource.
+ * The default implementation does the same work as the default method of
the {@link FeatureSet} interface,
+ * except that warnings are redirected to the {@linkplain #listeners
listeners}.
+ *
+ * @hidden
+ */
+ @Override
+ public FeatureSet subset(final Query query) throws
UnsupportedQueryException, DataStoreException {
+ if (Objects.requireNonNull(query) instanceof FeatureQuery) {
+ final ThreadLocal<Consumer<WarningEvent>> context =
WarningEvent.LISTENER;
+ final Consumer<WarningEvent> old = context.get();
+ try {
+ context.set(new WarningAdapter(listeners));
+ return ((FeatureQuery) query).execute(this);
+ } finally {
+ context.set(old);
+ }
+ } else {
+ throw new UnsupportedQueryException();
+ }
+ }
+
/**
* Invoked in a synchronized block the first time that {@code
getMetadata()} is invoked.
* The default implementation populates metadata based on information
provided by
diff --git
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/aggregate/ConcatenatedFeatureSet.java
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/aggregate/ConcatenatedFeatureSet.java
index 78a9582e76..f32afb8781 100644
---
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/aggregate/ConcatenatedFeatureSet.java
+++
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/aggregate/ConcatenatedFeatureSet.java
@@ -233,7 +233,7 @@ public class ConcatenatedFeatureSet extends
AggregatedFeatureSet {
*/
@Override
public FeatureSet subset(final Query query) throws DataStoreException {
- final FeatureSet[] subsets = new FeatureSet[sources.size()];
+ final var subsets = new FeatureSet[sources.size()];
boolean modified = false;
for (int i=0; i<subsets.length; i++) {
FeatureSet source = sources.get(i);
diff --git
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/WarningAdapter.java
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/WarningAdapter.java
new file mode 100644
index 0000000000..a29e9ff1e5
--- /dev/null
+++
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/WarningAdapter.java
@@ -0,0 +1,77 @@
+/*
+ * 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.logging.Level;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+import org.apache.sis.storage.event.StoreListeners;
+import org.apache.sis.filter.internal.shared.WarningEvent;
+
+
+/**
+ * Forwards to resource listeners the warnings that occurred during the
execution of expressions and filters.
+ * This is a bridge between the private filter/expression warning system to
public resource warning system.
+ *
+ * @author Martin Desruisseaux (Geomatys)
+ */
+public final class WarningAdapter implements Consumer<WarningEvent> {
+ /**
+ * The listeners where to send the warnings.
+ */
+ private final StoreListeners listeners;
+
+ /**
+ * Creates a new adapter from filter warnings to resource warnings.
+ *
+ * @param listeners the listeners where to send the warnings.
+ */
+ public WarningAdapter(final StoreListeners listeners) {
+ this.listeners = listeners;
+ }
+
+ /**
+ * Invoked when a warning occurred during the execution of filters or
expressions.
+ *
+ * @param event the warning event.
+ */
+ @Override
+ public void accept(final WarningEvent event) {
+ listeners.warning(event.recoverable ? Level.FINE : Level.WARNING,
null, event.exception);
+ }
+
+ /**
+ * Executes the given action with a redirection of all warnings to the
given listeners.
+ *
+ * @todo Replace by {@code ScopedValue.call(…)} when allowed to use JDK25.
+ *
+ * @param <V> the return value type of the given action.
+ * @param action the action to execute.
+ * @param listeners the listeners where to send the warnings.
+ * @return the return value of the given action.
+ */
+ public static <V> V execute(final Supplier<V> action, final StoreListeners
listeners) {
+ final ThreadLocal<Consumer<WarningEvent>> context =
WarningEvent.LISTENER;
+ final Consumer<WarningEvent> old = context.get();
+ try {
+ context.set(new WarningAdapter(listeners));
+ return action.get();
+ } finally {
+ context.set(old);
+ }
+ }
+}
diff --git
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/event/StoreListeners.java
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/event/StoreListeners.java
index 4674576d1b..246165ab57 100644
---
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/event/StoreListeners.java
+++
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/event/StoreListeners.java
@@ -885,7 +885,7 @@ public class StoreListeners implements Localized {
*
* @since 1.2
*/
- @SuppressWarnings("unchecked")
+ @SuppressWarnings({"unchecked", "element-type-mismatch"})
public synchronized void setUsableEventTypes(final Class<?>... permitted) {
ArgumentChecks.ensureNonEmpty("permitted", permitted);
final Set<Class<? extends StoreEvent>> current = permittedEventTypes;
diff --git
a/incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/ShapefileStore.java
b/incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/ShapefileStore.java
index 555d5ba7ef..877e9abb24 100644
---
a/incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/ShapefileStore.java
+++
b/incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/ShapefileStore.java
@@ -76,6 +76,7 @@ import org.apache.sis.filter.DefaultFilterFactory;
import org.apache.sis.filter.Optimization;
import org.apache.sis.filter.internal.shared.FunctionNames;
import org.apache.sis.filter.internal.shared.ListingPropertyVisitor;
+import org.apache.sis.filter.internal.shared.WarningEvent;
import org.apache.sis.io.stream.ChannelDataInput;
import org.apache.sis.io.stream.ChannelDataOutput;
import org.apache.sis.io.stream.IOUtilities;
@@ -127,6 +128,7 @@ import org.opengis.filter.LogicalOperatorName;
import org.opengis.filter.SpatialOperatorName;
import org.opengis.filter.ValueReference;
import org.apache.sis.geometry.wrapper.*;
+import org.apache.sis.storage.base.WarningAdapter;
/**
@@ -578,10 +580,17 @@ public final class ShapefileStore extends DataStore
implements WritableFeatureSe
//run optimizations
final Optimization optimization = new Optimization();
optimization.setFeatureType(type);
- selection = optimization.apply(selection);
- final Entry<Envelope, Filter> split =
extractBbox(selection);
- bbox = split.getKey();
- selection = split.getValue();
+ final ThreadLocal<Consumer<WarningEvent>> context =
WarningEvent.LISTENER;
+ final Consumer<WarningEvent> old = context.get();
+ try {
+ context.set(new WarningAdapter(listeners));
+ selection = optimization.apply(selection);
+ final Entry<Envelope, Filter> split =
extractBbox(selection);
+ bbox = split.getKey();
+ selection = split.getValue();
+ } finally {
+ context.set(old);
+ }
}
//extract field names