From 2885c35511821469932d434da4bf96e8c11f6aa7 Mon Sep 17 00:00:00 2001 From: Clement Petit Date: Tue, 30 Mar 2021 00:02:10 +0200 Subject: [PATCH] =?UTF-8?q?Handle=20nested=20Pattern=20and=20Document=20in?= =?UTF-8?q?=20Criteria.equals(=E2=80=A6).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #3414 Original pull request: #3615. --- .../data/mongodb/core/query/Criteria.java | 47 ++++++++++++++++++- .../mongodb/core/query/CriteriaUnitTests.java | 25 ++++++++++ 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Criteria.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Criteria.java index 43a0592df..c637f54c4 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Criteria.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Criteria.java @@ -20,8 +20,10 @@ import static org.springframework.util.ObjectUtils.*; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.Map.Entry; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -59,6 +61,7 @@ import com.mongodb.BasicDBList; * @author Mark Paluch * @author Andreas Zink * @author Ziemowit Stolarczyk + * @author Clément Petit */ public class Criteria implements CriteriaDefinition { @@ -976,9 +979,9 @@ public class Criteria implements CriteriaDefinition { return right == null; } - if (Pattern.class.isInstance(left)) { + if (left instanceof Pattern) { - if (!Pattern.class.isInstance(right)) { + if (!(right instanceof Pattern)) { return false; } @@ -989,6 +992,46 @@ public class Criteria implements CriteriaDefinition { && leftPattern.flags() == rightPattern.flags(); } + if (left instanceof Document) { + if (!(right instanceof Document)) { + return false; + } + Document leftDocument = (Document) left; + Document rightDocument = (Document) right; + Iterator leftIterator = leftDocument.entrySet().iterator(); + Iterator rightIterator = rightDocument.entrySet().iterator(); + + while (leftIterator.hasNext() && rightIterator.hasNext()) { + Map.Entry leftEntry = (Map.Entry)leftIterator.next(); + Map.Entry rightEntry = (Map.Entry)rightIterator.next(); + if (!isEqual(leftEntry.getKey(), rightEntry.getKey())) { + return false; + } + if (!isEqual(leftEntry.getValue(), rightEntry.getValue())) { + return false; + } + } + return !leftIterator.hasNext() && !rightIterator.hasNext(); + } + + if (Collection.class.isAssignableFrom(left.getClass())) { + if (!Collection.class.isAssignableFrom(right.getClass())) { + return false; + } + + Collection leftCollection = (Collection) left; + Collection rightCollection = (Collection) right; + Iterator leftIterator = leftCollection.iterator(); + Iterator rightIterator = rightCollection.iterator(); + + while (leftIterator.hasNext() && rightIterator.hasNext()) { + if (!isEqual(leftIterator.next(), rightIterator.next())) { + return false; + } + } + return !leftIterator.hasNext() && !rightIterator.hasNext(); + } + return ObjectUtils.nullSafeEquals(left, right); } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/CriteriaUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/CriteriaUnitTests.java index 01e3b1883..6d0c3a167 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/CriteriaUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/CriteriaUnitTests.java @@ -38,6 +38,7 @@ import org.springframework.data.mongodb.core.schema.MongoJsonSchema; * @author Christoph Strobl * @author Andreas Zink * @author Ziemowit Stolarczyk + * @author Clément Petit */ public class CriteriaUnitTests { @@ -353,9 +354,33 @@ public class CriteriaUnitTests { @Test // DATAMONGO-2002 public void shouldEqualForSamePattern() { + Criteria left = new Criteria("field").regex("foo"); + Criteria right = new Criteria("field").regex("foo"); + + assertThat(left).isEqualTo(right); + } + + @Test // DATAMONGO-2002 + public void shouldEqualForSamePatternAndFlags() { + Criteria left = new Criteria("field").regex("foo", "iu"); Criteria right = new Criteria("field").regex("foo"); assertThat(left).isNotEqualTo(right); } + + @Test // GH-3414 + public void shouldEqualForNestedPattern() { + + Criteria left = new Criteria("a").orOperator( + new Criteria("foo").regex("value", "i"), + new Criteria("bar").regex("value") + ); + Criteria right = new Criteria("a").orOperator( + new Criteria("foo").regex("value", "i"), + new Criteria("bar").regex("value") + ); + + assertThat(left).isEqualTo(right); + } }