From 3e1f95bc94a9bde9f6d20ae2a760d4dc53b7cf9f 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 cc99ad69d7..39c666d036 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 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; @@ -58,6 +60,7 @@ * @author Christoph Strobl * @author Mark Paluch * @author Andreas Zink + * @author Clément Petit */ public class Criteria implements CriteriaDefinition { @@ -901,9 +904,9 @@ private boolean isEqual(Object left, Object right) { return right == null; } - if (Pattern.class.isInstance(left)) { + if (left instanceof Pattern) { - if (!Pattern.class.isInstance(right)) { + if (!(right instanceof Pattern)) { return false; } @@ -914,6 +917,46 @@ private boolean isEqual(Object left, Object right) { && 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 6ed3fe6f1d..7496cf83fc 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 @@ -34,6 +34,7 @@ * @author Thomas Darimont * @author Christoph Strobl * @author Andreas Zink + * @author Clément Petit */ public class CriteriaUnitTests { @@ -310,9 +311,33 @@ public void shouldAppendBitsAnySetWithPositionListCorrectly() { @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); + } }