From 1fb76d135be9f374253b92b59816fc50a8962349 Mon Sep 17 00:00:00 2001 From: Thomas Darimont Date: Thu, 12 Jun 2014 16:40:24 +0200 Subject: [PATCH] =?UTF-8?q?DATAMONGO-953=20-=20Add=20equals(=E2=80=A6)/has?= =?UTF-8?q?hCode()/toString()=20to=20Update.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We now use the underlying updateObject to implement appropriate equals(…)/hashCode() and toString() methods. Original pull request: #192. --- .../data/mongodb/core/query/Update.java | 156 +++++++++++++++++- .../data/mongodb/core/query/UpdateTests.java | 58 +++++++ 2 files changed, 210 insertions(+), 4 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Update.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Update.java index e75c844f9..948297c7a 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Update.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Update.java @@ -15,10 +15,11 @@ */ package org.springframework.data.mongodb.core.query; +import static org.springframework.util.ObjectUtils.*; + import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; @@ -40,6 +41,7 @@ import com.mongodb.DBObject; * @author Oliver Gierke * @author Becca Gaspard * @author Christoph Strobl + * @author Thomas Darimont */ public class Update { @@ -279,6 +281,7 @@ public class Update { } public DBObject getUpdateObject() { + DBObject dbo = new BasicDBObject(); for (String k : modifierOps.keySet()) { dbo.put(k, modifierOps.get(k)); @@ -335,14 +338,52 @@ public class Update { return StringUtils.startsWithIgnoreCase(key, "$"); } + /* + * (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return getUpdateObject().hashCode(); + } + + /* + * (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (obj == null || getClass() != obj.getClass()) { + return false; + } + + Update that = (Update) obj; + return this.getUpdateObject().equals(that.getUpdateObject()); + } + + /* + * (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return getUpdateObject().toString(); + } + /** * Modifiers holds a distinct collection of {@link Modifier} * * @author Christoph Strobl + * @author Thomas Darimont */ public static class Modifiers { - private HashMap modifiers; + private Map modifiers; public Modifiers() { this.modifiers = new LinkedHashMap(1); @@ -355,6 +396,33 @@ public class Update { public void addModifier(Modifier modifier) { this.modifiers.put(modifier.getKey(), modifier); } + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return nullSafeHashCode(modifiers); + } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (obj == null || getClass() != obj.getClass()) { + return false; + } + + Modifiers that = (Modifiers) obj; + + return this.modifiers.equals(that.modifiers); + } } /** @@ -379,6 +447,7 @@ public class Update { * Implementation of {@link Modifier} representing {@code $each}. * * @author Christoph Strobl + * @author Thomas Darimont */ private static class Each implements Modifier { @@ -399,6 +468,7 @@ public class Update { } Object[] convertedValues = new Object[values.length]; + for (int i = 0; i < values.length; i++) { convertedValues[i] = values[i]; } @@ -406,21 +476,57 @@ public class Update { return convertedValues; } + /* + * (non-Javadoc) + * @see org.springframework.data.mongodb.core.query.Update.Modifier#getKey() + */ @Override public String getKey() { return "$each"; } + /* + * (non-Javadoc) + * @see org.springframework.data.mongodb.core.query.Update.Modifier#getValue() + */ @Override public Object getValue() { return this.values; } + + /* + * (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return nullSafeHashCode(values); + } + + /* + * (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object that) { + + if (this == that) { + return true; + } + + if (that == null || getClass() != that.getClass()) { + return false; + } + + return nullSafeEquals(values, ((Each) that).values); + } } /** * Builder for creating {@code $push} modifiers * * @author Christoph Strobl + * @author Thomas Darimont */ public class PushOperatorBuilder { @@ -453,6 +559,50 @@ public class Update { public Update value(Object value) { return Update.this.push(key, value); } + + /* + * (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + + int result = 17; + + result += 31 * result + getOuterType().hashCode(); + result += 31 * result + nullSafeHashCode(key); + result += 31 * result + nullSafeHashCode(modifiers); + + return result; + } + + /* + * (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (obj == null || getClass() != obj.getClass()) { + return false; + } + + PushOperatorBuilder that = (PushOperatorBuilder) obj; + + if (!getOuterType().equals(that.getOuterType())) { + return false; + } + + return nullSafeEquals(this.key, that.key) && nullSafeEquals(this.modifiers, that.modifiers); + } + + private Update getOuterType() { + return Update.this; + } } /** @@ -488,7 +638,5 @@ public class Update { public Update value(Object value) { return Update.this.addToSet(this.key, value); } - } - } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/UpdateTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/UpdateTests.java index 541e0005f..b8454c770 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/UpdateTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/UpdateTests.java @@ -30,6 +30,7 @@ import org.junit.Test; * @author Thomas Risberg * @author Becca Gaspard * @author Christoph Strobl + * @author Thomas Darimont */ public class UpdateTests { @@ -284,4 +285,61 @@ public class UpdateTests { public void testCreatingUpdateWithNullKeyThrowsException() { Update.update(null, "value"); } + + /** + * @see DATAMONGO-953 + */ + @Test + public void testEquality() { + + Update actualUpdate = new Update() // + .inc("size", 1) // + .set("nl", null) // + .set("directory", "/Users/Test/Desktop") // + .push("authors", Collections.singletonMap("name", "Sven")) // + .pop("authors", Update.Position.FIRST) // + .set("foo", "bar"); + + Update expectedUpdate = new Update() // + .inc("size", 1) // + .set("nl", null) // + .set("directory", "/Users/Test/Desktop") // + .push("authors", Collections.singletonMap("name", "Sven")) // + .pop("authors", Update.Position.FIRST) // + .set("foo", "bar"); + + assertThat(actualUpdate, is(equalTo(actualUpdate))); + assertThat(actualUpdate.hashCode(), is(equalTo(actualUpdate.hashCode()))); + assertThat(actualUpdate, is(equalTo(expectedUpdate))); + assertThat(actualUpdate.hashCode(), is(equalTo(expectedUpdate.hashCode()))); + } + + /** + * @see DATAMONGO-953 + */ + @Test + public void testToString() { + + Update actualUpdate = new Update() // + .inc("size", 1) // + .set("nl", null) // + .set("directory", "/Users/Test/Desktop") // + .push("authors", Collections.singletonMap("name", "Sven")) // + .pop("authors", Update.Position.FIRST) // + .set("foo", "bar"); + + Update expectedUpdate = new Update() // + .inc("size", 1) // + .set("nl", null) // + .set("directory", "/Users/Test/Desktop") // + .push("authors", Collections.singletonMap("name", "Sven")) // + .pop("authors", Update.Position.FIRST) // + .set("foo", "bar"); + + assertThat(actualUpdate.toString(), is(equalTo(expectedUpdate.toString()))); + assertThat(actualUpdate.toString(), is("{ \"$inc\" : { \"size\" : 1} ," // + + " \"$set\" : { \"nl\" : null , \"directory\" : \"/Users/Test/Desktop\" , \"foo\" : \"bar\"} , " // + + "\"$push\" : { \"authors\" : { \"name\" : \"Sven\"}} " // + + ", \"$pop\" : { \"authors\" : -1}}")); // + } }