DATAMONGO-1777 - Pretty print Modifiers when calling Update.toString().

We now make sure to pretty print Update modifiers by safely rendering to a json representation including an optional $isolated opereator if applicable.
Along the way we also fix a flaw in PushOperationBuilder ignoring eg. $position when pushing single values.
This commit is contained in:
Christoph Strobl
2017-09-21 09:44:22 +02:00
committed by Oliver Gierke
parent 98e893636b
commit 5bf03cfa70
5 changed files with 82 additions and 11 deletions

View File

@@ -109,7 +109,7 @@ public abstract class SerializationUtils {
* printing raw {@link Document}s containing complex values before actually converting them into Mongo native types.
*
* @param value
* @return
* @return the serialized value or {@literal null}.
*/
@Nullable
public static String serializeToJsonSafely(@Nullable Object value) {
@@ -119,14 +119,15 @@ public abstract class SerializationUtils {
}
try {
return JSON.serialize(value);
return value instanceof Document ? ((Document) value).toJson() : JSON.serialize(value);
} catch (Exception e) {
if (value instanceof Collection) {
return toString((Collection<?>) value);
} else if (value instanceof Map) {
return toString((Map<?, ?>) value);
} else {
return String.format("{ $java : %s }", value.toString());
return String.format("{ \"$java\" : %s }", value.toString());
}
}
}

View File

@@ -485,7 +485,14 @@ public class Update {
*/
@Override
public String toString() {
return SerializationUtils.serializeToJsonSafely(getUpdateObject());
Document doc = getUpdateObject();
if (isIsolated()) {
doc.append("$isolated", 1);
}
return SerializationUtils.serializeToJsonSafely(doc);
}
/**
@@ -510,7 +517,16 @@ public class Update {
this.modifiers.put(modifier.getKey(), modifier);
}
/* (non-Javadoc)
/**
* @return true if no modifiers present.
* @since 2.0
*/
public boolean isEmpty() {
return modifiers.isEmpty();
}
/*
* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
@@ -536,6 +552,11 @@ public class Update {
return this.modifiers.equals(that.modifiers);
}
@Override
public String toString() {
return SerializationUtils.serializeToJsonSafely(this.modifiers);
}
}
/**
@@ -554,6 +575,14 @@ public class Update {
* @return value to be sent with command
*/
Object getValue();
/**
* @return a safely serialized JSON representation.
* @since 2.0
*/
default String toJsonString() {
return SerializationUtils.serializeToJsonSafely(Collections.singletonMap(getKey(), getValue()));
}
}
/**
@@ -627,6 +656,11 @@ public class Update {
return nullSafeEquals(values, ((Each) that).values);
}
@Override
public String toString() {
return toJsonString();
}
}
/**
@@ -652,6 +686,11 @@ public class Update {
public Object getValue() {
return position;
}
@Override
public String toString() {
return toJsonString();
}
}
/**
@@ -685,6 +724,11 @@ public class Update {
public Object getValue() {
return this.count;
}
@Override
public String toString() {
return toJsonString();
}
}
/**
@@ -746,6 +790,11 @@ public class Update {
public Object getValue() {
return this.sort;
}
@Override
public String toString() {
return toJsonString();
}
}
/**
@@ -867,7 +916,13 @@ public class Update {
* @return never {@literal null}.
*/
public Update value(Object value) {
return Update.this.push(key, value);
if (this.modifiers.isEmpty()) {
return Update.this.push(key, value);
}
this.modifiers.addModifier(new Each(Collections.singletonList(value)));
return Update.this.push(key, this.modifiers);
}
/*

View File

@@ -41,7 +41,7 @@ public class SerializationUtilsUnitTests {
public void writesSimpleDocument() {
Document document = new Document("foo", "bar");
assertThat(serializeToJsonSafely(document), is("{ \"foo\" : \"bar\"}"));
assertThat(serializeToJsonSafely(document), is("{ \"foo\" : \"bar\" }"));
}
@Test
@@ -49,7 +49,7 @@ public class SerializationUtilsUnitTests {
Document document = new Document("foo", new Complex());
assertThat(serializeToJsonSafely(document),
startsWith("{ \"foo\" : { $java : org.springframework.data.mongodb.core.SerializationUtilsUnitTests$Complex"));
startsWith("{ \"foo\" : { \"$java\" : org.springframework.data.mongodb.core.SerializationUtilsUnitTests$Complex"));
}
@Test
@@ -58,7 +58,7 @@ public class SerializationUtilsUnitTests {
Document document = new Document("foo", Arrays.asList("bar", new Complex()));
Matcher<String> expectedOutput = allOf(
startsWith(
"{ \"foo\" : [ \"bar\", { $java : org.springframework.data.mongodb.core.SerializationUtilsUnitTests$Complex"),
"{ \"foo\" : [ \"bar\", { \"$java\" : org.springframework.data.mongodb.core.SerializationUtilsUnitTests$Complex"),
endsWith(" } ] }"));
assertThat(serializeToJsonSafely(document), is(expectedOutput));
}

View File

@@ -210,7 +210,7 @@ public class QueryTests {
Query query = new Query(where("name").is("foo")).restrict(SpecialDoc.class);
assertThat(query.toString(), is(
"Query: { \"name\" : \"foo\", \"_$RESTRICTED_TYPES\" : [ { $java : class org.springframework.data.mongodb.core.SpecialDoc } ] }, Fields: { }, Sort: { }"));
"Query: { \"name\" : \"foo\", \"_$RESTRICTED_TYPES\" : [ { \"$java\" : class org.springframework.data.mongodb.core.SpecialDoc } ] }, Fields: { }, Sort: { }"));
assertThat(query.getRestrictedTypes(), is(notNullValue()));
assertThat(query.getRestrictedTypes().size(), is(1));
assertThat(query.getRestrictedTypes(), hasItems(Arrays.asList(SpecialDoc.class).toArray(new Class<?>[0])));
@@ -221,7 +221,7 @@ public class QueryTests {
exception.expect(InvalidMongoDbApiUsageException.class);
exception.expectMessage("second 'value' criteria");
exception.expectMessage("already contains '{ \"value\" : { $java : VAL_1 } }'");
exception.expectMessage("already contains '{ \"value\" : { \"$java\" : VAL_1 } }'");
Query query = new Query();
query.addCriteria(where("value").is(EnumType.VAL_1));

View File

@@ -26,6 +26,7 @@ import org.bson.Document;
import org.joda.time.DateTime;
import org.junit.Test;
import org.springframework.data.mongodb.core.DocumentTestUtils;
import org.springframework.data.mongodb.core.query.Update.Position;
/**
* Test cases for {@link Update}.
@@ -476,4 +477,18 @@ public class UpdateTests {
assertThat(update.getUpdateObject(),
equalTo(new Document("$min", new Document("key", date))));
}
@Test // DATAMONGO-1777
public void toStringShouldPrettyPrintModifiers() {
assertThat(new Update().push("key").atPosition(Position.FIRST).value("Arya").toString(), is(equalTo(
"{ \"$push\" : { \"key\" : { \"$java\" : { \"$position\" : { \"$java\" : { \"$position\" : 0} }, \"$each\" : { \"$java\" : { \"$each\" : [ \"Arya\"]} } } } } }")));
}
@Test // DATAMONGO-1777
public void toStringConsidersIsolated() {
assertThat(new Update().set("key", "value").isolated().toString(),
is(equalTo("{ \"$set\" : { \"key\" : \"value\" }, \"$isolated\" : 1 }")));
}
}