From cfcea2efd49e7fccb3423b4c1c005df5caea1001 Mon Sep 17 00:00:00 2001 From: Michael Simons Date: Tue, 19 Nov 2019 11:36:12 +0100 Subject: [PATCH] DATAGRAPH-1268 - Remove usage of deprecated Filter#setPropertyName. --- .../filter/BetweenComparisonBuilder.java | 25 ++++---- .../filter/BooleanComparisonBuilder.java | 9 ++- .../filter/ContainsComparisonBuilder.java | 12 ++-- .../filter/DistanceComparisonBuilder.java | 9 ++- .../query/filter/ExistsFilterBuilder.java | 9 ++- .../query/filter/FilterBuilder.java | 64 +++++++++++++++++-- .../query/filter/IsNullFilterBuilder.java | 10 ++- .../filter/PropertyComparisonBuilder.java | 9 +-- 8 files changed, 111 insertions(+), 36 deletions(-) diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/filter/BetweenComparisonBuilder.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/filter/BetweenComparisonBuilder.java index c4edc2655..2a699bcd9 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/filter/BetweenComparisonBuilder.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/filter/BetweenComparisonBuilder.java @@ -24,7 +24,6 @@ import java.util.Stack; import org.neo4j.ogm.cypher.BooleanOperator; import org.neo4j.ogm.cypher.ComparisonOperator; import org.neo4j.ogm.cypher.Filter; -import org.neo4j.ogm.cypher.function.PropertyComparison; import org.springframework.data.domain.Range; import org.springframework.data.repository.query.parser.Part; @@ -65,29 +64,31 @@ class BetweenComparisonBuilder extends FilterBuilder { upperBoundValue = params.pop(); } - Filter lowerBoundFilter = createLowerBoundFilter(lowerBoundValue, inclusiveLowerBound); - setNestedAttributes(part, lowerBoundFilter); + NestedAttributes nestedAttributes = getNestedAttributes(part); - Filter upperBoundFilter = createUpperBoundFilter(upperBoundValue, inclusiveUpperBound); - setNestedAttributes(part, upperBoundFilter); + Filter lowerBoundFilter = createLowerBoundFilter(lowerBoundValue, inclusiveLowerBound, nestedAttributes); + Filter upperBoundFilter = createUpperBoundFilter(upperBoundValue, inclusiveUpperBound, nestedAttributes); return Arrays.asList(lowerBoundFilter, upperBoundFilter); } - private Filter createLowerBoundFilter(Object value, boolean inclusive) { - return createBoundFilter(Bound.LOWER, value, inclusive, booleanOperator); + private Filter createLowerBoundFilter(Object value, boolean inclusive, NestedAttributes nestedAttributes) { + return createBoundFilter(Bound.LOWER, value, inclusive, booleanOperator, nestedAttributes); } - private Filter createUpperBoundFilter(Object value, boolean inclusive) { - return createBoundFilter(Bound.UPPER, value, inclusive, BooleanOperator.AND); + private Filter createUpperBoundFilter(Object value, boolean inclusive, NestedAttributes nestedAttributes) { + return createBoundFilter(Bound.UPPER, value, inclusive, BooleanOperator.AND, nestedAttributes); } - private Filter createBoundFilter(Bound bound, Object value, boolean inclusive, BooleanOperator operator) { - Filter filter = new Filter(propertyName(), deriveComparisonOperator(bound, inclusive), value); + private Filter createBoundFilter(Bound bound, Object value, boolean inclusive, BooleanOperator operator, + NestedAttributes nestedAttributes) { + Filter filter = new Filter(nestedAttributes.isEmpty() ? + propertyName() : + nestedAttributes.getLeafPropertySegment(), deriveComparisonOperator(bound, inclusive), value); filter.setOwnerEntityType(entityType); filter.setNegated(isNegated()); - filter.setFunction(new PropertyComparison(value)); filter.setBooleanOperator(operator); + filter.setNestedPath(nestedAttributes.getSegments()); return filter; } diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/filter/BooleanComparisonBuilder.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/filter/BooleanComparisonBuilder.java index ba3e11d0c..20e19941c 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/filter/BooleanComparisonBuilder.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/filter/BooleanComparisonBuilder.java @@ -39,11 +39,16 @@ class BooleanComparisonBuilder extends FilterBuilder { @Override public List build(Stack params) { - Filter filter = new Filter(propertyName(), ComparisonOperator.IS_TRUE); + + NestedAttributes nestedAttributes = getNestedAttributes(part); + + Filter filter = new Filter( + nestedAttributes.isEmpty() ? propertyName() : nestedAttributes.getLeafPropertySegment(), + ComparisonOperator.IS_TRUE); filter.setOwnerEntityType(entityType); filter.setBooleanOperator(booleanOperator); filter.setNegated(isNegated() || part.getType() == FALSE); - setNestedAttributes(part, filter); + filter.setNestedPath(nestedAttributes.getSegments()); return Collections.singletonList(filter); } diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/filter/ContainsComparisonBuilder.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/filter/ContainsComparisonBuilder.java index 48aa52a8d..5d22175d0 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/filter/ContainsComparisonBuilder.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/filter/ContainsComparisonBuilder.java @@ -29,6 +29,7 @@ import org.springframework.data.repository.query.parser.Part; * Filter for entities having a collection like property (not) containing a given element. * * @author Gerrit Meier + * @author Michael J. Simons */ class ContainsComparisonBuilder extends FilterBuilder { @@ -38,15 +39,18 @@ class ContainsComparisonBuilder extends FilterBuilder { @Override public List build(Stack params) { + + NestedAttributes nestedAttributes = getNestedAttributes(part); + final Object containingValue = params.pop(); - Filter containingFilter = new Filter(propertyName(), ComparisonOperator.IN, containingValue); + Filter containingFilter = new Filter( + nestedAttributes.isEmpty() ? propertyName() : nestedAttributes.getLeafPropertySegment(), + new ContainsAnyComparison(containingValue), ComparisonOperator.IN); containingFilter.setOwnerEntityType(entityType); containingFilter.setBooleanOperator(booleanOperator); containingFilter.setNegated(isNegated()); - containingFilter.setFunction(new ContainsAnyComparison(containingValue)); - setNestedAttributes(part, containingFilter); + containingFilter.setNestedPath(nestedAttributes.getSegments()); return Collections.singletonList(containingFilter); } - } diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/filter/DistanceComparisonBuilder.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/filter/DistanceComparisonBuilder.java index 8274866fc..b43622b9f 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/filter/DistanceComparisonBuilder.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/filter/DistanceComparisonBuilder.java @@ -107,13 +107,14 @@ class DistanceComparisonBuilder extends FilterBuilder { NativeDistanceComparison distanceComparison = NativeDistanceComparison .distanceComparisonFor(new DistanceFromNativePoint(spatialPoint, meters)); + NestedAttributes nestedAttributes = getNestedAttributes(part); String propertyName = super.part.getProperty().getLeafProperty().getSegment(); Filter filter = new Filter(propertyName, distanceComparison, ComparisonOperator.LESS_THAN); filter.setOwnerEntityType(entityType); filter.setBooleanOperator(booleanOperator); filter.setNegated(isNegated()); - setNestedAttributes(part, filter); + filter.setNestedPath(nestedAttributes.getSegments()); return filter; } @@ -135,11 +136,13 @@ class DistanceComparisonBuilder extends FilterBuilder { } }; - Filter filter = new Filter(distanceComparison, ComparisonOperator.LESS_THAN); + NestedAttributes nestedAttributes = getNestedAttributes(part); + + Filter filter = new Filter(nestedAttributes.getLeafPropertySegment(), distanceComparison, ComparisonOperator.LESS_THAN); filter.setOwnerEntityType(entityType); filter.setBooleanOperator(booleanOperator); filter.setNegated(isNegated()); - setNestedAttributes(part, filter); + filter.setNestedPath(nestedAttributes.getSegments()); return filter; } diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/filter/ExistsFilterBuilder.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/filter/ExistsFilterBuilder.java index bff07e4ff..426109b57 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/filter/ExistsFilterBuilder.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/filter/ExistsFilterBuilder.java @@ -37,11 +37,16 @@ class ExistsFilterBuilder extends FilterBuilder { @Override public List build(Stack params) { - Filter filter = new Filter(propertyName(), ComparisonOperator.EXISTS); + + NestedAttributes nestedAttributes = getNestedAttributes(part); + + Filter filter = new Filter( + nestedAttributes.isEmpty() ? propertyName() : nestedAttributes.getLeafPropertySegment(), + ComparisonOperator.EXISTS); filter.setOwnerEntityType(entityType); filter.setBooleanOperator(booleanOperator); filter.setNegated(isNegated()); - setNestedAttributes(part, filter); + filter.setNestedPath(nestedAttributes.getSegments()); return Collections.singletonList(filter); } diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/filter/FilterBuilder.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/filter/FilterBuilder.java index b68a3fe2c..2cd3e228b 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/filter/FilterBuilder.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/filter/FilterBuilder.java @@ -16,15 +16,21 @@ package org.springframework.data.neo4j.repository.query.filter; import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import java.util.Objects; import java.util.Stack; import org.neo4j.ogm.cypher.BooleanOperator; import org.neo4j.ogm.cypher.Filter; import org.springframework.data.mapping.PropertyPath; import org.springframework.data.repository.query.parser.Part; +import org.springframework.lang.Nullable; /** + * The name of this class is wrong: It builds a list of filters, not a single filter. Starting with Neo4j-OGM 4.0, + * there will be an actual filter builder in OGM and this class needs to be renamed. + * * @author Jasper Blues * @author Nicolas Mervaillie * @author Gerrit Meier @@ -74,17 +80,63 @@ public abstract class FilterBuilder { return part.getProperty().getSegment(); } - protected void setNestedAttributes(Part part, Filter filter) { - List segments = new ArrayList<>(); + protected final NestedAttributes getNestedAttributes(Part part) { + PropertyPath property = part.getProperty(); - if (property.hasNext()) { - filter.setOwnerEntityType(property.getOwningType().getType()); + if (!property.hasNext()) { + return EMPTY_NESTED_ATTRIBUTES; + } else { + List segments = new ArrayList<>(); segments.add(new Filter.NestedPathSegment(property.getSegment(), property.getType())); segments.addAll(deepNestedProperty(property)); - filter.setPropertyName(property.getLeafProperty().getSegment()); - filter.setNestedPath(segments.toArray(new Filter.NestedPathSegment[0])); + return new NestedAttributes(property.getOwningType().getType(), segments, + property.getLeafProperty().getSegment()); + } + } + + public static final NestedAttributes EMPTY_NESTED_ATTRIBUTES = new NestedAttributes(Void.class, + Collections.emptyList(), null); + + protected static final class NestedAttributes { + + private final Class owningType; + private final List segments; + private final String leafPropertySegment; + + NestedAttributes(Class owningType, List segments, + @Nullable String leafPropertySegment) { + this.owningType = owningType; + this.segments = new ArrayList<>(segments); + this.leafPropertySegment = leafPropertySegment; } + public Filter.NestedPathSegment[] getSegments() { + return segments.toArray(new Filter.NestedPathSegment[segments.size()]); + } + + public String getLeafPropertySegment() { + return leafPropertySegment; + } + + public boolean isEmpty() { + return this == EMPTY_NESTED_ATTRIBUTES; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + NestedAttributes that = (NestedAttributes) o; + return owningType.equals(that.owningType) && + segments.equals(that.segments) && + Objects.equals(leafPropertySegment, that.leafPropertySegment); + } + + @Override public int hashCode() { + return Objects.hash(owningType, segments, leafPropertySegment); + } } private List deepNestedProperty(PropertyPath path) { diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/filter/IsNullFilterBuilder.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/filter/IsNullFilterBuilder.java index c9503e707..c9828405e 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/filter/IsNullFilterBuilder.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/filter/IsNullFilterBuilder.java @@ -39,13 +39,17 @@ class IsNullFilterBuilder extends FilterBuilder { @Override public List build(Stack params) { - Filter filter = new Filter(propertyName(), ComparisonOperator.IS_NULL); + + NestedAttributes nestedAttributes = getNestedAttributes(part); + + Filter filter = new Filter( + nestedAttributes.isEmpty() ? propertyName() : nestedAttributes.getLeafPropertySegment(), + ComparisonOperator.IS_NULL); filter.setOwnerEntityType(entityType); filter.setBooleanOperator(booleanOperator); filter.setNegated(isNegated() || part.getType() == IS_NOT_NULL); - setNestedAttributes(part, filter); + filter.setNestedPath(nestedAttributes.getSegments()); return Collections.singletonList(filter); } - } diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/filter/PropertyComparisonBuilder.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/filter/PropertyComparisonBuilder.java index 2d65e53e1..9284c01d4 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/filter/PropertyComparisonBuilder.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/query/filter/PropertyComparisonBuilder.java @@ -41,13 +41,15 @@ class PropertyComparisonBuilder extends FilterBuilder { @Override public List build(Stack params) { + NestedAttributes nestedAttributes = getNestedAttributes(part); + Object value = params.pop(); - Filter filter = new Filter(propertyName(), convertToComparisonOperator(part.getType()), value); + Filter filter = new Filter(nestedAttributes.isEmpty() ? propertyName() : nestedAttributes.getLeafPropertySegment(), convertToComparisonOperator(part.getType()), value); filter.setOwnerEntityType(entityType); filter.setBooleanOperator(booleanOperator); filter.setNegated(isNegated()); - setNestedAttributes(part, filter); + filter.setNestedPath(nestedAttributes.getSegments()); applyCaseInsensitivityIfShouldIgnoreCase(part, filter); return Collections.singletonList(filter); @@ -90,8 +92,7 @@ class PropertyComparisonBuilder extends FilterBuilder { /** * Sets the filter to ignore the case in case the underlying {@link Part} requires ignoring case and the property - * actually supports it. Note: The method is modelled after {@link #setNestedAttributes(Part, Filter)} to have some - * consistency. Preferable it should return a new filter. + * actually supports it. * * @param part * @param filter