Browse Source

DATAMONGO-953 - Add equals(…)/hashCode()/toString() to Update.

We now use the underlying updateObject to implement appropriate equals(…)/hashCode() and toString() methods.

Original pull request: #192.
pull/194/merge
Thomas Darimont 12 years ago committed by Oliver Gierke
parent
commit
1fb76d135b
  1. 156
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Update.java
  2. 58
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/UpdateTests.java

156
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; package org.springframework.data.mongodb.core.query;
import static org.springframework.util.ObjectUtils.*;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
@ -40,6 +41,7 @@ import com.mongodb.DBObject;
* @author Oliver Gierke * @author Oliver Gierke
* @author Becca Gaspard * @author Becca Gaspard
* @author Christoph Strobl * @author Christoph Strobl
* @author Thomas Darimont
*/ */
public class Update { public class Update {
@ -279,6 +281,7 @@ public class Update {
} }
public DBObject getUpdateObject() { public DBObject getUpdateObject() {
DBObject dbo = new BasicDBObject(); DBObject dbo = new BasicDBObject();
for (String k : modifierOps.keySet()) { for (String k : modifierOps.keySet()) {
dbo.put(k, modifierOps.get(k)); dbo.put(k, modifierOps.get(k));
@ -335,14 +338,52 @@ public class Update {
return StringUtils.startsWithIgnoreCase(key, "$"); 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} * Modifiers holds a distinct collection of {@link Modifier}
* *
* @author Christoph Strobl * @author Christoph Strobl
* @author Thomas Darimont
*/ */
public static class Modifiers { public static class Modifiers {
private HashMap<String, Modifier> modifiers; private Map<String, Modifier> modifiers;
public Modifiers() { public Modifiers() {
this.modifiers = new LinkedHashMap<String, Modifier>(1); this.modifiers = new LinkedHashMap<String, Modifier>(1);
@ -355,6 +396,33 @@ public class Update {
public void addModifier(Modifier modifier) { public void addModifier(Modifier modifier) {
this.modifiers.put(modifier.getKey(), 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}. * Implementation of {@link Modifier} representing {@code $each}.
* *
* @author Christoph Strobl * @author Christoph Strobl
* @author Thomas Darimont
*/ */
private static class Each implements Modifier { private static class Each implements Modifier {
@ -399,6 +468,7 @@ public class Update {
} }
Object[] convertedValues = new Object[values.length]; Object[] convertedValues = new Object[values.length];
for (int i = 0; i < values.length; i++) { for (int i = 0; i < values.length; i++) {
convertedValues[i] = values[i]; convertedValues[i] = values[i];
} }
@ -406,21 +476,57 @@ public class Update {
return convertedValues; return convertedValues;
} }
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.query.Update.Modifier#getKey()
*/
@Override @Override
public String getKey() { public String getKey() {
return "$each"; return "$each";
} }
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.query.Update.Modifier#getValue()
*/
@Override @Override
public Object getValue() { public Object getValue() {
return this.values; 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 * Builder for creating {@code $push} modifiers
* *
* @author Christoph Strobl * @author Christoph Strobl
* @author Thomas Darimont
*/ */
public class PushOperatorBuilder { public class PushOperatorBuilder {
@ -453,6 +559,50 @@ public class Update {
public Update value(Object value) { public Update value(Object value) {
return Update.this.push(key, 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) { public Update value(Object value) {
return Update.this.addToSet(this.key, value); return Update.this.addToSet(this.key, value);
} }
} }
} }

58
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 Thomas Risberg
* @author Becca Gaspard * @author Becca Gaspard
* @author Christoph Strobl * @author Christoph Strobl
* @author Thomas Darimont
*/ */
public class UpdateTests { public class UpdateTests {
@ -284,4 +285,61 @@ public class UpdateTests {
public void testCreatingUpdateWithNullKeyThrowsException() { public void testCreatingUpdateWithNullKeyThrowsException() {
Update.update(null, "value"); 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}}")); //
}
} }

Loading…
Cancel
Save