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/05/01 15:34:59 UTC
[sis] 01/01: Merge branch 'geoapi-3.1': remove contravariance in filters and expressions. https://issues.apache.org/jira/browse/SIS-578
This is an automated email from the ASF dual-hosted git repository.
desruisseaux pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sis.git
commit 410b3a1f6acefcbc61d5a45551482589661c6c97
Merge: ff2beab7ba 7d712579ff
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Mon May 1 16:29:33 2023 +0200
Merge branch 'geoapi-3.1': remove contravariance in filters and expressions.
https://issues.apache.org/jira/browse/SIS-578
.../apache/sis/feature/ExpressionOperation.java | 26 ++--
.../org/apache/sis/feature/FeatureOperations.java | 6 +-
.../org/apache/sis/filter/ArithmeticFunction.java | 30 ++--
.../org/apache/sis/filter/AssociationValue.java | 10 +-
.../java/org/apache/sis/filter/BinaryFunction.java | 25 ++-
.../apache/sis/filter/BinaryGeometryFilter.java | 73 +++++----
.../org/apache/sis/filter/BinarySpatialFilter.java | 16 +-
.../org/apache/sis/filter/ComparisonFilter.java | 83 +++++-----
.../org/apache/sis/filter/ConvertFunction.java | 10 +-
.../apache/sis/filter/DefaultFilterFactory.java | 168 ++++++++++-----------
.../org/apache/sis/filter/DefaultSortProperty.java | 8 +-
.../java/org/apache/sis/filter/DistanceFilter.java | 18 +--
.../java/org/apache/sis/filter/Expression.java | 11 +-
.../main/java/org/apache/sis/filter/Filter.java | 11 +-
.../java/org/apache/sis/filter/FilterLiteral.java | 5 +
.../java/org/apache/sis/filter/FilterNode.java | 86 -----------
.../org/apache/sis/filter/IdentifierFilter.java | 31 +++-
.../java/org/apache/sis/filter/LeafExpression.java | 10 +-
.../java/org/apache/sis/filter/LikeFilter.java | 23 ++-
.../java/org/apache/sis/filter/LogicalFilter.java | 78 ++++++----
.../java/org/apache/sis/filter/Optimization.java | 99 ++++++------
.../java/org/apache/sis/filter/PropertyValue.java | 12 +-
.../java/org/apache/sis/filter/TemporalFilter.java | 90 +++++------
.../java/org/apache/sis/filter/UnaryFunction.java | 28 ++--
.../java/org/apache/sis/filter/package-info.java | 2 +-
.../java/org/apache/sis/image/ImageCombiner.java | 11 +-
.../java/org/apache/sis/image/ImageProcessor.java | 6 +-
.../sis/internal/coverage/j2d/ObservableImage.java | 5 +-
.../sis/internal/filter/FunctionRegister.java | 4 +-
.../sis/internal/filter/GeometryConverter.java | 18 ++-
.../java/org/apache/sis/internal/filter/Node.java | 24 ++-
.../sis/internal/filter/SortByComparator.java | 8 +-
.../org/apache/sis/internal/filter/Visitor.java | 21 +--
.../internal/filter/sqlmm/FunctionWithSRID.java | 15 +-
.../internal/filter/sqlmm/GeometryConstructor.java | 18 ++-
.../sis/internal/filter/sqlmm/GeometryParser.java | 6 +-
.../sis/internal/filter/sqlmm/OneGeometry.java | 36 +++--
.../apache/sis/internal/filter/sqlmm/Registry.java | 4 +-
.../sis/internal/filter/sqlmm/ST_FromBinary.java | 6 +-
.../sis/internal/filter/sqlmm/ST_FromText.java | 6 +-
.../apache/sis/internal/filter/sqlmm/ST_Point.java | 22 ++-
.../sis/internal/filter/sqlmm/ST_Transform.java | 18 ++-
.../sis/internal/filter/sqlmm/SpatialFunction.java | 2 +-
.../sis/internal/filter/sqlmm/TwoGeometries.java | 40 +++--
.../sis/internal/filter/sqlmm/package-info.java | 2 +-
.../geoapi/filter/BetweenComparisonOperator.java | 6 +-
.../geoapi/filter/BinaryComparisonOperator.java | 4 +-
.../internal/geoapi/filter/FilterExpressions.java | 15 +-
.../apache/sis/internal/geoapi/filter/Literal.java | 2 +-
.../internal/geoapi/filter/LogicalOperator.java | 4 +-
.../sis/internal/geoapi/filter/SortProperty.java | 2 +-
.../sis/filter/BinarySpatialFilterTestCase.java | 7 +-
.../apache/sis/filter/IdentifierFilterTest.java | 4 +-
.../org/apache/sis/filter/LeafExpressionTest.java | 3 +-
.../org/apache/sis/filter/LogicalFilterTest.java | 27 +++-
.../java/org/apache/sis/filter/PeriodLiteral.java | 1 +
.../org/apache/sis/filter/TemporalFilterTest.java | 4 +-
.../internal/filter/sqlmm/RegistryTestCase.java | 4 +-
.../sis/internal/sql/feature/FeatureStream.java | 2 +-
.../sql/feature/SelectionClauseWriter.java | 19 +--
.../sql/feature/SelectionClauseWriterTest.java | 4 +-
.../java/org/apache/sis/storage/FeatureQuery.java | 24 +--
.../java/org/apache/sis/storage/FeatureSubset.java | 4 +-
.../sis/storage/aggregate/JoinFeatureSet.java | 8 +-
.../org/apache/sis/storage/FeatureQueryTest.java | 24 +--
65 files changed, 783 insertions(+), 616 deletions(-)
diff --cc core/sis-feature/src/main/java/org/apache/sis/feature/ExpressionOperation.java
index 964a1c143b,efbc5cb83c..0d0531ee49
--- a/core/sis-feature/src/main/java/org/apache/sis/feature/ExpressionOperation.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/feature/ExpressionOperation.java
@@@ -58,7 -64,7 +58,7 @@@ final class ExpressionOperation<V> exte
* The expression on which to delegate the execution of this operation.
*/
@SuppressWarnings("serial") // Not statically typed as serializable.
- private final Function<? super AbstractFeature, ? extends V> expression;
- private final Function<Feature, ? extends V> expression;
++ private final Function<AbstractFeature, ? extends V> expression;
/**
* The type of result of evaluating the expression.
@@@ -81,14 -88,14 +81,14 @@@
* @param result type of values computed by the expression.
*/
ExpressionOperation(final Map<String,?> identification,
- final Function<? super AbstractFeature, ? extends V> expression,
- final Function<Feature, ? extends V> expression,
- final AttributeType<? super V> result)
++ final Function<AbstractFeature, ? extends V> expression,
+ final DefaultAttributeType<? super V> result)
{
super(identification);
this.expression = expression;
this.result = result;
if (expression instanceof Expression<?,?>) {
- dependencies = DependencyFinder.search((Expression<Object,?>) expression);
- dependencies = DependencyFinder.search((Expression<Feature,?>) expression);
++ dependencies = DependencyFinder.search((Expression<AbstractFeature,?>) expression);
} else {
dependencies = Set.of();
}
@@@ -157,10 -164,8 +157,8 @@@
/**
* An expression visitor for finding all dependencies of a given expression.
* The dependencies are feature properties read by {@link ValueReference} nodes.
- *
- * @todo The first parameterized type should be {@code Feature} instead of {@code Object}.
*/
- private static final class DependencyFinder extends Visitor<Object, Collection<String>> {
- private static final class DependencyFinder extends Visitor<Feature, Collection<String>> {
++ private static final class DependencyFinder extends Visitor<AbstractFeature, Collection<String>> {
/**
* The unique instance.
*/
@@@ -172,7 -177,7 +170,7 @@@
* @param expression the expression for which to get dependencies.
* @return all dependencies recognized by this method.
*/
- static Set<String> search(final Expression<Object,?> expression) {
- static Set<String> search(final Expression<Feature,?> expression) {
++ static Set<String> search(final Expression<AbstractFeature,?> expression) {
final Set<String> dependencies = new HashSet<>();
VISITOR.visit(expression, dependencies);
return Set.copyOf(dependencies);
@@@ -183,13 -188,13 +181,13 @@@
*/
private DependencyFinder() {
setLogicalHandlers((f, dependencies) -> {
- final var filter = (LogicalOperator<Object>) f;
- for (Filter<Object> child : filter.getOperands()) {
- final var filter = (LogicalOperator<Feature>) f;
- for (Filter<Feature> child : filter.getOperands()) {
++ final var filter = (LogicalOperator<AbstractFeature>) f;
++ for (Filter<AbstractFeature> child : filter.getOperands()) {
visit(child, dependencies);
}
});
setExpressionHandler(FunctionNames.ValueReference, (e, dependencies) -> {
- final var expression = (ValueReference<Object,?>) e;
- final var expression = (ValueReference<Feature,?>) e;
++ final var expression = (ValueReference<AbstractFeature,?>) e;
final String propName = expression.getXPath();
if (!propName.trim().isEmpty()) {
dependencies.add(propName);
@@@ -201,8 -206,8 +199,8 @@@
* Fallback for all filters not explicitly handled by the setting applied in the constructor.
*/
@Override
- protected void typeNotFound(final Enum<?> type, final Filter<Object> filter, final Collection<String> dependencies) {
- for (final Expression<Object,?> f : filter.getExpressions()) {
- protected void typeNotFound(final CodeList<?> type, final Filter<Feature> filter, final Collection<String> dependencies) {
- for (final Expression<Feature,?> f : filter.getExpressions()) {
++ protected void typeNotFound(final Enum<?> type, final Filter<AbstractFeature> filter, final Collection<String> dependencies) {
++ for (final Expression<AbstractFeature,?> f : filter.getExpressions()) {
visit(f, dependencies);
}
}
@@@ -211,8 -216,8 +209,8 @@@
* Fallback for all expressions not explicitly handled by the setting applied in the constructor.
*/
@Override
- protected void typeNotFound(final String type, final Expression<Object,?> expression, final Collection<String> dependencies) {
- for (final Expression<Object,?> p : expression.getParameters()) {
- protected void typeNotFound(final String type, final Expression<Feature,?> expression, final Collection<String> dependencies) {
- for (final Expression<Feature,?> p : expression.getParameters()) {
++ protected void typeNotFound(final String type, final Expression<AbstractFeature,?> expression, final Collection<String> dependencies) {
++ for (final Expression<AbstractFeature,?> p : expression.getParameters()) {
visit(p, dependencies);
}
}
diff --cc core/sis-feature/src/main/java/org/apache/sis/feature/FeatureOperations.java
index 3ddd0ff779,b4ab1692d0..98b451ddd7
--- a/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureOperations.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureOperations.java
@@@ -286,9 -279,9 +286,9 @@@ public final class FeatureOperations ex
*
* @since 1.4
*/
- public static <V> Operation expression(final Map<String,?> identification,
- final Function<Feature, ? extends V> expression,
- final AttributeType<? super V> result)
+ public static <V> AbstractOperation expression(final Map<String,?> identification,
- final Function<? super AbstractFeature, ? extends V> expression,
++ final Function<AbstractFeature, ? extends V> expression,
+ final DefaultAttributeType<? super V> result)
{
ArgumentChecks.ensureNonNull("expression", expression);
return POOL.unique(new ExpressionOperation<>(identification, expression, result));
@@@ -310,9 -303,9 +310,9 @@@
*
* @since 1.4
*/
- public static <V> Operation expressionToResult(final Map<String,?> identification,
- final Expression<Feature, ?> expression,
- final AttributeType<V> result)
+ public static <V> AbstractOperation expressionToResult(final Map<String,?> identification,
- final Expression<? super AbstractFeature, ?> expression,
++ final Expression<AbstractFeature, ?> expression,
+ final DefaultAttributeType<V> result)
{
return expression(identification, expression.toValueType(result.getValueClass()), result);
}
diff --cc core/sis-feature/src/main/java/org/apache/sis/filter/ArithmeticFunction.java
index c418363a95,0cd6fa5a71..66fff6b926
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/ArithmeticFunction.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/ArithmeticFunction.java
@@@ -38,9 -39,9 +38,9 @@@ import org.apache.sis.feature.DefaultAt
*
* @author Johann Sorel (Geomatys)
* @author Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.4
*
- * @param <R> the type of resources (e.g. {@link org.opengis.feature.Feature}) used as inputs.
+ * @param <R> the type of resources (e.g. {@code Feature}) used as inputs.
*
* @since 1.1
*/
@@@ -141,12 -142,12 +141,12 @@@ abstract class ArithmeticFunction<R> ex
private static final long serialVersionUID = 5445433312445869201L;
/** Description of results of the {@code "Add"} expression. */
- private static final AttributeType<Number> TYPE = createNumericType(FunctionNames.Add);
- @Override protected AttributeType<Number> expectedType() {return TYPE;}
+ private static final DefaultAttributeType<Number> TYPE = createNumericType(FunctionNames.Add);
+ @Override protected DefaultAttributeType<Number> expectedType() {return TYPE;}
/** Creates a new expression for the {@code "Add"} operation. */
- Add(final Expression<? super R, ? extends Number> expression1,
- final Expression<? super R, ? extends Number> expression2)
+ Add(final Expression<R, ? extends Number> expression1,
+ final Expression<R, ? extends Number> expression2)
{
super(expression1, expression2);
}
@@@ -181,12 -182,12 +181,12 @@@
private static final long serialVersionUID = 3048878022726271508L;
/** Description of results of the {@code "Subtract"} expression. */
- private static final AttributeType<Number> TYPE = createNumericType(FunctionNames.Subtract);
- @Override protected AttributeType<Number> expectedType() {return TYPE;}
+ private static final DefaultAttributeType<Number> TYPE = createNumericType(FunctionNames.Subtract);
+ @Override protected DefaultAttributeType<Number> expectedType() {return TYPE;}
/** Creates a new expression for the {@code "Subtract"} operation. */
- Subtract(final Expression<? super R, ? extends Number> expression1,
- final Expression<? super R, ? extends Number> expression2)
+ Subtract(final Expression<R, ? extends Number> expression1,
+ final Expression<R, ? extends Number> expression2)
{
super(expression1, expression2);
}
@@@ -221,12 -222,12 +221,12 @@@
private static final long serialVersionUID = -1300022614832645625L;
/** Description of results of the {@code "Multiply"} expression. */
- private static final AttributeType<Number> TYPE = createNumericType(FunctionNames.Multiply);
- @Override protected AttributeType<Number> expectedType() {return TYPE;}
+ private static final DefaultAttributeType<Number> TYPE = createNumericType(FunctionNames.Multiply);
+ @Override protected DefaultAttributeType<Number> expectedType() {return TYPE;}
/** Creates a new expression for the {@code "Multiply"} operation. */
- Multiply(final Expression<? super R, ? extends Number> expression1,
- final Expression<? super R, ? extends Number> expression2)
+ Multiply(final Expression<R, ? extends Number> expression1,
+ final Expression<R, ? extends Number> expression2)
{
super(expression1, expression2);
}
@@@ -261,12 -262,12 +261,12 @@@
private static final long serialVersionUID = -7709291845568648891L;
/** Description of results of the {@code "Divide"} expression. */
- private static final AttributeType<Number> TYPE = createNumericType(FunctionNames.Divide);
- @Override protected AttributeType<Number> expectedType() {return TYPE;}
+ private static final DefaultAttributeType<Number> TYPE = createNumericType(FunctionNames.Divide);
+ @Override protected DefaultAttributeType<Number> expectedType() {return TYPE;}
/** Creates a new expression for the {@code "Divide"} operation. */
- Divide(final Expression<? super R, ? extends Number> expression1,
- final Expression<? super R, ? extends Number> expression2)
+ Divide(final Expression<R, ? extends Number> expression1,
+ final Expression<R, ? extends Number> expression2)
{
super(expression1, expression2);
}
diff --cc core/sis-feature/src/main/java/org/apache/sis/filter/AssociationValue.java
index e29b4c4be3,c8d714b8d5..a3f20b3055
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/AssociationValue.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/AssociationValue.java
@@@ -94,11 -94,14 +94,19 @@@ final class AssociationValue<V> extend
this.accessor = accessor;
}
+ @Override
+ public final ScopedName getFunctionName() {
+ return Name.VALUE_REFERENCE;
+ }
+
+ /**
+ * Returns the class of resources expected by this expression.
+ */
+ @Override
- public final Class<Feature> getResourceClass() {
- return Feature.class;
++ public final Class<AbstractFeature> getResourceClass() {
++ return AbstractFeature.class;
+ }
+
/**
* For {@link #toString()} implementation.
*/
diff --cc core/sis-feature/src/main/java/org/apache/sis/filter/BinaryFunction.java
index 8a542e5f17,a149e05cf9..ea158b7b0e
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/BinaryFunction.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/BinaryFunction.java
@@@ -35,9 -39,9 +35,9 @@@ import org.apache.sis.internal.filter.N
*
* @author Johann Sorel (Geomatys)
* @author Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.4
*
- * @param <R> the type of resources (e.g. {@link org.opengis.feature.Feature}) used as inputs.
+ * @param <R> the type of resources (e.g. {@code Feature}) used as inputs.
* @param <V1> the type of value computed by the first expression.
* @param <V2> the type of value computed by the second expression.
*
diff --cc core/sis-feature/src/main/java/org/apache/sis/filter/BinaryGeometryFilter.java
index b0be4785f0,5bb4d09ba6..457d8ea980
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/BinaryGeometryFilter.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/BinaryGeometryFilter.java
@@@ -42,14 -49,14 +43,14 @@@ import org.apache.sis.internal.geoapi.f
* @author Johann Sorel (Geomatys)
* @author Martin Desruisseaux (Geomatys)
* @author Alexis Manin (Geomatys)
- * @version 1.1
+ * @version 1.4
*
- * @param <R> the type of resources (e.g. {@link org.opengis.feature.Feature}) used as inputs.
+ * @param <R> the type of resources (e.g. {@code Feature}) used as inputs.
* @param <G> the implementation type of geometry objects.
*
* @since 1.1
*/
- abstract class BinaryGeometryFilter<R,G> extends FilterNode<R> implements Optimization.OnFilter<R> {
-abstract class BinaryGeometryFilter<R,G> extends Node implements SpatialOperator<R>, Optimization.OnFilter<R> {
++abstract class BinaryGeometryFilter<R,G> extends Node implements Optimization.OnFilter<R> {
/**
* For cross-version compatibility.
*/
@@@ -57,15 -64,19 +58,15 @@@
/**
* The first of the two expressions to be used by this function.
- *
- * @see BinarySpatialOperator#getOperand1()
*/
@SuppressWarnings("serial") // Most SIS implementations are serializable.
- protected final Expression<? super R, GeometryWrapper<G>> expression1;
+ protected final Expression<R, GeometryWrapper<G>> expression1;
/**
* The second of the two expressions to be used by this function.
- *
- * @see BinarySpatialOperator#getOperand2()
*/
@SuppressWarnings("serial") // Most SIS implementations are serializable.
- protected final Expression<? super R, GeometryWrapper<G>> expression2;
+ protected final Expression<R, GeometryWrapper<G>> expression2;
/**
* The preferred CRS and other context to use if geometry transformations are needed.
@@@ -211,7 -232,7 +222,7 @@@
final GeometryWrapper<G> geometry = wrapper.apply(null);
final GeometryWrapper<G> transformed = geometry.transform(targetCRS);
if (geometry != transformed) {
- literal = (Literal<? super R, ?>) Optimization.literal(transformed);
- literal = Optimization.literal(transformed);
++ literal = (Literal<R,?>) Optimization.literal(transformed);
if (literal == effective1) effective1 = literal;
else effective2 = literal;
}
diff --cc core/sis-feature/src/main/java/org/apache/sis/filter/BinarySpatialFilter.java
index a8e069b873,c9d7795038..e3ee507b62
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/BinarySpatialFilter.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/BinarySpatialFilter.java
@@@ -36,9 -38,9 +36,9 @@@ import org.apache.sis.internal.geoapi.f
*
* @author Johann Sorel (Geomatys)
* @author Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.4
*
- * @param <R> the type of resources (e.g. {@link org.opengis.feature.Feature}) used as inputs.
+ * @param <R> the type of resources (e.g. {@code Feature}) used as inputs.
* @param <G> the implementation type of geometry objects.
*
* @since 1.1
@@@ -112,14 -114,16 +112,14 @@@ final class BinarySpatialFilter<R,G> ex
/**
* Returns the first expression to be evaluated.
*/
- public Expression<? super R, ?> getOperand1() {
- @Override
+ public Expression<R,?> getOperand1() {
return original(expression1);
}
/**
* Returns the second expression to be evaluated.
*/
- public Expression<? super R, ?> getOperand2() {
- @Override
+ public Expression<R,?> getOperand2() {
return original(expression2);
}
diff --cc core/sis-feature/src/main/java/org/apache/sis/filter/ComparisonFilter.java
index 7934aaf5b9,b593f590c3..a3e29391a9
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/ComparisonFilter.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/ComparisonFilter.java
@@@ -36,12 -36,15 +36,13 @@@ import java.time.temporal.ChronoField
import java.time.temporal.Temporal;
import org.apache.sis.math.Fraction;
import org.apache.sis.util.ArgumentChecks;
+ import org.apache.sis.internal.filter.Node;
// Branch-dependent imports
-import org.opengis.filter.Filter;
-import org.opengis.filter.Expression;
-import org.opengis.filter.MatchAction;
-import org.opengis.filter.ComparisonOperatorName;
-import org.opengis.filter.BinaryComparisonOperator;
-import org.opengis.filter.BetweenComparisonOperator;
+import org.apache.sis.internal.geoapi.filter.MatchAction;
+import org.apache.sis.internal.geoapi.filter.ComparisonOperatorName;
+import org.apache.sis.internal.geoapi.filter.BinaryComparisonOperator;
+import org.apache.sis.internal.geoapi.filter.BetweenComparisonOperator;
/**
@@@ -65,9 -68,9 +66,9 @@@
*
* @author Johann Sorel (Geomatys)
* @author Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.4
*
- * @param <R> the type of resources (e.g. {@link org.opengis.feature.Feature}) used as inputs.
+ * @param <R> the type of resources (e.g. {@code Feature}) used as inputs.
*
* @since 1.1
*/
@@@ -810,10 -813,20 +811,24 @@@ abstract class ComparisonFilter<R> exte
this.upper = new LessThanOrEqualTo<>(expression, upper, true, MatchAction.ANY);
}
+ @Override public ComparisonOperatorName getOperatorType() {
+ return ComparisonOperatorName.PROPERTY_IS_BETWEEN;
+ }
+
+ /**
+ * Creates a new filter of the same type but different parameters.
+ */
+ @Override
+ public Filter<R> recreate(final Expression<R,?>[] effective) {
+ return new Between<>(effective[0], effective[1], effective[2]);
+ }
+
+ /** Returns the class of resources expected by this filter. */
+ @Override public final Class<? super R> getResourceClass() {
+ return specializedClass(lower.getResourceClass(),
+ upper.getResourceClass());
+ }
+
/**
* Returns the 3 children of this node. Since {@code lower.expression2}
* is the same as {@code upper.expression1}, that repetition is omitted.
diff --cc core/sis-feature/src/main/java/org/apache/sis/filter/ConvertFunction.java
index b163cadbfe,3095f4cb58..f58012ef8f
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/ConvertFunction.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/ConvertFunction.java
@@@ -36,9 -37,9 +36,9 @@@ import org.apache.sis.feature.DefaultFe
* Expression whose results are converted to a different type.
*
* @author Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.4
*
- * @param <R> the type of resources (e.g. {@link org.opengis.feature.Feature}) used as inputs.
+ * @param <R> the type of resources (e.g. {@code Feature}) used as inputs.
* @param <S> the type of value computed by the wrapped exception. This is the type to convert.
* @param <V> the type of value computed by this expression. This is the type after conversion.
*
diff --cc core/sis-feature/src/main/java/org/apache/sis/filter/DefaultFilterFactory.java
index f4f35e0cc4,7d56e36cc1..5bcf267097
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultFilterFactory.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultFilterFactory.java
@@@ -55,9 -48,9 +55,9 @@@ import org.apache.sis.internal.geoapi.f
*
* @author Johann Sorel (Geomatys)
* @author Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.4
*
- * @param <R> the type of resources (e.g. {@link org.opengis.feature.Feature}) to use as inputs.
+ * @param <R> the type of resources (e.g. {@link AbstractFeature}) to use as inputs.
* @param <G> base class of geometry objects. The implementation-neutral type is GeoAPI {@link Geometry},
* but this factory allows the use of other implementations such as JTS
* {@link org.locationtech.jts.geom.Geometry} or ESRI {@link com.esri.core.geometry.Geometry}.
@@@ -179,8 -185,29 +179,8 @@@ public abstract class DefaultFilterFact
* @return the predicate.
*/
@Override
- public ResourceId<Feature> resourceId(final String identifier) {
- return new IdentifierFilter(identifier);
- }
-
- /**
- * Creates a new predicate to identify an identifiable resource within a filter expression.
- * If {@code startTime} and {@code endTime} are non-null, the filter will select all versions
- * of a resource between the specified dates.
- *
- * @param identifier identifier of the resource that shall be selected by the predicate.
- * @param version version of the resource to select, or {@code null} for any version.
- * @param startTime start time of the resource to select, or {@code null} if none.
- * @param endTime end time of the resource to select, or {@code null} if none.
- * @return the predicate.
- *
- * @todo Current implementation ignores the version, start time and end time.
- * This limitation may be resolved in a future version.
- */
- @Override
- public ResourceId<Feature> resourceId(final String identifier, final Version version,
- final Instant startTime, final Instant endTime)
- {
+ public Filter<AbstractFeature> resourceId(final String identifier) {
- return new IdentifierFilter<>(identifier);
+ return new IdentifierFilter(identifier);
}
/**
@@@ -257,12 -250,19 +257,12 @@@
*
* @param expression1 the first of the two expressions to be used by this comparator.
* @param expression2 the second of the two expressions to be used by this comparator.
- * @param isMatchingCase specifies whether comparisons are case sensitive.
- * @param matchAction specifies how the comparisons shall be evaluated for a collection of values.
* @return a filter evaluating {@code expression1} = {@code expression2}.
- *
- * @see ComparisonOperatorName#PROPERTY_IS_EQUAL_TO
- * @todo Revisit if we can be more specific on the second parameterized type in expressions.
*/
- public Filter<R> equal(final Expression<? super R, ?> expression1,
- final Expression<? super R, ?> expression2)
- @Override
- public BinaryComparisonOperator<R> equal(final Expression<R,?> expression1,
- final Expression<R,?> expression2,
- boolean isMatchingCase, MatchAction matchAction)
++ public Filter<R> equal(final Expression<R,?> expression1,
++ final Expression<R,?> expression2)
{
- return new ComparisonFilter.EqualTo<>(expression1, expression2, isMatchingCase, matchAction);
+ return new ComparisonFilter.EqualTo<>(expression1, expression2, true, MatchAction.ANY);
}
/**
@@@ -270,12 -270,19 +270,12 @@@
*
* @param expression1 the first of the two expressions to be used by this comparator.
* @param expression2 the second of the two expressions to be used by this comparator.
- * @param isMatchingCase specifies whether comparisons are case sensitive.
- * @param matchAction specifies how the comparisons shall be evaluated for a collection of values.
* @return a filter evaluating {@code expression1} ≠ {@code expression2}.
- *
- * @see ComparisonOperatorName#PROPERTY_IS_NOT_EQUAL_TO
- * @todo Revisit if we can be more specific on the second parameterized type in expressions.
*/
- public Filter<R> notEqual(final Expression<? super R, ?> expression1,
- final Expression<? super R, ?> expression2)
- @Override
- public BinaryComparisonOperator<R> notEqual(final Expression<R,?> expression1,
- final Expression<R,?> expression2,
- boolean isMatchingCase, MatchAction matchAction)
++ public Filter<R> notEqual(final Expression<R,?> expression1,
++ final Expression<R,?> expression2)
{
- return new ComparisonFilter.NotEqualTo<>(expression1, expression2, isMatchingCase, matchAction);
+ return new ComparisonFilter.NotEqualTo<>(expression1, expression2, true, MatchAction.ANY);
}
/**
@@@ -283,12 -290,19 +283,12 @@@
*
* @param expression1 the first of the two expressions to be used by this comparator.
* @param expression2 the second of the two expressions to be used by this comparator.
- * @param isMatchingCase specifies whether comparisons are case sensitive.
- * @param matchAction specifies how the comparisons shall be evaluated for a collection of values.
* @return a filter evaluating {@code expression1} < {@code expression2}.
- *
- * @see ComparisonOperatorName#PROPERTY_IS_LESS_THAN
- * @todo Revisit if we can be more specific on the second parameterized type in expressions.
*/
- public Filter<R> less(final Expression<? super R, ?> expression1,
- final Expression<? super R, ?> expression2)
- @Override
- public BinaryComparisonOperator<R> less(final Expression<R,?> expression1,
- final Expression<R,?> expression2,
- boolean isMatchingCase, MatchAction matchAction)
++ public Filter<R> less(final Expression<R,?> expression1,
++ final Expression<R,?> expression2)
{
- return new ComparisonFilter.LessThan<>(expression1, expression2, isMatchingCase, matchAction);
+ return new ComparisonFilter.LessThan<>(expression1, expression2, true, MatchAction.ANY);
}
/**
@@@ -296,12 -310,19 +296,12 @@@
*
* @param expression1 the first of the two expressions to be used by this comparator.
* @param expression2 the second of the two expressions to be used by this comparator.
- * @param isMatchingCase specifies whether comparisons are case sensitive.
- * @param matchAction specifies how the comparisons shall be evaluated for a collection of values.
* @return a filter evaluating {@code expression1} > {@code expression2}.
- *
- * @see ComparisonOperatorName#PROPERTY_IS_GREATER_THAN
- * @todo Revisit if we can be more specific on the second parameterized type in expressions.
*/
- public Filter<R> greater(final Expression<? super R, ?> expression1,
- final Expression<? super R, ?> expression2)
- @Override
- public BinaryComparisonOperator<R> greater(final Expression<R,?> expression1,
- final Expression<R,?> expression2,
- boolean isMatchingCase, MatchAction matchAction)
++ public Filter<R> greater(final Expression<R,?> expression1,
++ final Expression<R,?> expression2)
{
- return new ComparisonFilter.GreaterThan<>(expression1, expression2, isMatchingCase, matchAction);
+ return new ComparisonFilter.GreaterThan<>(expression1, expression2, true, MatchAction.ANY);
}
/**
@@@ -309,12 -330,19 +309,12 @@@
*
* @param expression1 the first of the two expressions to be used by this comparator.
* @param expression2 the second of the two expressions to be used by this comparator.
- * @param isMatchingCase specifies whether comparisons are case sensitive.
- * @param matchAction specifies how the comparisons shall be evaluated for a collection of values.
* @return a filter evaluating {@code expression1} ≤ {@code expression2}.
- *
- * @see ComparisonOperatorName#PROPERTY_IS_LESS_THAN_OR_EQUAL_TO
- * @todo Revisit if we can be more specific on the second parameterized type in expressions.
*/
- public Filter<R> lessOrEqual(final Expression<? super R, ?> expression1,
- final Expression<? super R, ?> expression2)
- @Override
- public BinaryComparisonOperator<R> lessOrEqual(final Expression<R,?> expression1,
- final Expression<R,?> expression2,
- boolean isMatchingCase, MatchAction matchAction)
++ public Filter<R> lessOrEqual(final Expression<R,?> expression1,
++ final Expression<R,?> expression2)
{
- return new ComparisonFilter.LessThanOrEqualTo<>(expression1, expression2, isMatchingCase, matchAction);
+ return new ComparisonFilter.LessThanOrEqualTo<>(expression1, expression2, true, MatchAction.ANY);
}
/**
@@@ -322,12 -350,19 +322,12 @@@
*
* @param expression1 the first of the two expressions to be used by this comparator.
* @param expression2 the second of the two expressions to be used by this comparator.
- * @param isMatchingCase specifies whether comparisons are case sensitive.
- * @param matchAction specifies how the comparisons shall be evaluated for a collection of values.
* @return a filter evaluating {@code expression1} ≥ {@code expression2}.
- *
- * @see ComparisonOperatorName#PROPERTY_IS_GREATER_THAN_OR_EQUAL_TO
- * @todo Revisit if we can be more specific on the second parameterized type in expressions.
*/
- public Filter<R> greaterOrEqual(final Expression<? super R, ?> expression1,
- final Expression<? super R, ?> expression2)
- @Override
- public BinaryComparisonOperator<R> greaterOrEqual(final Expression<R,?> expression1,
- final Expression<R,?> expression2,
- boolean isMatchingCase, MatchAction matchAction)
++ public Filter<R> greaterOrEqual(final Expression<R,?> expression1,
++ final Expression<R,?> expression2)
{
- return new ComparisonFilter.GreaterThanOrEqualTo<>(expression1, expression2, isMatchingCase, matchAction);
+ return new ComparisonFilter.GreaterThanOrEqualTo<>(expression1, expression2, true, MatchAction.ANY);
}
/**
@@@ -340,26 -375,14 +340,26 @@@
* @return a filter evaluating ({@code expression} ≥ {@code lowerBoundary})
* & ({@code expression} ≤ {@code upperBoundary}).
*/
- public Filter<R> between(final Expression<? super R, ?> expression,
- final Expression<? super R, ?> lowerBoundary,
- final Expression<? super R, ?> upperBoundary)
- @Override
- public BetweenComparisonOperator<R> between(final Expression<R,?> expression,
- final Expression<R,?> lowerBoundary,
- final Expression<R,?> upperBoundary)
++ public Filter<R> between(final Expression<R,?> expression,
++ final Expression<R,?> lowerBoundary,
++ final Expression<R,?> upperBoundary)
{
return new ComparisonFilter.Between<>(expression, lowerBoundary, upperBoundary);
}
+ /**
+ * Character string comparison operator with pattern matching and default wildcards.
+ * The wildcard character is {@code '%'}, the single character is {@code '_'} and
+ * the escape character is {@code '\\'}. The comparison is case-sensitive.
+ *
+ * @param expression source of values to compare against the pattern.
+ * @param pattern pattern to match against expression values.
+ * @return a character string comparison operator with pattern matching.
+ */
- public Filter<R> like(Expression<? super R, ?> expression, String pattern) {
++ public Filter<R> like(Expression<R,?> expression, String pattern) {
+ return like(expression, pattern, '%', '_', '\\', true);
+ }
+
/**
* Character string comparison operator with pattern matching and specified wildcards.
*
@@@ -371,7 -394,8 +371,7 @@@
* @param isMatchingCase specifies how a filter expression processor should perform string comparisons.
* @return a character string comparison operator with pattern matching.
*/
- public Filter<R> like(final Expression<? super R, ?> expression, final String pattern,
- @Override
- public LikeOperator<R> like(final Expression<R,?> expression, final String pattern,
++ public Filter<R> like(final Expression<R,?> expression, final String pattern,
final char wildcard, final char singleChar, final char escape, final boolean isMatchingCase)
{
return new LikeFilter<>(expression, pattern, wildcard, singleChar, escape, isMatchingCase);
@@@ -384,7 -408,8 +384,7 @@@
* @param expression source of values to compare against {@code null}.
* @return a filter that checks if an expression's value is {@code null}.
*/
- public Filter<R> isNull(final Expression<? super R, ?> expression) {
- @Override
- public NullOperator<R> isNull(final Expression<R,?> expression) {
++ public Filter<R> isNull(final Expression<R,?> expression) {
return new UnaryFunction.IsNull<>(expression);
}
@@@ -412,7 -437,8 +412,7 @@@
* @see org.apache.sis.xml.NilObject
* @see org.apache.sis.xml.NilReason
*/
- public Filter<R> isNil(final Expression<? super R, ?> expression, final String nilReason) {
- @Override
- public NilOperator<R> isNil(final Expression<R,?> expression, final String nilReason) {
++ public Filter<R> isNil(final Expression<R,?> expression, final String nilReason) {
return new UnaryFunction.IsNil<>(expression, nilReason);
}
@@@ -422,8 -448,11 +422,8 @@@
* @param operand1 the first operand of the AND operation.
* @param operand2 the second operand of the AND operation.
* @return a filter evaluating {@code operand1 AND operand2}.
- *
- * @see LogicalOperatorName#AND
*/
- public Filter<R> and(final Filter<? super R> operand1, final Filter<? super R> operand2) {
- @Override
- public LogicalOperator<R> and(final Filter<R> operand1, final Filter<R> operand2) {
++ public Filter<R> and(final Filter<R> operand1, final Filter<R> operand2) {
ArgumentChecks.ensureNonNull("operand1", operand1);
ArgumentChecks.ensureNonNull("operand2", operand2);
return new LogicalFilter.And<>(operand1, operand2);
@@@ -435,8 -464,11 +435,8 @@@
* @param operands a collection of at least 2 operands.
* @return a filter evaluating {@code operand1 AND operand2 AND operand3}…
* @throws IllegalArgumentException if the given collection contains less than 2 elements.
- *
- * @see LogicalOperatorName#AND
*/
- public Filter<R> and(final Collection<? extends Filter<? super R>> operands) {
- @Override
- public LogicalOperator<R> and(final Collection<? extends Filter<R>> operands) {
++ public Filter<R> and(final Collection<? extends Filter<R>> operands) {
return new LogicalFilter.And<>(operands);
}
@@@ -446,8 -478,11 +446,8 @@@
* @param operand1 the first operand of the OR operation.
* @param operand2 the second operand of the OR operation.
* @return a filter evaluating {@code operand1 OR operand2}.
- *
- * @see LogicalOperatorName#OR
*/
- public Filter<R> or(final Filter<? super R> operand1, final Filter<? super R> operand2) {
- @Override
- public LogicalOperator<R> or(final Filter<R> operand1, final Filter<R> operand2) {
++ public Filter<R> or(final Filter<R> operand1, final Filter<R> operand2) {
ArgumentChecks.ensureNonNull("operand1", operand1);
ArgumentChecks.ensureNonNull("operand2", operand2);
return new LogicalFilter.Or<>(operand1, operand2);
@@@ -459,8 -494,11 +459,8 @@@
* @param operands a collection of at least 2 operands.
* @return a filter evaluating {@code operand1 OR operand2 OR operand3}…
* @throws IllegalArgumentException if the given collection contains less than 2 elements.
- *
- * @see LogicalOperatorName#OR
*/
- public Filter<R> or(final Collection<? extends Filter<? super R>> operands) {
- @Override
- public LogicalOperator<R> or(final Collection<? extends Filter<R>> operands) {
++ public Filter<R> or(final Collection<? extends Filter<R>> operands) {
return new LogicalFilter.Or<>(operands);
}
@@@ -469,8 -507,11 +469,8 @@@
*
* @param operand the operand of the NOT operation.
* @return a filter evaluating {@code NOT operand}.
- *
- * @see LogicalOperatorName#NOT
*/
- public Filter<R> not(final Filter<? super R> operand) {
- @Override
- public LogicalOperator<R> not(final Filter<R> operand) {
++ public Filter<R> not(final Filter<R> operand) {
return new LogicalFilter.Not<>(operand);
}
@@@ -481,8 -522,13 +481,8 @@@
* @param geometry expression fetching the geometry to check for interaction with bounds.
* @param bounds the bounds to check geometry against.
* @return a filter checking for any interactions between the bounding boxes.
- *
- * @see SpatialOperatorName#BBOX
- *
- * @todo Maybe the expression parameterized type should extend {@link Geometry}.
*/
- public Filter<R> bbox(final Expression<? super R, ? extends G> geometry, final Envelope bounds) {
- @Override
- public BinarySpatialOperator<R> bbox(final Expression<R, ? extends G> geometry, final Envelope bounds) {
++ public Filter<R> bbox(final Expression<R, ? extends G> geometry, final Envelope bounds) {
return new BinarySpatialFilter<>(library, geometry, bounds, wraparound);
}
@@@ -492,9 -538,12 +492,9 @@@
* @param geometry1 expression fetching the first geometry of the binary operator.
* @param geometry2 expression fetching the second geometry of the binary operator.
* @return a filter for the "Equals" operation between the two geometries.
- *
- * @see SpatialOperatorName#EQUALS
*/
- public Filter<R> equals(final Expression<? super R, ? extends G> geometry1,
- final Expression<? super R, ? extends G> geometry2)
- @Override
- public BinarySpatialOperator<R> equals(final Expression<R, ? extends G> geometry1,
- final Expression<R, ? extends G> geometry2)
++ public Filter<R> equals(final Expression<R, ? extends G> geometry1,
++ final Expression<R, ? extends G> geometry2)
{
return new BinarySpatialFilter<>(SpatialOperatorName.EQUALS, library, geometry1, geometry2);
}
@@@ -505,9 -554,12 +505,9 @@@
* @param geometry1 expression fetching the first geometry of the binary operator.
* @param geometry2 expression fetching the second geometry of the binary operator.
* @return a filter for the "Disjoint" operation between the two geometries.
- *
- * @see SpatialOperatorName#DISJOINT
*/
- public Filter<R> disjoint(final Expression<? super R, ? extends G> geometry1,
- final Expression<? super R, ? extends G> geometry2)
- @Override
- public BinarySpatialOperator<R> disjoint(final Expression<R, ? extends G> geometry1,
- final Expression<R, ? extends G> geometry2)
++ public Filter<R> disjoint(final Expression<R, ? extends G> geometry1,
++ final Expression<R, ? extends G> geometry2)
{
return new BinarySpatialFilter<>(SpatialOperatorName.DISJOINT, library, geometry1, geometry2);
}
@@@ -518,9 -570,12 +518,9 @@@
* @param geometry1 expression fetching the first geometry of the binary operator.
* @param geometry2 expression fetching the second geometry of the binary operator.
* @return a filter for the "Intersects" operation between the two geometries.
- *
- * @see SpatialOperatorName#INTERSECTS
*/
- public Filter<R> intersects(final Expression<? super R, ? extends G> geometry1,
- final Expression<? super R, ? extends G> geometry2)
- @Override
- public BinarySpatialOperator<R> intersects(final Expression<R, ? extends G> geometry1,
- final Expression<R, ? extends G> geometry2)
++ public Filter<R> intersects(final Expression<R, ? extends G> geometry1,
++ final Expression<R, ? extends G> geometry2)
{
return new BinarySpatialFilter<>(SpatialOperatorName.INTERSECTS, library, geometry1, geometry2);
}
@@@ -531,9 -586,12 +531,9 @@@
* @param geometry1 expression fetching the first geometry of the binary operator.
* @param geometry2 expression fetching the second geometry of the binary operator.
* @return a filter for the "Touches" operation between the two geometries.
- *
- * @see SpatialOperatorName#TOUCHES
*/
- public Filter<R> touches(final Expression<? super R, ? extends G> geometry1,
- final Expression<? super R, ? extends G> geometry2)
- @Override
- public BinarySpatialOperator<R> touches(final Expression<R, ? extends G> geometry1,
- final Expression<R, ? extends G> geometry2)
++ public Filter<R> touches(final Expression<R, ? extends G> geometry1,
++ final Expression<R, ? extends G> geometry2)
{
return new BinarySpatialFilter<>(SpatialOperatorName.TOUCHES, library, geometry1, geometry2);
}
@@@ -544,9 -602,12 +544,9 @@@
* @param geometry1 expression fetching the first geometry of the binary operator.
* @param geometry2 expression fetching the second geometry of the binary operator.
* @return a filter for the "Crosses" operation between the two geometries.
- *
- * @see SpatialOperatorName#CROSSES
*/
- public Filter<R> crosses(final Expression<? super R, ? extends G> geometry1,
- final Expression<? super R, ? extends G> geometry2)
- @Override
- public BinarySpatialOperator<R> crosses(final Expression<R, ? extends G> geometry1,
- final Expression<R, ? extends G> geometry2)
++ public Filter<R> crosses(final Expression<R, ? extends G> geometry1,
++ final Expression<R, ? extends G> geometry2)
{
return new BinarySpatialFilter<>(SpatialOperatorName.CROSSES, library, geometry1, geometry2);
}
@@@ -558,9 -619,12 +558,9 @@@
* @param geometry1 expression fetching the first geometry of the binary operator.
* @param geometry2 expression fetching the second geometry of the binary operator.
* @return a filter for the "Within" operation between the two geometries.
- *
- * @see SpatialOperatorName#WITHIN
*/
- public Filter<R> within(final Expression<? super R, ? extends G> geometry1,
- final Expression<? super R, ? extends G> geometry2)
- @Override
- public BinarySpatialOperator<R> within(final Expression<R, ? extends G> geometry1,
- final Expression<R, ? extends G> geometry2)
++ public Filter<R> within(final Expression<R, ? extends G> geometry1,
++ final Expression<R, ? extends G> geometry2)
{
return new BinarySpatialFilter<>(SpatialOperatorName.WITHIN, library, geometry1, geometry2);
}
@@@ -571,9 -635,12 +571,9 @@@
* @param geometry1 expression fetching the first geometry of the binary operator.
* @param geometry2 expression fetching the second geometry of the binary operator.
* @return a filter for the "Contains" operation between the two geometries.
- *
- * @see SpatialOperatorName#CONTAINS
*/
- public Filter<R> contains(final Expression<? super R, ? extends G> geometry1,
- final Expression<? super R, ? extends G> geometry2)
- @Override
- public BinarySpatialOperator<R> contains(final Expression<R, ? extends G> geometry1,
- final Expression<R, ? extends G> geometry2)
++ public Filter<R> contains(final Expression<R, ? extends G> geometry1,
++ final Expression<R, ? extends G> geometry2)
{
return new BinarySpatialFilter<>(SpatialOperatorName.CONTAINS, library, geometry1, geometry2);
}
@@@ -585,9 -652,12 +585,9 @@@
* @param geometry1 expression fetching the first geometry of the binary operator.
* @param geometry2 expression fetching the second geometry of the binary operator.
* @return a filter for the "Overlaps" operation between the two geometries.
- *
- * @see SpatialOperatorName#OVERLAPS
*/
- public Filter<R> overlaps(final Expression<? super R, ? extends G> geometry1,
- final Expression<? super R, ? extends G> geometry2)
- @Override
- public BinarySpatialOperator<R> overlaps(final Expression<R, ? extends G> geometry1,
- final Expression<R, ? extends G> geometry2)
++ public Filter<R> overlaps(final Expression<R, ? extends G> geometry1,
++ final Expression<R, ? extends G> geometry2)
{
return new BinarySpatialFilter<>(SpatialOperatorName.OVERLAPS, library, geometry1, geometry2);
}
@@@ -601,10 -671,13 +601,10 @@@
* @param distance minimal distance for evaluating the expression as {@code true}.
* @return operator that evaluates to {@code true} when all of a feature's geometry
* is more distant than the given distance from the second geometry.
- *
- * @see DistanceOperatorName#BEYOND
*/
- public Filter<R> beyond(final Expression<? super R, ? extends G> geometry1,
- final Expression<? super R, ? extends G> geometry2,
- @Override
- public DistanceOperator<R> beyond(final Expression<R, ? extends G> geometry1,
- final Expression<R, ? extends G> geometry2,
- final Quantity<Length> distance)
++ public Filter<R> beyond(final Expression<R, ? extends G> geometry1,
++ final Expression<R, ? extends G> geometry2,
+ final Quantity<Length> distance)
{
return new DistanceFilter<>(DistanceOperatorName.BEYOND, library, geometry1, geometry2, distance);
}
@@@ -618,10 -691,13 +618,10 @@@
* @param distance maximal distance for evaluating the expression as {@code true}.
* @return operator that evaluates to {@code true} when any part of the feature's geometry
* lies within the given distance of the second geometry.
- *
- * @see DistanceOperatorName#WITHIN
*/
- public Filter<R> within(final Expression<? super R, ? extends G> geometry1,
- final Expression<? super R, ? extends G> geometry2,
- @Override
- public DistanceOperator<R> within(final Expression<R, ? extends G> geometry1,
- final Expression<R, ? extends G> geometry2,
- final Quantity<Length> distance)
++ public Filter<R> within(final Expression<R, ? extends G> geometry1,
++ final Expression<R, ? extends G> geometry2,
+ final Quantity<Length> distance)
{
return new DistanceFilter<>(DistanceOperatorName.WITHIN, library, geometry1, geometry2, distance);
}
@@@ -632,9 -708,12 +632,9 @@@
* @param time1 expression fetching the first temporal value.
* @param time2 expression fetching the second temporal value.
* @return a filter for the "After" operator between the two temporal values.
- *
- * @see TemporalOperatorName#AFTER
*/
- public Filter<R> after(final Expression<? super R, ? extends T> time1,
- final Expression<? super R, ? extends T> time2)
- @Override
- public TemporalOperator<R> after(final Expression<R, ? extends T> time1,
- final Expression<R, ? extends T> time2)
++ public Filter<R> after(final Expression<R, ? extends T> time1,
++ final Expression<R, ? extends T> time2)
{
return new TemporalFilter.After<>(time1, time2);
}
@@@ -645,9 -724,12 +645,9 @@@
* @param time1 expression fetching the first temporal value.
* @param time2 expression fetching the second temporal value.
* @return a filter for the "Before" operator between the two temporal values.
- *
- * @see TemporalOperatorName#BEFORE
*/
- public Filter<R> before(final Expression<? super R, ? extends T> time1,
- final Expression<? super R, ? extends T> time2)
- @Override
- public TemporalOperator<R> before(final Expression<R, ? extends T> time1,
- final Expression<R, ? extends T> time2)
++ public Filter<R> before(final Expression<R, ? extends T> time1,
++ final Expression<R, ? extends T> time2)
{
return new TemporalFilter.Before<>(time1, time2);
}
@@@ -658,9 -740,12 +658,9 @@@
* @param time1 expression fetching the first temporal value.
* @param time2 expression fetching the second temporal value.
* @return a filter for the "Begins" operator between the two temporal values.
- *
- * @see TemporalOperatorName#BEGINS
*/
- public Filter<R> begins(final Expression<? super R, ? extends T> time1,
- final Expression<? super R, ? extends T> time2)
- @Override
- public TemporalOperator<R> begins(final Expression<R, ? extends T> time1,
- final Expression<R, ? extends T> time2)
++ public Filter<R> begins(final Expression<R, ? extends T> time1,
++ final Expression<R, ? extends T> time2)
{
return new TemporalFilter.Begins<>(time1, time2);
}
@@@ -671,9 -756,12 +671,9 @@@
* @param time1 expression fetching the first temporal value.
* @param time2 expression fetching the second temporal value.
* @return a filter for the "BegunBy" operator between the two temporal values.
- *
- * @see TemporalOperatorName#BEGUN_BY
*/
- public Filter<R> begunBy(final Expression<? super R, ? extends T> time1,
- final Expression<? super R, ? extends T> time2)
- @Override
- public TemporalOperator<R> begunBy(final Expression<R, ? extends T> time1,
- final Expression<R, ? extends T> time2)
++ public Filter<R> begunBy(final Expression<R, ? extends T> time1,
++ final Expression<R, ? extends T> time2)
{
return new TemporalFilter.BegunBy<>(time1, time2);
}
@@@ -684,9 -772,12 +684,9 @@@
* @param time1 expression fetching the first temporal value.
* @param time2 expression fetching the second temporal value.
* @return a filter for the "TContains" operator between the two temporal values.
- *
- * @see TemporalOperatorName#CONTAINS
*/
- public Filter<R> tcontains(final Expression<? super R, ? extends T> time1,
- final Expression<? super R, ? extends T> time2)
- @Override
- public TemporalOperator<R> tcontains(final Expression<R, ? extends T> time1,
- final Expression<R, ? extends T> time2)
++ public Filter<R> tcontains(final Expression<R, ? extends T> time1,
++ final Expression<R, ? extends T> time2)
{
return new TemporalFilter.Contains<>(time1, time2);
}
@@@ -697,9 -788,12 +697,9 @@@
* @param time1 expression fetching the first temporal value.
* @param time2 expression fetching the second temporal value.
* @return a filter for the "During" operator between the two temporal values.
- *
- * @see TemporalOperatorName#DURING
*/
- public Filter<R> during(final Expression<? super R, ? extends T> time1,
- final Expression<? super R, ? extends T> time2)
- @Override
- public TemporalOperator<R> during(final Expression<R, ? extends T> time1,
- final Expression<R, ? extends T> time2)
++ public Filter<R> during(final Expression<R, ? extends T> time1,
++ final Expression<R, ? extends T> time2)
{
return new TemporalFilter.During<>(time1, time2);
}
@@@ -710,9 -804,12 +710,9 @@@
* @param time1 expression fetching the first temporal value.
* @param time2 expression fetching the second temporal value.
* @return a filter for the "TEquals" operator between the two temporal values.
- *
- * @see TemporalOperatorName#EQUALS
*/
- public Filter<R> tequals(final Expression<? super R, ? extends T> time1,
- final Expression<? super R, ? extends T> time2)
- @Override
- public TemporalOperator<R> tequals(final Expression<R, ? extends T> time1,
- final Expression<R, ? extends T> time2)
++ public Filter<R> tequals(final Expression<R, ? extends T> time1,
++ final Expression<R, ? extends T> time2)
{
return new TemporalFilter.Equals<>(time1, time2);
}
@@@ -723,9 -820,12 +723,9 @@@
* @param time1 expression fetching the first temporal value.
* @param time2 expression fetching the second temporal value.
* @return a filter for the "TOverlaps" operator between the two temporal values.
- *
- * @see TemporalOperatorName#OVERLAPS
*/
- public Filter<R> toverlaps(final Expression<? super R, ? extends T> time1,
- final Expression<? super R, ? extends T> time2)
- @Override
- public TemporalOperator<R> toverlaps(final Expression<R, ? extends T> time1,
- final Expression<R, ? extends T> time2)
++ public Filter<R> toverlaps(final Expression<R, ? extends T> time1,
++ final Expression<R, ? extends T> time2)
{
return new TemporalFilter.Overlaps<>(time1, time2);
}
@@@ -736,9 -836,12 +736,9 @@@
* @param time1 expression fetching the first temporal value.
* @param time2 expression fetching the second temporal value.
* @return a filter for the "Meets" operator between the two temporal values.
- *
- * @see TemporalOperatorName#MEETS
*/
- public Filter<R> meets(final Expression<? super R, ? extends T> time1,
- final Expression<? super R, ? extends T> time2)
- @Override
- public TemporalOperator<R> meets(final Expression<R, ? extends T> time1,
- final Expression<R, ? extends T> time2)
++ public Filter<R> meets(final Expression<R, ? extends T> time1,
++ final Expression<R, ? extends T> time2)
{
return new TemporalFilter.Meets<>(time1, time2);
}
@@@ -749,9 -852,12 +749,9 @@@
* @param time1 expression fetching the first temporal value.
* @param time2 expression fetching the second temporal value.
* @return a filter for the "Ends" operator between the two temporal values.
- *
- * @see TemporalOperatorName#ENDS
*/
- public Filter<R> ends(final Expression<? super R, ? extends T> time1,
- final Expression<? super R, ? extends T> time2)
- @Override
- public TemporalOperator<R> ends(final Expression<R, ? extends T> time1,
- final Expression<R, ? extends T> time2)
++ public Filter<R> ends(final Expression<R, ? extends T> time1,
++ final Expression<R, ? extends T> time2)
{
return new TemporalFilter.Ends<>(time1, time2);
}
@@@ -762,9 -868,12 +762,9 @@@
* @param time1 expression fetching the first temporal value.
* @param time2 expression fetching the second temporal value.
* @return a filter for the "OverlappedBy" operator between the two temporal values.
- *
- * @see TemporalOperatorName#OVERLAPPED_BY
*/
- public Filter<R> overlappedBy(final Expression<? super R, ? extends T> time1,
- final Expression<? super R, ? extends T> time2)
- @Override
- public TemporalOperator<R> overlappedBy(final Expression<R, ? extends T> time1,
- final Expression<R, ? extends T> time2)
++ public Filter<R> overlappedBy(final Expression<R, ? extends T> time1,
++ final Expression<R, ? extends T> time2)
{
return new TemporalFilter.OverlappedBy<>(time1, time2);
}
@@@ -775,9 -884,12 +775,9 @@@
* @param time1 expression fetching the first temporal value.
* @param time2 expression fetching the second temporal value.
* @return a filter for the "MetBy" operator between the two temporal values.
- *
- * @see TemporalOperatorName#MET_BY
*/
- public Filter<R> metBy(final Expression<? super R, ? extends T> time1,
- final Expression<? super R, ? extends T> time2)
- @Override
- public TemporalOperator<R> metBy(final Expression<R, ? extends T> time1,
- final Expression<R, ? extends T> time2)
++ public Filter<R> metBy(final Expression<R, ? extends T> time1,
++ final Expression<R, ? extends T> time2)
{
return new TemporalFilter.MetBy<>(time1, time2);
}
@@@ -788,9 -900,12 +788,9 @@@
* @param time1 expression fetching the first temporal value.
* @param time2 expression fetching the second temporal value.
* @return a filter for the "EndedBy" operator between the two temporal values.
- *
- * @see TemporalOperatorName#ENDED_BY
*/
- public Filter<R> endedBy(final Expression<? super R, ? extends T> time1,
- final Expression<? super R, ? extends T> time2)
- @Override
- public TemporalOperator<R> endedBy(final Expression<R, ? extends T> time1,
- final Expression<R, ? extends T> time2)
++ public Filter<R> endedBy(final Expression<R, ? extends T> time1,
++ final Expression<R, ? extends T> time2)
{
return new TemporalFilter.EndedBy<>(time1, time2);
}
@@@ -802,9 -917,12 +802,9 @@@
* @param time1 expression fetching the first temporal value.
* @param time2 expression fetching the second temporal value.
* @return a filter for the "AnyInteracts" operator between the two temporal values.
- *
- * @see TemporalOperatorName#ANY_INTERACTS
*/
- public Filter<R> anyInteracts(final Expression<? super R, ? extends T> time1,
- final Expression<? super R, ? extends T> time2)
- @Override
- public TemporalOperator<R> anyInteracts(final Expression<R, ? extends T> time1,
- final Expression<R, ? extends T> time2)
++ public Filter<R> anyInteracts(final Expression<R, ? extends T> time1,
++ final Expression<R, ? extends T> time2)
{
return new TemporalFilter.AnyInteracts<>(time1, time2);
}
@@@ -815,9 -933,12 +815,9 @@@
* @param operand1 expression fetching the first number.
* @param operand2 expression fetching the second number.
* @return an expression for the "Add" function between the two numerical values.
- *
- * @todo Should we really restrict the type to {@link Number}?
*/
- public Expression<R,Number> add(final Expression<? super R, ? extends Number> operand1,
- final Expression<? super R, ? extends Number> operand2)
- @Override
+ public Expression<R,Number> add(final Expression<R, ? extends Number> operand1,
+ final Expression<R, ? extends Number> operand2)
{
return new ArithmeticFunction.Add<>(operand1, operand2);
}
@@@ -828,9 -949,12 +828,9 @@@
* @param operand1 expression fetching the first number.
* @param operand2 expression fetching the second number.
* @return an expression for the "Subtract" function between the two numerical values.
- *
- * @todo Should we really restrict the type to {@link Number}?
*/
- public Expression<R,Number> subtract(final Expression<? super R, ? extends Number> operand1,
- final Expression<? super R, ? extends Number> operand2)
- @Override
+ public Expression<R,Number> subtract(final Expression<R, ? extends Number> operand1,
+ final Expression<R, ? extends Number> operand2)
{
return new ArithmeticFunction.Subtract<>(operand1, operand2);
}
@@@ -841,9 -965,12 +841,9 @@@
* @param operand1 expression fetching the first number.
* @param operand2 expression fetching the second number.
* @return an expression for the "Multiply" function between the two numerical values.
- *
- * @todo Should we really restrict the type to {@link Number}?
*/
- public Expression<R,Number> multiply(final Expression<? super R, ? extends Number> operand1,
- final Expression<? super R, ? extends Number> operand2)
- @Override
+ public Expression<R,Number> multiply(final Expression<R, ? extends Number> operand1,
+ final Expression<R, ? extends Number> operand2)
{
return new ArithmeticFunction.Multiply<>(operand1, operand2);
}
@@@ -854,9 -981,12 +854,9 @@@
* @param operand1 expression fetching the first number.
* @param operand2 expression fetching the second number.
* @return an expression for the "Divide" function between the two numerical values.
- *
- * @todo Should we really restrict the type to {@link Number}?
*/
- public Expression<R,Number> divide(final Expression<? super R, ? extends Number> operand1,
- final Expression<? super R, ? extends Number> operand2)
- @Override
+ public Expression<R,Number> divide(final Expression<R, ? extends Number> operand1,
+ final Expression<R, ? extends Number> operand2)
{
return new ArithmeticFunction.Divide<>(operand1, operand2);
}
@@@ -899,7 -1001,8 +899,7 @@@
* @throws IllegalArgumentException if the given name is not recognized,
* or if the arguments are illegal for the specified function.
*/
- public Expression<R,?> function(final String name, Expression<? super R, ?>[] parameters) {
- @Override
+ public Expression<R,?> function(final String name, Expression<R,?>[] parameters) {
ArgumentChecks.ensureNonNull("name", name);
ArgumentChecks.ensureNonNull("parameters", parameters);
parameters = parameters.clone();
diff --cc core/sis-feature/src/main/java/org/apache/sis/filter/DistanceFilter.java
index 76942d2db9,404770b4cd..30061a34c4
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/DistanceFilter.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/DistanceFilter.java
@@@ -41,9 -43,9 +41,9 @@@ import org.apache.sis.internal.geoapi.f
*
* @author Johann Sorel (Geomatys)
* @author Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.4
*
- * @param <R> the type of resources (e.g. {@link org.opengis.feature.Feature}) used as inputs.
+ * @param <R> the type of resources (e.g. {@code Feature}) used as inputs.
* @param <G> the implementation type of geometry objects.
*
* @since 1.1
@@@ -136,12 -139,13 +136,12 @@@ final class DistanceFilter<R,G> extend
*
* @throws IllegalStateException if the geometry is not a literal.
*/
- @Override
public Geometry getGeometry() {
- final Literal<? super R, ? extends GeometryWrapper<G>> literal;
+ final Literal<R, ? extends GeometryWrapper<G>> literal;
if (expression2 instanceof Literal<?,?>) {
- literal = (Literal<? super R, ? extends GeometryWrapper<G>>) expression2;
+ literal = (Literal<R, ? extends GeometryWrapper<G>>) expression2;
} else if (expression1 instanceof Literal<?,?>) {
- literal = (Literal<? super R, ? extends GeometryWrapper<G>>) expression1;
+ literal = (Literal<R, ? extends GeometryWrapper<G>>) expression1;
} else {
throw new IllegalStateException();
}
diff --cc core/sis-feature/src/main/java/org/apache/sis/filter/Expression.java
index 3d28abfd48,0000000000..a55c9d1946
mode 100644,000000..100644
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/Expression.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/Expression.java
@@@ -1,74 -1,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.filter;
+
+import java.util.List;
+import java.util.function.Function;
+import org.opengis.util.ScopedName;
+
+
+/**
+ * A literal or a named procedure that performs a distinct computation.
+ *
+ * <div class="warning"><b>Upcoming API change</b><br>
+ * This is a placeholder for a GeoAPI 3.1 interface not yet released.
+ * In a future version, all usages of this interface may be replaced
+ * by an interface of the same name but in the {@code org.opengis.filter} package
+ * instead of {@code org.apache.sis.filter}.
+ * </div>
+ *
+ * @param <R> the type of resources (e.g. {@code Feature}) used as inputs.
+ * @param <V> the type of values computed by the expression.
+ */
+public interface Expression<R,V> extends Function<R,V> {
+ /**
+ * Returns the name of the function to be called.
+ *
+ * @return name of the function to be called.
+ */
+ ScopedName getFunctionName();
+
++ /**
++ * Returns the class of resources expected by this expression.
++ *
++ * @return type of resources accepted by this expression.
++ *
++ * @since 1.4
++ */
++ Class<? super R> getResourceClass();
++
+ /**
+ * Returns the list sub-expressions that will be evaluated to provide the parameters to the function.
+ *
+ * @return the sub-expressions to be evaluated, or an empty list if none.
+ */
- List<Expression<? super R, ?>> getParameters();
++ List<Expression<R,?>> getParameters();
+
+ /**
+ * Evaluates the expression value based on the content of the given object.
+ *
+ * @param input the object to be evaluated by the expression.
+ * Can be {@code null} if this expression allows null values.
+ * @return value computed by the expression.
+ * @throws NullPointerException if {@code input} is null and this expression requires non-null values.
+ * @throws IllegalArgumentException if the expression can not be applied on the given object.
+ */
+ @Override
+ V apply(R input);
+
+ /**
+ * Returns an expression doing the same evaluation than this method, but returning results
+ * as values of the specified type.
+ *
+ * @param <N> compile-time value of {@code type}.
+ * @param type desired type of expression results.
+ * @return expression doing the same operation this this expression but with results of the specified type.
+ * @throws ClassCastException if the specified type is not a target type supported by implementation.
+ */
+ <N> Expression<R,N> toValueType(Class<N> type);
+}
diff --cc core/sis-feature/src/main/java/org/apache/sis/filter/Filter.java
index b35a5d7a1d,0000000000..1fd3741752
mode 100644,000000..100644
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/Filter.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/Filter.java
@@@ -1,81 -1,0 +1,90 @@@
+/*
+ * 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.filter;
+
+import java.util.List;
+import java.util.function.Predicate;
+
+
+/**
+ * Identification of a subset of resources from a collection of resources
+ * whose property values satisfy a set of logically connected predicates.
+ *
+ * <div class="warning"><b>Upcoming API change</b><br>
+ * This is a placeholder for a GeoAPI 3.1 interface not yet released.
+ * In a future version, all usages of this interface may be replaced
+ * by an interface of the same name but in the {@code org.opengis.filter} package
+ * instead of {@code org.apache.sis.filter}.
+ * </div>
+ */
+public interface Filter<R> extends Predicate<R> {
+ /**
+ * A filter that always evaluates to {@code true}.
+ *
+ * @param <R> the type of resources to filter.
+ * @return the "no filtering" filter.
+ */
+ @SuppressWarnings("unchecked")
+ static <R> Filter<R> include() {
+ return FilterLiteral.INCLUDE;
+ }
+
+ /**
+ * A filter that always evaluates to {@code false}.
+ *
+ * @param <R> the type of resources to filter.
+ * @return the "exclude all" filter.
+ */
+ @SuppressWarnings("unchecked")
+ static <R> Filter<R> exclude() {
+ return FilterLiteral.EXCLUDE;
+ }
+
+ /**
+ * Returns the nature of the operator.
+ *
+ * @return the nature of this operator.
+ */
+ Enum<?> getOperatorType();
+
++ /**
++ * Returns the class of resources expected by this filter.
++ *
++ * @return type of resources accepted by this filter.
++ *
++ * @since 1.4
++ */
++ Class<? super R> getResourceClass();
++
+ /**
+ * Returns the expressions used as arguments for this filter.
+ *
+ * @return the expressions used as inputs, or an empty list if none.
+ */
- List<Expression<? super R, ?>> getExpressions();
++ List<Expression<R,?>> getExpressions();
+
+ /**
+ * Given an object, determines if the test(s) represented by this filter are passed.
+ *
+ * @param object the object (often a {@code Feature} instance) to evaluate.
+ * @return {@code true} if the test(s) are passed for the provided object.
+ * @throws NullPointerException if {@code object} is null.
+ * @throws IllegalArgumentException if the filter can not be applied on the given object.
+ */
+ @Override
+ boolean test(R object);
+}
diff --cc core/sis-feature/src/main/java/org/apache/sis/filter/FilterLiteral.java
index 8ca4b9c401,0000000000..d39cef550c
mode 100644,000000..100644
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/FilterLiteral.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/FilterLiteral.java
@@@ -1,65 -1,0 +1,70 @@@
+/*
+ * 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.filter;
+
+import java.util.List;
+import java.util.Collections;
+import java.io.Serializable;
+import java.io.ObjectStreamException;
+
+
+/**
+ * Placeholder for GeoAPI 3.1 interfaces (not yet released).
+ * Shall not be visible in public API, as it will be deleted after next GeoAPI release.
+ */
+final class FilterLiteral implements Filter<Object>, Serializable {
+ @SuppressWarnings("rawtypes")
+ public static final Filter INCLUDE = new FilterLiteral(true);
+
+ @SuppressWarnings("rawtypes")
+ public static final Filter EXCLUDE = new FilterLiteral(false);
+
+ private final boolean value;
+
+ private FilterLiteral(final boolean value) {
+ this.value = value;
+ }
+
+ @Override
+ public Enum<?> getOperatorType() {
+ return value ? FilterName.INCLUDE : FilterName.EXCLUDE;
+ }
+
++ @Override
++ public Class<Object> getResourceClass() {
++ return Object.class;
++ }
++
+ @Override
+ public List<Expression<? super Object, ?>> getExpressions() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public boolean test(Object object) {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return "Filter." + (value ? "INCLUDE" : "EXCLUDE");
+ }
+
+ private Object readResolve() throws ObjectStreamException {
+ return value ? INCLUDE : EXCLUDE;
+ }
+}
diff --cc core/sis-feature/src/main/java/org/apache/sis/filter/IdentifierFilter.java
index f47c13d287,102fc4363e..9017aaab4d
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/IdentifierFilter.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/IdentifierFilter.java
@@@ -31,13 -35,10 +32,10 @@@ import org.apache.sis.feature.AbstractF
*
* @author Johann Sorel (Geomatys)
* @author Martin Desruisseaux (Geomatys)
- * @version 1.1
- *
- * @param <R> the type of resources used as inputs.
- *
- * @since 1.1
+ * @version 1.4
+ * @since 1.1
*/
- final class IdentifierFilter<R extends AbstractFeature> extends FilterNode<R> {
-final class IdentifierFilter extends Node implements ResourceId<Feature>, Optimization.OnFilter<Feature> {
++final class IdentifierFilter extends Node implements Optimization.OnFilter<AbstractFeature> {
/**
* For cross-version compatibility.
*/
@@@ -56,11 -57,23 +54,28 @@@
this.identifier = identifier;
}
+ @Override
+ public Enum<?> getOperatorType() {
+ return FilterName.RESOURCE_ID;
+ }
+
+ /**
+ * Nothing to optimize here. The {@code Optimization.OnFilter} interface
+ * is implemented for inheriting the AND, OR and NOT methods overriding.
+ */
+ @Override
- public Filter<Feature> optimize(Optimization optimization) {
++ public Filter<AbstractFeature> optimize(Optimization optimization) {
+ return this;
+ }
+
+ /**
+ * Returns the class of resources expected by this expression.
+ */
+ @Override
- public Class<Feature> getResourceClass() {
- return Feature.class;
++ public Class<AbstractFeature> getResourceClass() {
++ return AbstractFeature.class;
+ }
+
/**
* Returns the identifiers of feature instances to accept.
*/
@@@ -72,7 -86,7 +87,7 @@@
* Returns the parameters of this filter.
*/
@Override
- public List<Expression<? super R, ?>> getExpressions() {
- public List<Expression<Feature,?>> getExpressions() {
++ public List<Expression<AbstractFeature,?>> getExpressions() {
return List.of(new LeafExpression.Literal<>(identifier));
}
@@@ -90,7 -104,7 +105,7 @@@
* is one of the identifier specified at {@code IdentifierFilter} construction time.
*/
@Override
- public boolean test(R object) {
- public boolean test(final Feature object) {
++ public boolean test(final AbstractFeature object) {
if (object == null) {
return false;
}
diff --cc core/sis-feature/src/main/java/org/apache/sis/filter/LeafExpression.java
index 4bd0256975,18e6864560..aac4113826
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/LeafExpression.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/LeafExpression.java
@@@ -41,9 -42,9 +41,9 @@@ import org.apache.sis.feature.DefaultAt
*
* @author Johann Sorel (Geomatys)
* @author Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.4
*
- * @param <R> the type of resources (e.g. {@link org.opengis.feature.Feature}) used as inputs.
+ * @param <R> the type of resources (e.g. {@code Feature}) used as inputs.
* @param <V> the type of value computed by the expression.
*
* @since 1.1
@@@ -92,6 -93,6 +92,10 @@@ abstract class LeafExpression<R,V> exte
this.value = value; // Null is accepted.
}
++ @Override public Class<? super R> getResourceClass() {
++ return Object.class;
++ }
++
/** For {@link #toString()}, {@link #hashCode()} and {@link #equals(Object)} implementations. */
@Override protected Collection<?> getChildren() {
// Not `List.of(…)` because value may be null.
diff --cc core/sis-feature/src/main/java/org/apache/sis/filter/LikeFilter.java
index 7e8e569dae,bc3a4ab79e..88720d0fa1
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/LikeFilter.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/LikeFilter.java
@@@ -20,9 -20,12 +20,10 @@@ import java.util.List
import java.util.Collection;
import java.util.regex.Pattern;
import org.apache.sis.util.ArgumentChecks;
+ import org.apache.sis.internal.filter.Node;
// Branch-dependent imports
-import org.opengis.filter.Filter;
-import org.opengis.filter.Expression;
-import org.opengis.filter.LikeOperator;
+import org.apache.sis.internal.geoapi.filter.ComparisonOperatorName;
/**
@@@ -30,13 -33,13 +31,13 @@@
*
* @author Johann Sorel (Geomatys)
* @author Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.4
*
- * @param <R> the type of resources (e.g. {@link org.opengis.feature.Feature}) used as inputs.
+ * @param <R> the type of resources (e.g. {@code Feature}) used as inputs.
*
* @since 1.1
*/
- final class LikeFilter<R> extends FilterNode<R> implements Optimization.OnFilter<R> {
-final class LikeFilter<R> extends Node implements LikeOperator<R>, Optimization.OnFilter<R> {
++final class LikeFilter<R> extends Node implements Optimization.OnFilter<R> {
/**
* For cross-version compatibility.
*/
diff --cc core/sis-feature/src/main/java/org/apache/sis/filter/LogicalFilter.java
index 6805ddfadf,8dc2b23b28..cd2148b839
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/LogicalFilter.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/LogicalFilter.java
@@@ -34,9 -36,9 +35,9 @@@ import org.apache.sis.internal.geoapi.f
*
* @author Johann Sorel (Geomatys)
* @author Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.4
*
- * @param <R> the type of resources (e.g. {@link org.opengis.feature.Feature}) used as inputs.
+ * @param <R> the type of resources (e.g. {@code Feature}) used as inputs.
*
* @since 1.1
*/
diff --cc core/sis-feature/src/main/java/org/apache/sis/filter/PropertyValue.java
index 365831f00f,cae63556d3..825fc7393b
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/PropertyValue.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/PropertyValue.java
@@@ -138,6 -133,14 +138,14 @@@ split: if (path != null)
return (path == null || path.isEmpty()) ? tip : new AssociationValue<>(path, tip);
}
+ /**
+ * Returns the class of resources expected by this expression.
+ */
+ @Override
- public final Class<Feature> getResourceClass() {
- return Feature.class;
++ public final Class<AbstractFeature> getResourceClass() {
++ return AbstractFeature.class;
+ }
+
/**
* For {@link #toString()}, {@link #hashCode()} and {@link #equals(Object)} implementations.
*/
diff --cc core/sis-feature/src/main/java/org/apache/sis/filter/TemporalFilter.java
index aa6d0d3175,c38677e51c..d66a1089a6
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/TemporalFilter.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/TemporalFilter.java
@@@ -37,9 -40,9 +37,9 @@@ import org.apache.sis.internal.geoapi.f
*
* @author Johann Sorel (Geomatys)
* @author Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.4
*
- * @param <T> the type of resources (e.g. {@link org.opengis.feature.Feature}) used as inputs.
+ * @param <T> the type of resources (e.g. {@code Feature}) used as inputs.
*
* @since 1.1
*/
diff --cc core/sis-feature/src/main/java/org/apache/sis/filter/UnaryFunction.java
index 451f522112,cff832db14..c25b3165fb
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/UnaryFunction.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/UnaryFunction.java
@@@ -33,9 -36,9 +33,9 @@@ import org.apache.sis.internal.geoapi.f
*
* @author Johann Sorel (Geomatys)
* @author Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.4
*
- * @param <R> the type of resources (e.g. {@link org.opengis.feature.Feature}) used as inputs.
+ * @param <R> the type of resources (e.g. {@code Feature}) used as inputs.
* @param <V> the type of value computed by the expression.
*
* @since 1.1
@@@ -108,12 -121,8 +118,12 @@@ class UnaryFunction<R,V> extends Node
super(expression);
}
+ @Override public ComparisonOperatorName getOperatorType() {
+ return ComparisonOperatorName.PROPERTY_IS_NULL;
+ }
+
/** Creates a new filter of the same type but different parameters. */
- @Override public Filter<R> recreate(final Expression<? super R, ?>[] effective) {
+ @Override public Filter<R> recreate(final Expression<R,?>[] effective) {
return new IsNull<>(effective[0]);
}
@@@ -151,12 -160,8 +161,12 @@@
this.nilReason = nilReason;
}
+ @Override public ComparisonOperatorName getOperatorType() {
+ return ComparisonOperatorName.PROPERTY_IS_NIL;
+ }
+
/** Creates a new filter of the same type but different parameters. */
- @Override public Filter<R> recreate(final Expression<? super R, ?>[] effective) {
+ @Override public Filter<R> recreate(final Expression<R,?>[] effective) {
return new IsNil<>(effective[0], nilReason);
}
diff --cc core/sis-feature/src/main/java/org/apache/sis/internal/filter/GeometryConverter.java
index 211d7f7c79,a9bcf55dc4..b3a4a96bd7
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/filter/GeometryConverter.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/filter/GeometryConverter.java
@@@ -42,9 -43,9 +42,9 @@@ import org.apache.sis.filter.Expression
*
* @author Martin Desruisseaux (Geomatys)
* @author Alexis Manin (Geomatys)
- * @version 1.3
+ * @version 1.4
*
- * @param <R> the type of resources (e.g. {@link org.opengis.feature.Feature}) used as inputs.
+ * @param <R> the type of resources (e.g. {@code Feature}) used as inputs.
* @param <G> the geometry implementation type.
*
* @see org.apache.sis.filter.ConvertFunction
diff --cc core/sis-feature/src/main/java/org/apache/sis/internal/filter/Node.java
index 67ee11a650,581588efb3..5e615957e1
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/filter/Node.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/filter/Node.java
@@@ -88,12 -90,32 +88,32 @@@ public abstract class Node implements S
*
* @see Expression#getFunctionName()
*/
- protected static <T> AttributeType<T> createType(final Class<T> type, final Object name) {
+ protected static <T> DefaultAttributeType<T> createType(final Class<T> type, final Object name) {
// We do not use `Map.of(…)` for letting the attribute type constructor do the null check.
return new DefaultAttributeType<>(Collections.singletonMap(DefaultAttributeType.NAME_KEY, name),
- type, 1, 1, null, (AttributeType<?>[]) null);
+ type, 1, 1, null, (DefaultAttributeType<?>[]) null);
}
+ /**
+ * Returns the most specialized class of the given pair of class. A specialized class is guaranteed to exist
+ * if parametrized type safety has not been bypassed with unchecked casts, because {@code <R>} is always valid.
+ * However this method is not guaranteed to be able to find that specialized type, because it could be none of
+ * the given arguments if {@code t1}, {@code t2} and {@code <R>} are interfaces with {@code <R>} extending both
+ * {@code t1} and {@code t2}.
+ *
+ * @param <R> the compile-time type of resources expected by filters or expressions.
+ * @param t1 the runtime type of resources expected by the first filter or expression. May be null.
+ * @param t2 the runtime type of resources expected by the second filter or expression. May be null.
+ * @return the most specialized type of resources, or {@code null} if it cannot be determined.
+ */
+ protected static <R> Class<? super R> specializedClass(final Class<? super R> t1, final Class<? super R> t2) {
+ if (t1 != null && t2 != null) {
+ if (t1.isAssignableFrom(t2)) return t2;
+ if (t2.isAssignableFrom(t1)) return t1;
+ }
+ return null;
+ }
+
/**
* Returns the mathematical symbol for this binary function.
* For comparison operators, the symbol should be one of {@literal < > ≤ ≥ = ≠}.
diff --cc core/sis-feature/src/main/java/org/apache/sis/internal/filter/Visitor.java
index 9c47f9c5a0,60945dfea5..dc879f081e
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/filter/Visitor.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/filter/Visitor.java
@@@ -24,14 -24,14 +24,13 @@@ import java.util.function.BiConsumer
import org.apache.sis.internal.feature.Resources;
// Branch-dependent imports
-import org.opengis.filter.Filter;
-import org.opengis.filter.Expression;
-import org.opengis.filter.LogicalOperatorName;
-import org.opengis.filter.SpatialOperatorName;
-import org.opengis.filter.DistanceOperatorName;
-import org.opengis.filter.TemporalOperatorName;
-import org.opengis.filter.ComparisonOperatorName;
+import org.apache.sis.filter.Filter;
+import org.apache.sis.filter.Expression;
- import org.apache.sis.internal.geoapi.filter.LogicalOperator;
+import org.apache.sis.internal.geoapi.filter.LogicalOperatorName;
+import org.apache.sis.internal.geoapi.filter.SpatialOperatorName;
+import org.apache.sis.internal.geoapi.filter.DistanceOperatorName;
+import org.apache.sis.internal.geoapi.filter.TemporalOperatorName;
+import org.apache.sis.internal.geoapi.filter.ComparisonOperatorName;
/**
@@@ -49,9 -49,9 +48,9 @@@
* {@code Visitor} instances are thread-safe if protected methods are invoked at construction time only.
*
* @author Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.4
*
- * @param <R> the type of resources (e.g. {@link org.opengis.feature.Feature}) used as inputs.
+ * @param <R> the type of resources (e.g. {@code Feature}) used as inputs.
* @param <A> type of the accumulator object where actions will write their results.
*
* @since 1.1
@@@ -259,10 -259,10 +258,10 @@@ public abstract class Visitor<R,A>
* Actions are registered by calls to {@code setFooHandler(…)} before the call to this {@code visit(…)} method.
*
* <h4>Note on parameterized type</h4>
- * This method often needs to be invoked with instances of {@code Filter<? super R>},
- * because this is the type of filters returned by GeoAPI methods such as {@link LogicalOperator#getOperands()}.
+ * This method sometimes needs to be invoked with instances of {@code Filter<? super R>},
+ * because this is the type of predicate expected by {@link java.util.function} and {@link java.util.stream}.
* But the parameterized type expected by this method matches the parameterized type of handlers registered by
- * {@link #setFilterHandler(CodeList, BiConsumer)} and similar methods, which use the exact {@code <R>} type.
+ * {@link #setFilterHandler(Enum, BiConsumer)} and similar methods, which use the exact {@code <R>} type.
* This restriction exists because when doing otherwise, parameterized types become hard to express in Java
* (we get a cascade of {@code super} keywords, something like {@code <? super ? super R>}).
* However, doing the {@code (Filter<R>) filter} cast is actually safe if the handlers do not invoke any
diff --cc core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/FunctionWithSRID.java
index 7f3a0d4b1c,b2640be641..2edc6d4b4b
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/FunctionWithSRID.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/FunctionWithSRID.java
@@@ -43,9 -44,9 +43,9 @@@ import org.apache.sis.internal.geoapi.f
* @author Johann Sorel (Geomatys)
* @author Martin Desruisseaux (Geomatys)
* @author Alexis Manin (Geomatys)
- * @version 1.3
+ * @version 1.4
*
- * @param <R> the type of resources (e.g. {@link org.opengis.feature.Feature}) used as inputs.
+ * @param <R> the type of resources (e.g. {@code Feature}) used as inputs.
*
* @since 1.1
*/
diff --cc core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/GeometryConstructor.java
index c88d01cbac,bebef3918e..07e52584a7
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/GeometryConstructor.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/GeometryConstructor.java
@@@ -34,9 -35,9 +34,9 @@@ import org.apache.sis.filter.Expression
*
* @author Johann Sorel (Geomatys)
* @author Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.4
*
- * @param <R> the type of resources (e.g. {@link org.opengis.feature.Feature}) used as inputs.
+ * @param <R> the type of resources (e.g. {@code Feature}) used as inputs.
* @param <G> the implementation type of geometry objects.
*
* @since 1.1
diff --cc core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/GeometryParser.java
index c84813e4da,425f02a9c8..635882b939
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/GeometryParser.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/GeometryParser.java
@@@ -32,9 -33,9 +32,9 @@@ import org.apache.sis.filter.Expression
*
* @author Johann Sorel (Geomatys)
* @author Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.4
*
- * @param <R> the type of resources (e.g. {@link org.opengis.feature.Feature}) used as inputs.
+ * @param <R> the type of resources (e.g. {@code Feature}) used as inputs.
* @param <G> the implementation type of geometry objects.
*
* @since 1.1
diff --cc core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/OneGeometry.java
index 2b8774708e,2ce129b57d..5f1da923c3
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/OneGeometry.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/OneGeometry.java
@@@ -31,9 -31,9 +31,9 @@@ import org.apache.sis.filter.Expression
*
* @author Johann Sorel (Geomatys)
* @author Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
*
- * @param <R> the type of resources (e.g. {@link org.opengis.feature.Feature}) used as inputs.
+ * @param <R> the type of resources (e.g. {@code Feature}) used as inputs.
* @param <G> the implementation type of geometry objects.
*
* @since 1.1
diff --cc core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/ST_FromBinary.java
index 22d64ab43d,ef835b17c7..b76ddbf5dd
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/ST_FromBinary.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/ST_FromBinary.java
@@@ -29,9 -29,9 +29,9 @@@ import org.apache.sis.filter.Expression
*
* @author Johann Sorel (Geomatys)
* @author Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.4
*
- * @param <R> the type of resources (e.g. {@link org.opengis.feature.Feature}) used as inputs.
+ * @param <R> the type of resources (e.g. {@code Feature}) used as inputs.
* @param <G> the implementation type of geometry objects.
*
* @since 1.1
diff --cc core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/ST_FromText.java
index 8608b18868,e8f919dedc..40e20e4904
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/ST_FromText.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/ST_FromText.java
@@@ -28,9 -28,9 +28,9 @@@ import org.apache.sis.filter.Expression
*
* @author Johann Sorel (Geomatys)
* @author Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.4
*
- * @param <R> the type of resources (e.g. {@link org.opengis.feature.Feature}) used as inputs.
+ * @param <R> the type of resources (e.g. {@code Feature}) used as inputs.
* @param <G> the implementation type of geometry objects.
*
* @since 1.1
diff --cc core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/ST_Point.java
index 028dbacd98,eeb2809a65..94f90443f9
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/ST_Point.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/ST_Point.java
@@@ -44,9 -45,9 +44,9 @@@ import org.apache.sis.filter.Expression
*
* @author Johann Sorel (Geomatys)
* @author Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.4
*
- * @param <R> the type of resources (e.g. {@link org.opengis.feature.Feature}) used as inputs.
+ * @param <R> the type of resources (e.g. {@code Feature}) used as inputs.
* @param <G> the implementation type of geometry objects.
*
* @since 1.1
diff --cc core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/ST_Transform.java
index 9e2c9ec4ce,887ae43dc4..2370a485a4
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/ST_Transform.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/ST_Transform.java
@@@ -76,9 -77,9 +76,9 @@@ final class ST_Transform<R,G> extends F
* Creates a new function with the given parameters. It is caller's responsibility to ensure
* that the given array is non-null and does not contain null elements.
*
- * @throws InvalidFilterValueException if CRS cannot be constructed from the second expression.
+ * @throws IllegalArgumentException if CRS cannot be constructed from the second expression.
*/
- ST_Transform(final Expression<? super R, ?>[] parameters, final Geometries<G> library) {
+ ST_Transform(final Expression<R,?>[] parameters, final Geometries<G> library) {
super(SQLMM.ST_Transform, parameters, PRESENT);
geometry = toGeometryWrapper(library, parameters[0]);
}
diff --cc core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/TwoGeometries.java
index a60e2744ce,ad06f76fa8..cc72136844
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/TwoGeometries.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/TwoGeometries.java
@@@ -36,9 -37,9 +36,9 @@@ import org.apache.sis.internal.geoapi.f
*
* @author Johann Sorel (Geomatys)
* @author Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
*
- * @param <R> the type of resources (e.g. {@link org.opengis.feature.Feature}) used as inputs.
+ * @param <R> the type of resources (e.g. {@code Feature}) used as inputs.
* @param <G> the implementation type of geometry objects.
*
* @since 1.1
@@@ -80,10 -81,10 +80,10 @@@ class TwoGeometries<R,G> extends Spatia
* executed in the CRS of the first argument.
*/
@Override
- public Expression<? super R, ?> optimize(final Optimization optimization) {
+ public Expression<R,?> optimize(final Optimization optimization) {
- final FeatureType featureType = optimization.getFeatureType();
+ final DefaultFeatureType featureType = optimization.getFeatureType();
if (featureType != null) {
- final Expression<? super R, ?> p1 = unwrap(geometry1);
+ final Expression<R,?> p1 = unwrap(geometry1);
if (p1 instanceof ValueReference<?,?> && unwrap(geometry2) instanceof Literal<?,?>) try {
final CoordinateReferenceSystem targetCRS = AttributeConvention.getCRSCharacteristic(
featureType, featureType.getProperty(((ValueReference<?,?>) p1).getXPath()));
diff --cc core/sis-feature/src/main/java/org/apache/sis/internal/geoapi/filter/BetweenComparisonOperator.java
index 8e4e8f30be,18427e2c07..2905fb62c0
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/geoapi/filter/BetweenComparisonOperator.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/geoapi/filter/BetweenComparisonOperator.java
@@@ -14,18 -14,23 +14,18 @@@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.sis.internal.map;
+package org.apache.sis.internal.geoapi.filter;
+
+import org.apache.sis.filter.Expression;
+import org.apache.sis.filter.Filter;
-import org.opengis.style.Symbolizer;
/**
- * Resource symbolizers act on a resource as a whole, not on individual features.
- * Such symbolizers are not defined by the Symbology Encoding specification but are
- * often required to produce uncommon presentations.
- *
- * <p>
- * NOTE: this class is a first draft subject to modifications.
- * </p>
- *
- * @author Johann Sorel (Geomatys)
- * @version 1.2
- * @since 1.2
+ * Placeholder for GeoAPI 3.1 interfaces (not yet released).
+ * Shall not be visible in public API, as it will be deleted after next GeoAPI release.
*/
-public interface ResourceSymbolizer extends Symbolizer {
-
+public interface BetweenComparisonOperator<R> extends Filter<R> {
- Expression<? super R, ?> getExpression();
- Expression<? super R, ?> getLowerBoundary();
- Expression<? super R, ?> getUpperBoundary();
++ Expression<R,?> getExpression();
++ Expression<R,?> getLowerBoundary();
++ Expression<R,?> getUpperBoundary();
}
diff --cc core/sis-feature/src/main/java/org/apache/sis/internal/geoapi/filter/BinaryComparisonOperator.java
index b2fff0f701,18427e2c07..eec80796c3
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/geoapi/filter/BinaryComparisonOperator.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/geoapi/filter/BinaryComparisonOperator.java
@@@ -14,19 -14,23 +14,19 @@@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.sis.internal.map;
+package org.apache.sis.internal.geoapi.filter;
+
+import org.apache.sis.filter.Expression;
+import org.apache.sis.filter.Filter;
-import org.opengis.style.Symbolizer;
/**
- * Resource symbolizers act on a resource as a whole, not on individual features.
- * Such symbolizers are not defined by the Symbology Encoding specification but are
- * often required to produce uncommon presentations.
- *
- * <p>
- * NOTE: this class is a first draft subject to modifications.
- * </p>
- *
- * @author Johann Sorel (Geomatys)
- * @version 1.2
- * @since 1.2
+ * Placeholder for GeoAPI 3.1 interfaces (not yet released).
+ * Shall not be visible in public API, as it will be deleted after next GeoAPI release.
*/
-public interface ResourceSymbolizer extends Symbolizer {
-
+public interface BinaryComparisonOperator<R> extends Filter<R> {
- Expression<? super R, ?> getOperand1();
- Expression<? super R, ?> getOperand2();
++ Expression<R,?> getOperand1();
++ Expression<R,?> getOperand2();
+ boolean isMatchingCase();
+ MatchAction getMatchAction();
}
diff --cc core/sis-feature/src/main/java/org/apache/sis/internal/geoapi/filter/FilterExpressions.java
index 6bb16907b0,0000000000..cae55c6df5
mode 100644,000000..100644
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/geoapi/filter/FilterExpressions.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/geoapi/filter/FilterExpressions.java
@@@ -1,105 -1,0 +1,110 @@@
+/*
+ * 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.internal.geoapi.filter;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.AbstractList;
+import java.util.Locale;
+import org.opengis.util.ScopedName;
+import org.apache.sis.filter.Filter;
+import org.apache.sis.filter.Expression;
+import org.apache.sis.util.iso.Names;
+
+
+/**
+ * Placeholder for GeoAPI 3.1 interfaces (not yet released).
+ * Shall not be visible in public API, as it will be deleted after next GeoAPI release.
+ */
- final class FilterExpressions<R> extends AbstractList<Expression<? super R, ?>> {
- private final List<Filter<? super R>> filters;
++final class FilterExpressions<R> extends AbstractList<Expression<R,?>> {
++ private final List<Filter<R>> filters;
+
- FilterExpressions(final List<Filter<? super R>> filters) {
++ FilterExpressions(final List<Filter<R>> filters) {
+ this.filters = Objects.requireNonNull(filters);
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return filters.isEmpty();
+ }
+
+ @Override
+ public int size() {
+ return filters.size();
+ }
+
+ @Override
- public Expression<? super R, ?> get(final int index) {
++ public Expression<R,?> get(final int index) {
+ return new Element<>(filters.get(index));
+ }
+
+ private static final class Element<R> implements Expression<R,Boolean> {
+ private final Filter<R> filter;
+
+ Element(final Filter<R> filter) {
+ this.filter = Objects.requireNonNull(filter);
+ }
+
+ @Override
+ public ScopedName getFunctionName() {
+ final Enum<?> type = filter.getOperatorType();
+ final String identifier = type.name().toLowerCase(Locale.US);
+ if (identifier != null) {
+ return Names.createScopedName(Name.STANDARD, null, identifier);
+ } else {
+ return Names.createScopedName(Name.EXTENSION, null, type.name());
+ }
+ }
+
+ @Override
- public List<Expression<? super R, ?>> getParameters() {
++ public Class<? super R> getResourceClass() {
++ return filter.getResourceClass();
++ }
++
++ @Override
++ public List<Expression<R,?>> getParameters() {
+ return filter.getExpressions();
+ }
+
+ @Override
+ public Boolean apply(final R input) {
+ return filter.test(input);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public <N> Expression<R,N> toValueType(final Class<N> type) {
+ if (type.isAssignableFrom(Boolean.class)) return (Expression<R,N>) this;
+ else throw new ClassCastException();
+ }
+
+ @Override
+ public int hashCode() {
+ return ~filter.hashCode();
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ return (obj instanceof Element) && filter.equals(((Element) obj).filter);
+ }
+
+ @Override
+ public String toString() {
+ return "Expression[" + filter.toString() + ']';
+ }
+ }
+}
diff --cc core/sis-feature/src/main/java/org/apache/sis/internal/geoapi/filter/Literal.java
index 85d0294458,18427e2c07..93c3140420
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/geoapi/filter/Literal.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/geoapi/filter/Literal.java
@@@ -14,28 -14,23 +14,28 @@@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.sis.internal.map;
+package org.apache.sis.internal.geoapi.filter;
+
+import java.util.List;
+import java.util.Collections;
+import org.opengis.util.ScopedName;
+import org.apache.sis.filter.Expression;
-import org.opengis.style.Symbolizer;
/**
- * Resource symbolizers act on a resource as a whole, not on individual features.
- * Such symbolizers are not defined by the Symbology Encoding specification but are
- * often required to produce uncommon presentations.
- *
- * <p>
- * NOTE: this class is a first draft subject to modifications.
- * </p>
- *
- * @author Johann Sorel (Geomatys)
- * @version 1.2
- * @since 1.2
+ * Placeholder for GeoAPI 3.1 interfaces (not yet released).
+ * Shall not be visible in public API, as it will be deleted after next GeoAPI release.
*/
-public interface ResourceSymbolizer extends Symbolizer {
+public interface Literal<R,V> extends Expression<R,V> {
+ @Override
+ default ScopedName getFunctionName() {
+ return Name.LITERAL;
+ }
+
+ @Override
- default List<Expression<? super R, ?>> getParameters() {
++ default List<Expression<R,?>> getParameters() {
+ return Collections.emptyList();
+ }
+ V getValue();
}
diff --cc core/sis-feature/src/main/java/org/apache/sis/internal/geoapi/filter/LogicalOperator.java
index 8647cd1ed3,18427e2c07..e68663026b
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/geoapi/filter/LogicalOperator.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/geoapi/filter/LogicalOperator.java
@@@ -14,25 -14,23 +14,25 @@@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.sis.internal.map;
+package org.apache.sis.internal.geoapi.filter;
+
+import java.util.List;
+import org.apache.sis.filter.Filter;
+import org.apache.sis.filter.Expression;
-import org.opengis.style.Symbolizer;
/**
- * Resource symbolizers act on a resource as a whole, not on individual features.
- * Such symbolizers are not defined by the Symbology Encoding specification but are
- * often required to produce uncommon presentations.
- *
- * <p>
- * NOTE: this class is a first draft subject to modifications.
- * </p>
- *
- * @author Johann Sorel (Geomatys)
- * @version 1.2
- * @since 1.2
+ * Placeholder for GeoAPI 3.1 interfaces (not yet released).
+ * Shall not be visible in public API, as it will be deleted after next GeoAPI release.
*/
-public interface ResourceSymbolizer extends Symbolizer {
+public interface LogicalOperator<R> extends Filter<R> {
+ @Override
+ LogicalOperatorName getOperatorType();
+
+ @Override
- default List<Expression<? super R, ?>> getExpressions() {
++ default List<Expression<R,?>> getExpressions() {
+ return new FilterExpressions<>(getOperands());
+ }
- List<Filter<? super R>> getOperands();
++ List<Filter<R>> getOperands();
}
diff --cc core/sis-feature/src/main/java/org/apache/sis/internal/geoapi/filter/SortProperty.java
index ab27a0e692,18427e2c07..f3cd74aa69
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/geoapi/filter/SortProperty.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/geoapi/filter/SortProperty.java
@@@ -14,17 -14,23 +14,17 @@@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.sis.internal.map;
+package org.apache.sis.internal.geoapi.filter;
+
+import java.util.Comparator;
-import org.opengis.style.Symbolizer;
/**
- * Resource symbolizers act on a resource as a whole, not on individual features.
- * Such symbolizers are not defined by the Symbology Encoding specification but are
- * often required to produce uncommon presentations.
- *
- * <p>
- * NOTE: this class is a first draft subject to modifications.
- * </p>
- *
- * @author Johann Sorel (Geomatys)
- * @version 1.2
- * @since 1.2
+ * Placeholder for GeoAPI 3.1 interfaces (not yet released).
+ * Shall not be visible in public API, as it will be deleted after next GeoAPI release.
*/
-public interface ResourceSymbolizer extends Symbolizer {
+public interface SortProperty<R> extends Comparator<R> {
- ValueReference<? super R, ?> getValueReference();
++ ValueReference<R,?> getValueReference();
+ SortOrder getSortOrder();
}
diff --cc core/sis-feature/src/test/java/org/apache/sis/filter/BinarySpatialFilterTestCase.java
index 6b21237346,9256708be1..5b1c0bc185
--- a/core/sis-feature/src/test/java/org/apache/sis/filter/BinarySpatialFilterTestCase.java
+++ b/core/sis-feature/src/test/java/org/apache/sis/filter/BinarySpatialFilterTestCase.java
@@@ -131,10 -134,11 +131,11 @@@ public abstract class BinarySpatialFilt
*/
@Test
public void bbox_preserve_expression_type() {
- final BinarySpatialOperator<Feature> bbox = factory.bbox(literal(Polygon.RIGHT), new Envelope2D(null, 0, 0, 1, 1));
- final Expression<Feature,?> arg2 = bbox.getOperand2();
+ final Filter<AbstractFeature> bbox = factory.bbox(literal(Polygon.RIGHT), new Envelope2D(null, 0, 0, 1, 1));
- final Expression<? super AbstractFeature, ?> arg2 = bbox.getExpressions().get(1);
++ final Expression<AbstractFeature,?> arg2 = bbox.getExpressions().get(1);
+ assertSame("The two ways to acquire the second argument return different values.", arg2, bbox.getExpressions().get(1));
assertInstanceOf("Second argument value should be an envelope.", Envelope.class,
- ((Literal<? super AbstractFeature, ?>) arg2).getValue());
- ((Literal<Feature,?>) arg2).getValue());
++ ((Literal<AbstractFeature,?>) arg2).getValue());
}
/**
diff --cc core/sis-feature/src/test/java/org/apache/sis/filter/IdentifierFilterTest.java
index 0552ce6a27,d005888119..e08dbc2e1f
--- a/core/sis-feature/src/test/java/org/apache/sis/filter/IdentifierFilterTest.java
+++ b/core/sis-feature/src/test/java/org/apache/sis/filter/IdentifierFilterTest.java
@@@ -73,12 -75,13 +73,13 @@@ public final class IdentifierFilterTes
f1.setPropertyValue("att", "123");
ftb.clear().addAttribute(Integer.class).setName("att").addRole(AttributeRole.IDENTIFIER_COMPONENT);
- final Feature f2 = ftb.setName("Test 2").build().newInstance();
+ final AbstractFeature f2 = ftb.setName("Test 2").build().newInstance();
f2.setPropertyValue("att", 123);
- final Feature f3 = ftb.clear().setName("Test 3").build().newInstance();
+ final AbstractFeature f3 = ftb.clear().setName("Test 3").build().newInstance();
- final Filter<Feature> id = factory.resourceId("123");
- assertEquals(Feature.class, id.getResourceClass());
+ final Filter<AbstractFeature> id = factory.resourceId("123");
++ assertEquals(AbstractFeature.class, id.getResourceClass());
assertTrue (id.test(f1));
assertTrue (id.test(f2));
assertFalse(id.test(f3));
@@@ -101,6 -104,7 +102,7 @@@
factory.resourceId("abc"),
factory.resourceId("123"));
- assertEquals(Feature.class, id.getResourceClass());
++ assertEquals(AbstractFeature.class, id.getResourceClass());
assertTrue (id.test(f1));
assertTrue (id.test(f2));
assertFalse(id.test(f3));
diff --cc core/sis-feature/src/test/java/org/apache/sis/filter/LeafExpressionTest.java
index f380ac0026,c1b80108a7..84976cde44
--- a/core/sis-feature/src/test/java/org/apache/sis/filter/LeafExpressionTest.java
+++ b/core/sis-feature/src/test/java/org/apache/sis/filter/LeafExpressionTest.java
@@@ -89,9 -90,10 +89,10 @@@ public final class LeafExpressionTest e
public void testReferenceEvaluation() {
final FeatureTypeBuilder ftb = new FeatureTypeBuilder();
ftb.addAttribute(String.class).setName("some_property");
- final Feature f = ftb.setName("Test").build().newInstance();
+ final AbstractFeature f = ftb.setName("Test").build().newInstance();
- ValueReference<Feature,?> ref = factory.property("some_property");
- assertEquals(Feature.class, ref.getResourceClass());
+ Expression<AbstractFeature,?> ref = factory.property("some_property");
++ assertEquals(AbstractFeature.class, ref.getResourceClass());
assertNull(ref.apply(f));
assertNull(ref.apply(null));
diff --cc core/sis-feature/src/test/java/org/apache/sis/filter/LogicalFilterTest.java
index 729fbfe24f,5111178236..6cadd74277
--- a/core/sis-feature/src/test/java/org/apache/sis/filter/LogicalFilterTest.java
+++ b/core/sis-feature/src/test/java/org/apache/sis/filter/LogicalFilterTest.java
@@@ -103,12 -108,12 +104,12 @@@ public final class LogicalFilterTest ex
* @param anyArity the function creating a logical operator from an arbitrary number of operands.
* @param expected expected evaluation result.
*/
- private void create(final BiFunction<Filter<? super AbstractFeature>, Filter<? super AbstractFeature>, Filter<AbstractFeature>> binary,
- final Function<Collection<Filter<? super AbstractFeature>>, Filter<AbstractFeature>> anyArity,
- private void create(final BiFunction<Filter<Feature>, Filter<Feature>, LogicalOperator<Feature>> binary,
- final Function<Collection<Filter<Feature>>, LogicalOperator<Feature>> anyArity,
++ private void create(final BiFunction<Filter<AbstractFeature>, Filter<AbstractFeature>, Filter<AbstractFeature>> binary,
++ final Function<Collection<Filter<AbstractFeature>>, Filter<AbstractFeature>> anyArity,
final boolean expected)
{
- final Filter<Feature> f1 = factory.isNull(factory.literal("text"));
- final Filter<Feature> f2 = factory.isNull(factory.literal(null));
+ final Filter<AbstractFeature> f1 = factory.isNull(factory.literal("text"));
+ final Filter<AbstractFeature> f2 = factory.isNull(factory.literal(null));
try {
binary.apply(null, null);
fail("Creation with a null operand shall raise an exception.");
@@@ -137,8 -142,10 +138,10 @@@
assertArrayEquals(new Filter<?>[] {f1, f2}, filter.getOperands().toArray());
assertEquals(expected, filter.test(null));
assertSerializedEquals(filter);
-
+ /*
+ * Same test, using the constructor accepting any number of operands.
+ */
- filter = anyArity.apply(List.of(f1, f2, f1));
+ filter = (LogicalOperator<AbstractFeature>) anyArity.apply(List.of(f1, f2, f1));
assertArrayEquals(new Filter<?>[] {f1, f2, f1}, filter.getOperands().toArray());
assertEquals(expected, filter.test(null));
assertSerializedEquals(filter);
@@@ -170,6 -183,16 +179,16 @@@
assertFalse(factory.not(filterTrue ).test(feature));
assertTrue (factory.not(filterFalse).test(feature));
+ /*
+ * Test the `Predicate` methods, which should be overridden by `Optimization.OnFilter`.
+ */
- Predicate<Feature> predicate = filterTrue.and(filterFalse);
++ Predicate<AbstractFeature> predicate = filterTrue.and(filterFalse);
+ assertInstanceOf("Predicate.and(…)", Optimization.OnFilter.class, predicate);
+ assertFalse(predicate.test(feature));
+
+ predicate = filterTrue.or(filterFalse);
+ assertInstanceOf("Predicate.or(…)", Optimization.OnFilter.class, predicate);
+ assertTrue(predicate.test(feature));
}
/**
diff --cc core/sis-feature/src/test/java/org/apache/sis/filter/PeriodLiteral.java
index b39ae1750d,dc7806ef25..1a110ca368
--- a/core/sis-feature/src/test/java/org/apache/sis/filter/PeriodLiteral.java
+++ b/core/sis-feature/src/test/java/org/apache/sis/filter/PeriodLiteral.java
@@@ -60,7 -73,11 +60,8 @@@ final class PeriodLiteral implements Pe
}
/** Not needed for the tests. */
- @Override public ReferenceIdentifier getName() {throw new UnsupportedOperationException();}
- @Override public RelativePosition relativePosition(TemporalPrimitive o) {throw new UnsupportedOperationException();}
- @Override public Duration distance(TemporalGeometricPrimitive o) {throw new UnsupportedOperationException();}
- @Override public Duration length() {throw new UnsupportedOperationException();}
- @Override public <N> Expression<Feature,N> toValueType(Class<N> target) {throw new UnsupportedOperationException();}
+ @Override public <N> Expression<AbstractFeature,N> toValueType(Class<N> target) {throw new UnsupportedOperationException();}
++ @Override public Class<AbstractFeature> getResourceClass() {return AbstractFeature.class;}
/**
* Hash code value. Used by the tests for checking the results of deserialization.
diff --cc core/sis-feature/src/test/java/org/apache/sis/filter/TemporalFilterTest.java
index e6c11e2938,ead5d8fd3e..feb0a8a78c
--- a/core/sis-feature/src/test/java/org/apache/sis/filter/TemporalFilterTest.java
+++ b/core/sis-feature/src/test/java/org/apache/sis/filter/TemporalFilterTest.java
@@@ -75,7 -78,7 +75,7 @@@ public final class TemporalFilterTest e
private void validate(final TemporalOperatorName name) {
assertInstanceOf("Expected SIS implementation.", TemporalFilter.class, filter);
assertEquals("name", name, filter.getOperatorType());
- final List<Expression<? super AbstractFeature, ?>> operands = filter.getExpressions();
- final List<Expression<Feature,?>> operands = filter.getExpressions();
++ final List<Expression<AbstractFeature,?>> operands = filter.getExpressions();
assertEquals(2, operands.size());
assertSame("expression1", expression1, operands.get(0));
assertSame("expression2", expression2, operands.get(1));
diff --cc core/sis-feature/src/test/java/org/apache/sis/internal/filter/sqlmm/RegistryTestCase.java
index 9dd8219049,2d5e60e320..7dc2374a2b
--- a/core/sis-feature/src/test/java/org/apache/sis/internal/filter/sqlmm/RegistryTestCase.java
+++ b/core/sis-feature/src/test/java/org/apache/sis/internal/filter/sqlmm/RegistryTestCase.java
@@@ -468,7 -470,7 +468,7 @@@ public abstract class RegistryTestCase<
/*
* Optimization should evaluate the point immediately.
*/
- final Expression<? super AbstractFeature, ?> optimized = new Optimization().apply(function);
- final Expression<Feature,?> optimized = new Optimization().apply(function);
++ final Expression<AbstractFeature,?> optimized = new Optimization().apply(function);
assertNotSame("Optimization should produce a new expression.", function, optimized);
assertInstanceOf("Expected immediate expression evaluation.", Literal.class, optimized);
assertPointEquals(((Literal) optimized).getValue(), HardCodedCRS.WGS84_LATITUDE_FIRST, 30, 10);
@@@ -487,7 -489,7 +487,7 @@@
final FeatureTypeBuilder ftb = new FeatureTypeBuilder();
ftb.addAttribute(library.pointClass).setName(P_NAME).setCRS(HardCodedCRS.WGS84);
optimization.setFeatureType(ftb.setName("Test").build());
- final Expression<? super AbstractFeature, ?> optimized = optimization.apply(function);
- final Expression<Feature,?> optimized = optimization.apply(function);
++ final Expression<AbstractFeature,?> optimized = optimization.apply(function);
assertNotSame("Optimization should produce a new expression.", function, optimized);
/*
* Get the second parameter, which should be a literal, and get the point coordinates.
diff --cc storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/FeatureStream.java
index ef6d66e1e0,28649cb1c4..3b7fad02e8
--- a/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/FeatureStream.java
+++ b/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/FeatureStream.java
@@@ -55,10 -55,10 +55,10 @@@ import org.apache.sis.internal.geoapi.f
*
* @author Alexis Manin (Geomatys)
* @author Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.4
* @since 1.1
*/
-final class FeatureStream extends DeferredStream<Feature> {
+final class FeatureStream extends DeferredStream<AbstractFeature> {
/**
* The table which is the source of features.
*/
diff --cc storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/SelectionClauseWriter.java
index e477df9d80,0d847b22c5..2c0abf6ade
--- a/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/SelectionClauseWriter.java
+++ b/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/SelectionClauseWriter.java
@@@ -59,10 -60,10 +59,10 @@@ import org.apache.sis.internal.geoapi.f
*
* @author Alexis Manin (Geomatys)
* @author Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.4
* @since 1.1
*/
-public class SelectionClauseWriter extends Visitor<Feature, SelectionClause> {
+public class SelectionClauseWriter extends Visitor<AbstractFeature, SelectionClause> {
/**
* The default instance.
*/
@@@ -88,7 -89,7 +88,7 @@@
sql.append(" AND "); write(sql, filter.getUpperBoundary());
});
setNullAndNilHandlers((filter, sql) -> {
- final List<Expression<? super AbstractFeature, ?>> expressions = filter.getExpressions();
- final List<Expression<Feature, ?>> expressions = filter.getExpressions();
++ final List<Expression<AbstractFeature, ?>> expressions = filter.getExpressions();
if (expressions.size() == 1) {
write(sql, expressions.get(0));
sql.append(" IS NULL");
@@@ -246,9 -243,8 +242,8 @@@
* @param expression the expression for which to execute an action based on its type.
* @return value of {@link SelectionClause#isInvalid} flag, for allowing caller to short-circuit.
*/
- @SuppressWarnings("unchecked")
- private boolean write(final SelectionClause sql, final Expression<? super AbstractFeature, ?> expression) {
- visit((Expression<AbstractFeature, ?>) expression, sql);
- private boolean write(final SelectionClause sql, final Expression<Feature, ?> expression) {
++ private boolean write(final SelectionClause sql, final Expression<AbstractFeature, ?> expression) {
+ visit(expression, sql);
return sql.isInvalid;
}
@@@ -272,7 -268,7 +267,7 @@@
* @param separator the separator to insert between expression.
* @param binary whether the list of expressions shall contain exactly 2 elements.
*/
- private void writeParameters(final SelectionClause sql, final List<Expression<? super AbstractFeature, ?>> expressions,
- private void writeParameters(final SelectionClause sql, final List<Expression<Feature,?>> expressions,
++ private void writeParameters(final SelectionClause sql, final List<Expression<AbstractFeature,?>> expressions,
final String separator, final boolean binary)
{
final int n = expressions.size();
@@@ -317,9 -313,9 +312,9 @@@
}
/** Invoked when a logical filter needs to be converted to SQL clause. */
- @Override public void accept(final Filter<Feature> f, final SelectionClause sql) {
- final LogicalOperator<Feature> filter = (LogicalOperator<Feature>) f;
- final List<Filter<Feature>> operands = filter.getOperands();
+ @Override public void accept(final Filter<AbstractFeature> f, final SelectionClause sql) {
- final LogicalOperator<AbstractFeature> filter = (LogicalOperator<AbstractFeature>) f;
- final List<Filter<? super AbstractFeature>> operands = filter.getOperands();
++ final var filter = (LogicalOperator<AbstractFeature>) f;
++ final List<Filter<AbstractFeature>> operands = filter.getOperands();
final int n = operands.size();
if (unary ? (n != 1) : (n == 0)) {
sql.invalidate();
diff --cc storage/sis-sqlstore/src/test/java/org/apache/sis/internal/sql/feature/SelectionClauseWriterTest.java
index bd404e202f,d89eb696de..25e04e0079
--- a/storage/sis-sqlstore/src/test/java/org/apache/sis/internal/sql/feature/SelectionClauseWriterTest.java
+++ b/storage/sis-sqlstore/src/test/java/org/apache/sis/internal/sql/feature/SelectionClauseWriterTest.java
@@@ -140,7 -142,7 +140,7 @@@ public final class SelectionClauseWrite
* Formats the given filter as a SQL {@code WHERE} statement body
* and verifies that the result is equal to the expected string.
*/
- private void verifySQL(final Filter<? super AbstractFeature> filter, final String expected) {
- private void verifySQL(final Filter<Feature> filter, final String expected) {
++ private void verifySQL(final Filter<AbstractFeature> filter, final String expected) {
final SelectionClause sql = new SelectionClause(table);
assertTrue(sql.tryAppend(SelectionClauseWriter.DEFAULT, filter));
assertEquals(expected, sql.toString());
diff --cc storage/sis-storage/src/main/java/org/apache/sis/storage/FeatureQuery.java
index 30be91a062,0459d9af4f..a95ce19519
--- a/storage/sis-storage/src/main/java/org/apache/sis/storage/FeatureQuery.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/storage/FeatureQuery.java
@@@ -112,7 -116,7 +112,7 @@@ public class FeatureQuery extends Quer
* @see #setSelection(Filter)
*/
@SuppressWarnings("serial") // Most SIS implementations are serializable.
- private Filter<? super AbstractFeature> selection;
- private Filter<Feature> selection;
++ private Filter<AbstractFeature> selection;
/**
* The number of feature instances to skip from the beginning.
@@@ -193,12 -197,12 +193,12 @@@
* @throws IllegalArgumentException if a property is duplicated.
*/
@SafeVarargs
- public final void setProjection(final Expression<? super AbstractFeature, ?>... properties) {
- public final void setProjection(final Expression<Feature, ?>... properties) {
++ public final void setProjection(final Expression<AbstractFeature, ?>... properties) {
NamedExpression[] wrappers = null;
if (properties != null) {
wrappers = new NamedExpression[properties.length];
for (int i=0; i<wrappers.length; i++) {
- final Expression<? super AbstractFeature, ?> e = properties[i];
- final Expression<Feature, ?> e = properties[i];
++ final Expression<AbstractFeature, ?> e = properties[i];
ArgumentChecks.ensureNonNullElement("properties", i, e);
wrappers[i] = new NamedExpression(e);
}
@@@ -259,9 -263,9 +259,9 @@@
*/
@Override
public void setSelection(final Envelope domain) {
- Filter<? super AbstractFeature> filter = null;
- Filter<Feature> filter = null;
++ Filter<AbstractFeature> filter = null;
if (domain != null) {
- final FilterFactory<Feature,Object,?> ff = DefaultFilterFactory.forFeatures();
+ final DefaultFilterFactory<AbstractFeature,Object,?> ff = DefaultFilterFactory.forFeatures();
filter = ff.bbox(ff.property(AttributeConvention.GEOMETRY), domain);
}
setSelection(filter);
@@@ -274,7 -278,7 +274,7 @@@
*
* @param selection the filter, or {@code null} if none.
*/
- public void setSelection(final Filter<? super AbstractFeature> selection) {
- public void setSelection(final Filter<Feature> selection) {
++ public void setSelection(final Filter<AbstractFeature> selection) {
this.selection = selection;
}
@@@ -285,7 -289,7 +285,7 @@@
*
* @return the filter, or {@code null} if none.
*/
- public Filter<? super AbstractFeature> getSelection() {
- public Filter<Feature> getSelection() {
++ public Filter<AbstractFeature> getSelection() {
return selection;
}
@@@ -485,7 -483,7 +485,7 @@@
* Never {@code null}.
*/
@SuppressWarnings("serial")
- public final Expression<? super AbstractFeature, ?> expression;
- public final Expression<Feature,?> expression;
++ public final Expression<AbstractFeature,?> expression;
/**
* The name to assign to the expression result, or {@code null} if unspecified.
@@@ -508,7 -506,7 +508,7 @@@
*
* @param expression the literal, value reference or expression to be retrieved by a {@code Query}.
*/
- public NamedExpression(final Expression<? super AbstractFeature, ?> expression) {
- public NamedExpression(final Expression<Feature,?> expression) {
++ public NamedExpression(final Expression<AbstractFeature,?> expression) {
this(expression, (GenericName) null);
}
@@@ -518,7 -516,7 +518,7 @@@
* @param expression the literal, value reference or expression to be retrieved by a {@code Query}.
* @param alias the name to assign to the expression result, or {@code null} if unspecified.
*/
- public NamedExpression(final Expression<? super AbstractFeature, ?> expression, final GenericName alias) {
- public NamedExpression(final Expression<Feature,?> expression, final GenericName alias) {
++ public NamedExpression(final Expression<AbstractFeature,?> expression, final GenericName alias) {
this(expression, alias, ProjectionType.STORED);
}
@@@ -529,7 -527,7 +529,7 @@@
* @param expression the literal, value reference or expression to be retrieved by a {@code Query}.
* @param alias the name to assign to the expression result, or {@code null} if unspecified.
*/
- public NamedExpression(final Expression<? super AbstractFeature, ?> expression, final String alias) {
- public NamedExpression(final Expression<Feature,?> expression, final String alias) {
++ public NamedExpression(final Expression<AbstractFeature,?> expression, final String alias) {
ArgumentChecks.ensureNonNull("expression", expression);
this.expression = expression;
this.alias = (alias != null) ? Names.createLocalName(null, null, alias) : null;
@@@ -545,7 -543,7 +545,7 @@@
*
* @since 1.4
*/
- public NamedExpression(final Expression<? super AbstractFeature, ?> expression, final GenericName alias, ProjectionType type) {
- public NamedExpression(final Expression<Feature,?> expression, final GenericName alias, ProjectionType type) {
++ public NamedExpression(final Expression<AbstractFeature,?> expression, final GenericName alias, ProjectionType type) {
ArgumentChecks.ensureNonNull("expression", expression);
ArgumentChecks.ensureNonNull("type", type);
this.expression = expression;
@@@ -689,7 -687,7 +689,7 @@@
* For each property, get the expected type (mandatory) and its name (optional).
* A default name will be computed if no alias were explicitly given by user.
*/
- final Expression<? super AbstractFeature,?> expression = item.expression;
- final Expression<Feature,?> expression = item.expression;
++ final Expression<AbstractFeature,?> expression = item.expression;
final FeatureExpression<?,?> fex = FeatureExpression.castOrCopy(expression);
final PropertyTypeBuilder resultType;
if (fex == null || (resultType = fex.expectedType(valueType, ftb)) == null) {
diff --cc storage/sis-storage/src/main/java/org/apache/sis/storage/FeatureSubset.java
index 71bc463b1b,920c859c43..5a1b87e95d
--- a/storage/sis-storage/src/main/java/org/apache/sis/storage/FeatureSubset.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/storage/FeatureSubset.java
@@@ -110,7 -110,7 +110,7 @@@ final class FeatureSubset extends Abstr
/*
* Apply filter.
*/
- final Filter<? super AbstractFeature> selection = query.getSelection();
- final Filter<Feature> selection = query.getSelection();
++ final Filter<AbstractFeature> selection = query.getSelection();
if (selection != null && !selection.equals(Filter.include())) {
stream = stream.filter(selection);
}
@@@ -142,7 -142,7 +142,7 @@@
final FeatureQuery.NamedExpression[] projection = query.getProjection();
if (projection != null) {
@SuppressWarnings({"unchecked", "rawtypes"})
- final Expression<? super AbstractFeature, ?>[] expressions = new Expression[projection.length];
- final Expression<Feature,?>[] expressions = new Expression[projection.length];
++ final Expression<AbstractFeature,?>[] expressions = new Expression[projection.length];
for (int i=0; i<expressions.length; i++) {
expressions[i] = projection[i].expression;
}
diff --cc storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/JoinFeatureSet.java
index 61931e80bf,c4a98d419b..ea0c32ac16
--- a/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/JoinFeatureSet.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/JoinFeatureSet.java
@@@ -174,7 -176,7 +174,7 @@@ public class JoinFeatureSet extends Agg
* This condition specifies also if the comparison is {@linkplain BinaryComparisonOperator#isMatchingCase() case
* sensitive} and {@linkplain BinaryComparisonOperator#getMatchAction() how to compare multi-values}.
*/
- public final BinaryComparisonOperator<? super AbstractFeature> condition;
- public final BinaryComparisonOperator<Feature> condition;
++ public final BinaryComparisonOperator<AbstractFeature> condition;
/**
* The factory to use for creating {@code Query} expressions for retrieving subsets of feature sets.
@@@ -206,7 -208,7 +206,7 @@@
public JoinFeatureSet(final Resource parent,
final FeatureSet left, String leftAlias,
final FeatureSet right, String rightAlias,
- final Type joinType, final BinaryComparisonOperator<? super AbstractFeature> condition,
- final Type joinType, final BinaryComparisonOperator<Feature> condition,
++ final Type joinType, final BinaryComparisonOperator<AbstractFeature> condition,
Map<String,?> featureInfo)
throws DataStoreException
{
@@@ -462,7 -464,7 +462,7 @@@
* The filtering condition is determined by the current {@link #mainFeature}.
*/
private void createFilteredIterator() {
- final Expression<? super AbstractFeature, ?> expression1, expression2;
- final Expression<Feature,?> expression1, expression2;
++ final Expression<AbstractFeature,?> expression1, expression2;
final FeatureSet filteredSet;
if (swapSides) {
expression1 = condition.getOperand2();
@@@ -474,9 -476,10 +474,9 @@@
filteredSet = right;
}
final Object mainValue = expression1.apply(mainFeature);
- final Filter<? super AbstractFeature> filter;
- final Filter<Feature> filter;
++ final Filter<AbstractFeature> filter;
if (mainValue != null) {
- filter = factory.equal(expression2, factory.literal(mainValue),
- condition.isMatchingCase(), condition.getMatchAction());
+ filter = factory.equal(expression2, factory.literal(mainValue));
} else {
filter = factory.isNull(expression2);
}
diff --cc storage/sis-storage/src/test/java/org/apache/sis/storage/FeatureQueryTest.java
index 91886d5b03,b4aa6f3786..04073e0a50
--- a/storage/sis-storage/src/test/java/org/apache/sis/storage/FeatureQueryTest.java
+++ b/storage/sis-storage/src/test/java/org/apache/sis/storage/FeatureQueryTest.java
@@@ -272,16 -291,16 +272,16 @@@ public final class FeatureQueryTest ext
new FeatureQuery.NamedExpression(ff.property("/*/unknown"), "unexpected"));
// Check result type.
- final Feature instance = executeAndGetFirst();
- final FeatureType resultType = instance.getType();
+ final AbstractFeature instance = executeAndGetFirst();
+ final DefaultFeatureType resultType = instance.getType();
assertEquals("Test", resultType.getName().toString());
assertEquals(2, resultType.getProperties(true).size());
- final PropertyType pt1 = resultType.getProperty("value1");
- final PropertyType pt2 = resultType.getProperty("unexpected");
- assertTrue(pt1 instanceof AttributeType<?>);
- assertTrue(pt2 instanceof AttributeType<?>);
- assertEquals(Integer.class, ((AttributeType<?>) pt1).getValueClass());
- assertEquals(Object.class, ((AttributeType<?>) pt2).getValueClass());
+ final AbstractIdentifiedType pt1 = resultType.getProperty("value1");
+ final AbstractIdentifiedType pt2 = resultType.getProperty("unexpected");
- assertTrue(pt1 instanceof DefaultAttributeType);
- assertTrue(pt2 instanceof DefaultAttributeType);
- assertEquals(Integer.class, ((DefaultAttributeType) pt1).getValueClass());
- assertEquals(Object.class, ((DefaultAttributeType) pt2).getValueClass());
++ assertTrue(pt1 instanceof DefaultAttributeType<?>);
++ assertTrue(pt2 instanceof DefaultAttributeType<?>);
++ assertEquals(Integer.class, ((DefaultAttributeType<?>) pt1).getValueClass());
++ assertEquals(Object.class, ((DefaultAttributeType<?>) pt2).getValueClass());
// Check feature property values.
assertEquals(3, instance.getPropertyValue("value1"));
@@@ -308,7 -327,7 +308,7 @@@
/**
* Shortcut for creating expression for a projection computed on-the-fly.
*/
- private static FeatureQuery.NamedExpression virtualProjection(final Expression<? super AbstractFeature, ?> expression, final String alias) {
- private static FeatureQuery.NamedExpression virtualProjection(final Expression<Feature, ?> expression, final String alias) {
++ private static FeatureQuery.NamedExpression virtualProjection(final Expression<AbstractFeature, ?> expression, final String alias) {
return new FeatureQuery.NamedExpression(expression, Names.createLocalName(null, null, alias), FeatureQuery.ProjectionType.VIRTUAL);
}
@@@ -326,21 -345,23 +326,23 @@@
virtualProjection(ff.literal("a literal"), "computed"));
// Check result type.
- final Feature instance = executeAndGetFirst();
- final FeatureType resultType = instance.getType();
+ final AbstractFeature instance = executeAndGetFirst();
+ final DefaultFeatureType resultType = instance.getType();
assertEquals("Test", resultType.getName().toString());
assertEquals(3, resultType.getProperties(true).size());
- final PropertyType pt1 = resultType.getProperty("value1");
- final PropertyType pt2 = resultType.getProperty("renamed1");
- final PropertyType pt3 = resultType.getProperty("computed");
- assertTrue(pt1 instanceof AttributeType<?>);
- assertTrue(pt2 instanceof Operation);
- assertTrue(pt3 instanceof Operation);
- final IdentifiedType result2 = ((Operation) pt2).getResult();
- final IdentifiedType result3 = ((Operation) pt3).getResult();
- assertEquals(Integer.class, ((AttributeType<?>) pt1).getValueClass());
- assertTrue(result2 instanceof AttributeType<?>);
- assertTrue(result3 instanceof AttributeType<?>);
- assertEquals(Integer.class, ((AttributeType<?>) result2).getValueClass());
- assertEquals(String.class, ((AttributeType<?>) result3).getValueClass());
+ final AbstractIdentifiedType pt1 = resultType.getProperty("value1");
+ final AbstractIdentifiedType pt2 = resultType.getProperty("renamed1");
+ final AbstractIdentifiedType pt3 = resultType.getProperty("computed");
- assertTrue(pt1 instanceof DefaultAttributeType);
++ assertTrue(pt1 instanceof DefaultAttributeType<?>);
+ assertTrue(pt2 instanceof AbstractOperation);
+ assertTrue(pt3 instanceof AbstractOperation);
- assertEquals(Integer.class, ((DefaultAttributeType) pt1).getValueClass());
- assertTrue(((AbstractOperation) pt2).getResult() instanceof DefaultAttributeType);
- assertTrue(((AbstractOperation) pt3).getResult() instanceof DefaultAttributeType);
- assertEquals(Integer.class, ((DefaultAttributeType)((AbstractOperation) pt2).getResult()).getValueClass());
- assertEquals(String.class, ((DefaultAttributeType)((AbstractOperation) pt3).getResult()).getValueClass());
++ final AbstractIdentifiedType result2 = ((AbstractOperation) pt2).getResult();
++ final AbstractIdentifiedType result3 = ((AbstractOperation) pt3).getResult();
++ assertEquals(Integer.class, ((DefaultAttributeType<?>) pt1).getValueClass());
++ assertTrue(result2 instanceof DefaultAttributeType<?>);
++ assertTrue(result3 instanceof DefaultAttributeType<?>);
++ assertEquals(Integer.class, ((DefaultAttributeType<?>) result2).getValueClass());
++ assertEquals(String.class, ((DefaultAttributeType<?>) result3).getValueClass());
// Check feature instance.
assertEquals(3, instance.getPropertyValue("value1"));