diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperation.java index 9d0958fbc..95648b67b 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperation.java @@ -28,13 +28,14 @@ import com.mongodb.BasicDBObject; import com.mongodb.DBObject; /** - * Encapsulates the aggregation framework {@code $replaceRoot}-operation. - *
+ * Encapsulates the aggregation framework {@code $replaceRoot}-operation.
* We recommend to use the static factory method {@link Aggregation#replaceRoot(String)} instead of creating instances
* of this class directly.
- *
- * @see https://docs.mongodb.com/manual/reference/operator/aggregation/replaceRoot/#pipe._S_replaceRoot
+ *
+ * @see https://docs.mongodb.com/manual/reference/operator/aggregation/replaceRoot/
* @author Mark Paluch
+ * @author Christoph Strobl
* @since 1.10
*/
public class ReplaceRootOperation implements FieldsExposingAggregationOperation {
@@ -42,32 +43,37 @@ public class ReplaceRootOperation implements FieldsExposingAggregationOperation
private final Replacement replacement;
/**
- * Creates a new {@link ReplaceRootOperation} given the {@link as} field name.
+ * Creates a new {@link ReplaceRootOperation} given the {@link Field} field name.
*
* @param field must not be {@literal null} or empty.
*/
public ReplaceRootOperation(Field field) {
- this.replacement = new FieldReplacement(field);
+ this(new FieldReplacement(field));
}
/**
- * Creates a new {@link ReplaceRootOperation} given the {@link as} field name.
+ * Creates a new {@link ReplaceRootOperation} given the {@link AggregationExpression} pointing to a document.
*
* @param aggregationExpression must not be {@literal null}.
*/
public ReplaceRootOperation(AggregationExpression aggregationExpression) {
-
- Assert.notNull(aggregationExpression, "AggregationExpression must not be null!");
- this.replacement = new AggregationExpressionReplacement(aggregationExpression);
+ this(new AggregationExpressionReplacement(aggregationExpression));
}
- protected ReplaceRootOperation(Replacement replacement) {
+ /**
+ * Creates a new {@link ReplaceRootOperation} given the {@link Replacement}.
+ *
+ * @param replacement must not be {@literal null}.
+ */
+ public ReplaceRootOperation(Replacement replacement) {
+
+ Assert.notNull(replacement, "Replacement must not be null!");
this.replacement = replacement;
}
/**
* Creates a new {@link ReplaceRootDocumentOperationBuilder}.
- *
+ *
* @return a new {@link ReplaceRootDocumentOperationBuilder}.
*/
public static ReplaceRootOperationBuilder builder() {
@@ -79,7 +85,7 @@ public class ReplaceRootOperation implements FieldsExposingAggregationOperation
*/
@Override
public DBObject toDBObject(AggregationOperationContext context) {
- return new BasicDBObject("$replaceRoot", new BasicDBObject("newRoot", replacement.toObject(context)));
+ return new BasicDBObject("$replaceRoot", new BasicDBObject("newRoot", replacement.toDocumentExpression(context)));
}
/* (non-Javadoc)
@@ -99,7 +105,7 @@ public class ReplaceRootOperation implements FieldsExposingAggregationOperation
/**
* Defines a root document replacement based on a {@literal fieldName} that resolves to a document.
- *
+ *
* @param fieldName must not be {@literal null} or empty.
* @return the final {@link ReplaceRootOperation}.
*/
@@ -118,8 +124,7 @@ public class ReplaceRootOperation implements FieldsExposingAggregationOperation
}
/**
- * Defines a root document replacement based on a composable document that is empty initially.
- *
+ * Defines a root document replacement based on a composable document that is empty initially.
* {@link ReplaceRootOperation} can be populated with individual entries and derive its values from other, existing
* documents.
*
@@ -130,8 +135,7 @@ public class ReplaceRootOperation implements FieldsExposingAggregationOperation
}
/**
- * Defines a root document replacement based on a composable document given {@literal dbObject}
- *
+ * Defines a root document replacement based on a composable document given {@literal dbObject}.
* {@link ReplaceRootOperation} can be populated with individual entries and derive its values from other, existing
* documents.
*
@@ -148,8 +152,7 @@ public class ReplaceRootOperation implements FieldsExposingAggregationOperation
/**
* Encapsulates the aggregation framework {@code $replaceRoot}-operation to result in a composable replacement
- * document.
- *
+ * document.
+ * {@link ReplacementContributor} to contribute multiple fields based on the input {@literal value}.
* Instances of {@link ReplaceRootDocumentOperation} yield empty upon construction and can be populated with single
* values and documents.
*
@@ -175,7 +178,7 @@ public class ReplaceRootOperation implements FieldsExposingAggregationOperation
/**
* Creates an extended {@link ReplaceRootDocumentOperation} that combines {@link ReplacementDocument}s from the
* {@literal currentOperation} and {@literal extension} operation.
- *
+ *
* @param currentOperation must not be {@literal null}.
* @param extension must not be {@literal null}.
*/
@@ -185,9 +188,9 @@ public class ReplaceRootOperation implements FieldsExposingAggregationOperation
}
/**
- * Creates a new {@link ReplaceRootDocumentOperationBuilder} to define a field for the {@link AggregationExpression}
- * .
- *
+ * Creates a new {@link ReplaceRootDocumentOperationBuilder} to define a field for the
+ * {@link AggregationExpression}.
+ *
* @param aggregationExpression must not be {@literal null}.
* @return the {@link ReplaceRootDocumentOperationBuilder}.
*/
@@ -251,17 +254,18 @@ public class ReplaceRootOperation implements FieldsExposingAggregationOperation
* Replacement object that results in a replacement document or an expression that results in a document.
*
* @author Mark Paluch
+ * @author Christoph Strobl
*/
- private abstract static class Replacement {
+ public interface Replacement {
/**
- * Renders the current {@link Replacement} into a {@link DBObject} based on the given
+ * Renders the current {@link Replacement} into a its MongoDB representation based on the given
* {@link AggregationOperationContext}.
*
* @param context will never be {@literal null}.
* @return a replacement document or an expression that results in a document.
*/
- public abstract Object toObject(AggregationOperationContext context);
+ Object toDocumentExpression(AggregationOperationContext context);
}
/**
@@ -269,11 +273,13 @@ public class ReplaceRootOperation implements FieldsExposingAggregationOperation
*
* @author Mark Paluch
*/
- private static class AggregationExpressionReplacement extends Replacement {
+ private static class AggregationExpressionReplacement implements Replacement {
private final AggregationExpression aggregationExpression;
protected AggregationExpressionReplacement(AggregationExpression aggregationExpression) {
+
+ Assert.notNull(aggregationExpression, "AggregationExpression must not be null!");
this.aggregationExpression = aggregationExpression;
}
@@ -281,17 +287,17 @@ public class ReplaceRootOperation implements FieldsExposingAggregationOperation
* @see org.springframework.data.mongodb.core.aggregation.ReplaceRootOperation.Replacement#toObject(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
*/
@Override
- public DBObject toObject(AggregationOperationContext context) {
+ public DBObject toDocumentExpression(AggregationOperationContext context) {
return aggregationExpression.toDbObject(context);
}
}
/**
* {@link Replacement that references a {@link Field} inside the current aggregation pipeline.
- *
+ *
* @author Mark Paluch
*/
- private static class FieldReplacement extends Replacement {
+ private static class FieldReplacement implements Replacement {
private final Field field;
@@ -308,7 +314,7 @@ public class ReplaceRootOperation implements FieldsExposingAggregationOperation
* @see org.springframework.data.mongodb.core.aggregation.ReplaceRootOperation.Replacement#toObject(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
*/
@Override
- public Object toObject(AggregationOperationContext context) {
+ public Object toDocumentExpression(AggregationOperationContext context) {
return context.getReference(field).toString();
}
}
@@ -318,7 +324,7 @@ public class ReplaceRootOperation implements FieldsExposingAggregationOperation
*
* @author Mark Paluch
*/
- private static class ReplacementDocument extends Replacement {
+ private static class ReplacementDocument implements Replacement {
private final Collection
* The value object is mapped into a MongoDB {@link DBObject}.
- *
+ *
* @author Mark Paluch
+ * @author Christoph Strobl
*/
- private static class DocumentContributor extends ReplacementContributor {
+ private static class DocumentContributor implements ReplacementContributor {
private final Object value;
@@ -455,11 +461,13 @@ public class ReplaceRootOperation implements FieldsExposingAggregationOperation
* @see org.springframework.data.mongodb.core.aggregation.ReplaceRootOperation.ReplacementContributor#toDBObject(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
*/
@Override
- public DBObject toDBObject(AggregationOperationContext context) {
+ public DBObject toDbObject(AggregationOperationContext context) {
- DBObject dbObject = new BasicDBObject("$set", value);
+ if (value instanceof DBObject) {
+ return (DBObject) value;
+ }
- return (DBObject) context.getMappedObject(dbObject).get("$set");
+ return (DBObject) context.getMappedObject(new BasicDBObject("$set", value)).get("$set");
}
}
@@ -469,7 +477,7 @@ public class ReplaceRootOperation implements FieldsExposingAggregationOperation
*
* @author Mark Paluch
*/
- private abstract static class FieldContributorSupport extends ReplacementContributor {
+ private abstract static class FieldContributorSupport implements ReplacementContributor {
private final ExposedField field;
@@ -521,10 +529,12 @@ public class ReplaceRootOperation implements FieldsExposingAggregationOperation
* @see org.springframework.data.mongodb.core.aggregation.ReplaceRootOperation.ReplacementContributor#toDBObject(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
*/
@Override
- public DBObject toDBObject(AggregationOperationContext context) {
+ public DBObject toDbObject(AggregationOperationContext context) {
- DBObject dbObject = new BasicDBObject("$set", value);
- return new BasicDBObject(getField().getTarget(), context.getMappedObject(dbObject).get("$set"));
+ Object mappedValue = value instanceof BasicDBObject ? value
+ : context.getMappedObject(new BasicDBObject("$set", value)).get("$set");
+
+ return new BasicDBObject(getField().getTarget(), mappedValue);
}
}
@@ -557,7 +567,7 @@ public class ReplaceRootOperation implements FieldsExposingAggregationOperation
* @see org.springframework.data.mongodb.core.aggregation.ReplaceRootOperation.ReplacementContributor#toDBObject(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
*/
@Override
- public DBObject toDBObject(AggregationOperationContext context) {
+ public DBObject toDbObject(AggregationOperationContext context) {
return new BasicDBObject(getField().getTarget(), aggregationExpression.toDbObject(context));
}
}
diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperationUnitTests.java
index 375372040..5a6830336 100644
--- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperationUnitTests.java
+++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperationUnitTests.java
@@ -28,7 +28,7 @@ import com.mongodb.util.JSON;
/**
* Unit tests for {@link ReplaceRootOperation}.
- *
+ *
* @author Mark Paluch
*/
public class ReplaceRootOperationUnitTests {