From 794756d055096c8020c0d23aca136bd9cfe5da53 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Mon, 12 Dec 2016 11:55:51 +0100 Subject: [PATCH] DATAMONGO-1548 - Polishing. Enhance JavaDoc. Minor formatting. Fix typos. Original pull request: #423. --- .../aggregation/AggregationExpressions.java | 406 ++++++++++++++++-- .../ProjectionOperationUnitTests.java | 40 +- 2 files changed, 372 insertions(+), 74 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationExpressions.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationExpressions.java index 07150b8b2..327aed87f 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationExpressions.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationExpressions.java @@ -25,6 +25,7 @@ import java.util.List; import org.bson.Document; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.domain.Range; +import org.springframework.data.mongodb.core.aggregation.AggregationExpressions.ArithmeticOperators.ArithmeticOperatorFactory; import org.springframework.data.mongodb.core.aggregation.AggregationExpressions.Cond.OtherwiseBuilder; import org.springframework.data.mongodb.core.aggregation.AggregationExpressions.Cond.ThenBuilder; import org.springframework.data.mongodb.core.aggregation.AggregationExpressions.Filter.AsBuilder; @@ -32,7 +33,6 @@ import org.springframework.data.mongodb.core.aggregation.AggregationExpressions. import org.springframework.data.mongodb.core.aggregation.AggregationExpressions.Reduce.PropertyExpression; import org.springframework.data.mongodb.core.aggregation.AggregationExpressions.Switch.CaseOperator; import org.springframework.data.mongodb.core.aggregation.ExposedFields.ExposedField; -import org.springframework.data.mongodb.core.aggregation.ExposedFields.FieldReference; import org.springframework.data.mongodb.core.query.CriteriaDefinition; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -266,8 +266,8 @@ public interface AggregationExpressions { /** * Creates new {@link AggregationExpression} that evaluates a series of {@link CaseOperator} expressions. When it - * finds an expression which evaluates to true, {@code $switch} executes a specified expression and breaks out of - * the control flow. + * finds an expression which evaluates to {@literal true}, {@code $switch} executes a specified expression and + * breaks out of the control flow. * * @param conditions must not be {@literal null}. * @return @@ -278,8 +278,8 @@ public interface AggregationExpressions { /** * Creates new {@link AggregationExpression} that evaluates a series of {@link CaseOperator} expressions. When it - * finds an expression which evaluates to true, {@code $switch} executes a specified expression and breaks out of - * the control flow. + * finds an expression which evaluates to {@literal true}, {@code $switch} executes a specified expression and + * breaks out of the control flow. * * @param conditions must not be {@literal null}. * @return @@ -1593,8 +1593,8 @@ public interface AggregationExpressions { /** * Creates new {@link AggregationExpressions} that takes the associated string representation and searches a - * string for an occurence of a given {@literal substring} and returns the UTF-8 byte index (zero-based) of the - * first occurence. + * string for an occurrence of a given {@literal substring} and returns the UTF-8 byte index (zero-based) of the + * first occurrence. * * @param substring must not be {@literal null}. * @return @@ -1607,8 +1607,8 @@ public interface AggregationExpressions { /** * Creates new {@link AggregationExpressions} that takes the associated string representation and searches a - * string for an occurence of a substring contained in the given {@literal field reference} and returns the UTF-8 - * byte index (zero-based) of the first occurence. + * string for an occurrence of a substring contained in the given {@literal field reference} and returns the UTF-8 + * byte index (zero-based) of the first occurrence. * * @param fieldReference must not be {@literal null}. * @return @@ -1621,8 +1621,8 @@ public interface AggregationExpressions { /** * Creates new {@link AggregationExpressions} that takes the associated string representation and searches a - * string for an occurence of a substring resulting from the given {@link AggregationExpression} and returns the - * UTF-8 byte index (zero-based) of the first occurence. + * string for an occurrence of a substring resulting from the given {@link AggregationExpression} and returns the + * UTF-8 byte index (zero-based) of the first occurrence. * * @param expression must not be {@literal null}. * @return @@ -1639,8 +1639,8 @@ public interface AggregationExpressions { /** * Creates new {@link AggregationExpressions} that takes the associated string representation and searches a - * string for an occurence of a given {@literal substring} and returns the UTF-8 code point index (zero-based) of - * the first occurence. + * string for an occurrence of a given {@literal substring} and returns the UTF-8 code point index (zero-based) of + * the first occurrence. * * @param substring must not be {@literal null}. * @return @@ -1653,8 +1653,8 @@ public interface AggregationExpressions { /** * Creates new {@link AggregationExpressions} that takes the associated string representation and searches a - * string for an occurence of a substring contained in the given {@literal field reference} and returns the UTF-8 - * code point index (zero-based) of the first occurence. + * string for an occurrence of a substring contained in the given {@literal field reference} and returns the UTF-8 + * code point index (zero-based) of the first occurrence. * * @param fieldReference must not be {@literal null}. * @return @@ -1667,8 +1667,8 @@ public interface AggregationExpressions { /** * Creates new {@link AggregationExpressions} that takes the associated string representation and searches a - * string for an occurence of a substring resulting from the given {@link AggregationExpression} and returns the - * UTF-8 code point index (zero-based) of the first occurence. + * string for an occurrence of a substring resulting from the given {@link AggregationExpression} and returns the + * UTF-8 code point index (zero-based) of the first occurrence. * * @param expression must not be {@literal null}. * @return @@ -1936,8 +1936,8 @@ public interface AggregationExpressions { } /** - * Creates new {@link AggregationExpressions} that searches the associated array for an occurence of a specified - * value and returns the array index (zero-based) of the first occurence. + * Creates new {@link AggregationExpressions} that searches the associated array for an occurrence of a specified + * value and returns the array index (zero-based) of the first occurrence. * * @param value must not be {@literal null}. * @return @@ -1965,6 +1965,7 @@ public interface AggregationExpressions { */ public ReduceInitialValueBuilder reduce(final AggregationExpression expression) { return new ReduceInitialValueBuilder() { + @Override public Reduce startingWith(Object initialValue) { return (usesFieldRef() ? Reduce.arrayOf(fieldReference) : Reduce.arrayOf(expression)) @@ -1983,6 +1984,7 @@ public interface AggregationExpressions { public ReduceInitialValueBuilder reduce(final PropertyExpression... expressions) { return new ReduceInitialValueBuilder() { + @Override public Reduce startingWith(Object initialValue) { return (usesFieldRef() ? Reduce.arrayOf(fieldReference) : Reduce.arrayOf(expression)) @@ -1994,7 +1996,7 @@ public interface AggregationExpressions { /** * Creates new {@link AggregationExpressions} that transposes an array of input arrays so that the first element * of the output array would be an array containing, the first element of the first input array, the first element - * of the second input array, etc + * of the second input array, etc. * * @param arrays must not be {@literal null}. * @return @@ -2005,7 +2007,7 @@ public interface AggregationExpressions { /** * Creates new {@link AggregationExpressions} that returns a boolean indicating whether a specified value is in - * the associcated array. + * the associated array. * * @param value must not be {@literal null}. * @return @@ -2014,7 +2016,17 @@ public interface AggregationExpressions { return (usesFieldRef() ? In.arrayOf(fieldReference) : In.arrayOf(expression)).containsValue(value); } + /** + * @author Christoph Strobl + */ public interface ReduceInitialValueBuilder { + + /** + * Define the initial cumulative value set before in is applied to the first element of the input array. + * + * @param initialValue must not be {@literal null}. + * @return + */ Reduce startingWith(Object initialValue); } @@ -2338,6 +2350,9 @@ public interface AggregationExpressions { this.value = value; } + /* (non-Javadoc) + * @see org.springframework.data.mongodb.core.aggregation.AggregationExpression#toDocument(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext) + */ @Override public Document toDocument(AggregationOperationContext context) { return toDocument(this.value, context); @@ -4145,14 +4160,32 @@ public interface AggregationExpressions { this.stringExpression = stringExpression; } + /** + * Creates a new {@link IndexOfBytes} given {@literal substring}. + * + * @param substring must not be {@literal null}. + * @return + */ public IndexOfBytes indexOf(String substring) { return new IndexOfBytes(Arrays.asList(stringExpression, substring)); } + /** + * Creates a new {@link IndexOfBytes} given {@link AggregationExpression} that resolves to the substring. + * + * @param expression must not be {@literal null}. + * @return + */ public IndexOfBytes indexOf(AggregationExpression expression) { return new IndexOfBytes(Arrays.asList(stringExpression, expression)); } + /** + * Creates a new {@link IndexOfBytes} given {@link Field} that resolves to the substring. + * + * @param fieldReference must not be {@literal null}. + * @return + */ public IndexOfBytes indexOf(Field fieldReference) { return new IndexOfBytes(Arrays.asList(stringExpression, fieldReference)); } @@ -4226,14 +4259,32 @@ public interface AggregationExpressions { this.stringExpression = stringExpression; } + /** + * Creates a new {@link IndexOfCP} given {@literal substring}. + * + * @param substring must not be {@literal null}. + * @return + */ public IndexOfCP indexOf(String substring) { return new IndexOfCP(Arrays.asList(stringExpression, substring)); } + /** + * Creates a new {@link IndexOfCP} given {@link AggregationExpression} that resolves to the substring. + * + * @param expression must not be {@literal null}. + * @return + */ public IndexOfCP indexOf(AggregationExpression expression) { return new IndexOfCP(Arrays.asList(stringExpression, expression)); } + /** + * Creates a new {@link IndexOfCP} given {@link Field} that resolves to the substring. + * + * @param fieldReference must not be {@literal null}. + * @return + */ public IndexOfCP indexOf(Field fieldReference) { return new IndexOfCP(Arrays.asList(stringExpression, fieldReference)); } @@ -4242,6 +4293,8 @@ public interface AggregationExpressions { /** * {@link AggregationExpression} for {@code $split}. + * + * @author Christoph Strobl */ class Split extends AbstractAggregationExpression { @@ -4279,19 +4332,19 @@ public interface AggregationExpressions { } /** - * Use given {@link String} as deliminator + * Use given {@link String} as delimiter. * - * @param deliminator must not be {@literal null}. + * @param delimiter must not be {@literal null}. * @return */ - public Split split(String deliminator) { + public Split split(String delimiter) { - Assert.notNull(deliminator, "Deliminator must not be null!"); - return new Split(append(deliminator)); + Assert.notNull(delimiter, "Delimiter must not be null!"); + return new Split(append(delimiter)); } /** - * Usge value of referenced field as deliminator. + * Use value of referenced field as delimiter. * * @param fieldReference must not be {@literal null}. * @return @@ -4303,7 +4356,7 @@ public interface AggregationExpressions { } /** - * Use value resulting from {@link AggregationExpression} as deliminator. + * Use value resulting from {@link AggregationExpression} as delimiter. * * @param expression must not be {@literal null}. * @return @@ -4317,6 +4370,8 @@ public interface AggregationExpressions { /** * {@link AggregationExpression} for {@code $strLenBytes}. + * + * @author Christoph Strobl */ class StrLenBytes extends AbstractAggregationExpression { @@ -4329,17 +4384,33 @@ public interface AggregationExpressions { return "$strLenBytes"; } + /** + * Creates new {@link StrLenBytes}. + * + * @param fieldReference must not be {@literal null}. + * @return + */ public static StrLenBytes stringLengthOf(String fieldReference) { return new StrLenBytes(Fields.field(fieldReference)); } + /** + * Creates new {@link StrLenBytes}. + * + * @param expression must not be {@literal null}. + * @return + */ public static StrLenBytes stringLengthOf(AggregationExpression expression) { + + Assert.notNull(expression, "Expression must not be null!"); return new StrLenBytes(expression); } } /** * {@link AggregationExpression} for {@code $strLenCP}. + * + * @author Christoph Strobl */ class StrLenCP extends AbstractAggregationExpression { @@ -4352,11 +4423,25 @@ public interface AggregationExpressions { return "$strLenCP"; } + /** + * Creates new {@link StrLenCP}. + * + * @param fieldReference must not be {@literal null}. + * @return + */ public static StrLenCP stringLengthOfCP(String fieldReference) { return new StrLenCP(Fields.field(fieldReference)); } + /** + * Creates new {@link StrLenCP}. + * + * @param expression must not be {@literal null}. + * @return + */ public static StrLenCP stringLengthOfCP(AggregationExpression expression) { + + Assert.notNull(expression, "Expression must not be null!"); return new StrLenCP(expression); } } @@ -4907,7 +4992,17 @@ public interface AggregationExpressions { }; } + /** + * @author Christoph Strobl + */ public interface SliceElementsBuilder { + + /** + * Set the number of elements given {@literal nrElements}. + * + * @param nrElements + * @return + */ Slice itemCount(int nrElements); } } @@ -4965,6 +5060,9 @@ public interface AggregationExpressions { return new IndexOfArray(append(rangeValues)); } + /** + * @author Christoph Strobl + */ public static class IndexOfArrayBuilder { private final Object targetArray; @@ -4973,6 +5071,12 @@ public interface AggregationExpressions { this.targetArray = targetArray; } + /** + * Set the {@literal value} to check for its index in the array. + * + * @param value must not be {@literal null}. + * @return + */ public IndexOfArray indexOf(Object value) { Assert.notNull(value, "Value must not be null!"); @@ -4997,19 +5101,37 @@ public interface AggregationExpressions { return "$range"; } + /** + * Start creating new {@link RangeOperator}. + * + * @param fieldReference must not be {@literal null}. + * @return + */ public static RangeOperatorBuilder rangeStartingAt(String fieldReference) { return new RangeOperatorBuilder(Fields.field(fieldReference)); } + /** + * Start creating new {@link RangeOperator}. + * + * @param expression must not be {@literal null}. + * @return + */ public static RangeOperatorBuilder rangeStartingAt(AggregationExpression expression) { return new RangeOperatorBuilder(expression); } - public static RangeOperatorBuilder rangeStartingAt(Long value) { + /** + * Start creating new {@link RangeOperator}. + * + * @param value + * @return + */ + public static RangeOperatorBuilder rangeStartingAt(long value) { return new RangeOperatorBuilder(value); } - public RangeOperator withStepSize(Long stepSize) { + public RangeOperator withStepSize(long stepSize) { return new RangeOperator(append(stepSize)); } @@ -5021,23 +5143,42 @@ public interface AggregationExpressions { this.startPoint = startPoint; } - public RangeOperator to(Long index) { + /** + * Creates new {@link RangeOperator}. + * + * @param index + * @return + */ + public RangeOperator to(long index) { return new RangeOperator(Arrays.asList(startPoint, index)); } + /** + * Creates new {@link RangeOperator}. + * + * @param expression must not be {@literal null}. + * @return + */ public RangeOperator to(AggregationExpression expression) { return new RangeOperator(Arrays.asList(startPoint, expression)); } + /** + * Creates new {@link RangeOperator}. + * + * @param fieldReference must not be {@literal null}. + * @return + */ public RangeOperator to(String fieldReference) { return new RangeOperator(Arrays.asList(startPoint, Fields.field(fieldReference))); } } - } /** * {@link AggregationExpression} for {@code $reverseArray}. + * + * @author Christoph Strobl */ class ReverseArray extends AbstractAggregationExpression { @@ -5050,10 +5191,22 @@ public interface AggregationExpressions { return "$reverseArray"; } + /** + * Creates new {@link ReverseArray} given {@literal fieldReference}. + * + * @param fieldReference must not be {@literal null}. + * @return + */ public static ReverseArray reverseArrayOf(String fieldReference) { return new ReverseArray(Fields.field(fieldReference)); } + /** + * Creates new {@link ReverseArray} given {@link AggregationExpression}. + * + * @param expression must not be {@literal null}. + * @return + */ public static ReverseArray reverseArrayOf(AggregationExpression expression) { return new ReverseArray(expression); } @@ -5061,6 +5214,8 @@ public interface AggregationExpressions { /** * {@link AggregationExpression} for {@code $reduce}. + * + * @author Christoph Strobl */ class Reduce implements AggregationExpression { @@ -5069,11 +5224,15 @@ public interface AggregationExpressions { private final List reduceExpressions; private Reduce(Object input, Object initialValue, List reduceExpressions) { + this.input = input; this.initialValue = initialValue; this.reduceExpressions = reduceExpressions; } + /* (non-Javadoc) + * @see org.springframework.data.mongodb.core.aggregation.AggregationExpression#toDocument(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext) + */ @Override public Document toDocument(AggregationOperationContext context) { @@ -5110,19 +5269,37 @@ public interface AggregationExpressions { } } + /** + * Start creating new {@link Reduce}. + * + * @param fieldReference must not be {@literal null}. + * @return + */ public static InitialValueBuilder arrayOf(final String fieldReference) { + + Assert.notNull(fieldReference, "FieldReference must not be null"); + return new InitialValueBuilder() { @Override public ReduceBuilder withInitialValue(final Object initialValue) { + + Assert.notNull(initialValue, "Initial value must not be null"); + return new ReduceBuilder() { + @Override public Reduce reduce(AggregationExpression expression) { + + Assert.notNull(expression, "AggregationExpression must not be null"); return new Reduce(Fields.field(fieldReference), initialValue, Collections.singletonList(expression)); } @Override public Reduce reduce(PropertyExpression... expressions) { + + Assert.notNull(expressions, "PropertyExpressions must not be null"); + return new Reduce(Fields.field(fieldReference), initialValue, Arrays. asList(expressions)); } @@ -5131,19 +5308,36 @@ public interface AggregationExpressions { }; } + /** + * Start creating new {@link Reduce}. + * + * @param expression must not be {@literal null}. + * @return + */ public static InitialValueBuilder arrayOf(final AggregationExpression expression) { + + Assert.notNull(expression, "AggregationExpression must not be null"); + return new InitialValueBuilder() { @Override public ReduceBuilder withInitialValue(final Object initialValue) { + + Assert.notNull(initialValue, "Initial value must not be null"); + return new ReduceBuilder() { + @Override public Reduce reduce(AggregationExpression expression) { + + Assert.notNull(expression, "AggregationExpression must not be null"); return new Reduce(expression, initialValue, Collections.singletonList(expression)); } @Override public Reduce reduce(PropertyExpression... expressions) { + + Assert.notNull(expressions, "PropertyExpressions must not be null"); return new Reduce(expression, initialValue, Arrays. asList(expressions)); } }; @@ -5151,24 +5345,30 @@ public interface AggregationExpressions { }; } + /** + * @author Christoph Strobl + */ public interface InitialValueBuilder { /** * Define the initial cumulative value set before in is applied to the first element of the input array. * - * @param intialValue must not be {@literal null}. + * @param initialValue must not be {@literal null}. * @return */ - ReduceBuilder withInitialValue(Object intialValue); + ReduceBuilder withInitialValue(Object initialValue); } + /** + * @author Christoph Strobl + */ public interface ReduceBuilder { /** * Define the {@link AggregationExpression} to apply to each element in the input array in left-to-right order. *
- * NOTE: During evaulation of the in expression the variable references {@link Variable#THIS} and - * {@link Variable#VALUE} are availble. + * NOTE: During evaluation of the in expression the variable references {@link Variable#THIS} and + * {@link Variable#VALUE} are available. * * @param expression must not be {@literal null}. * @return @@ -5178,8 +5378,8 @@ public interface AggregationExpressions { /** * Define the {@link PropertyExpression}s to apply to each element in the input array in left-to-right order. *
- * NOTE: During evaulation of the in expression the variable references {@link Variable#THIS} and - * {@link Variable#VALUE} are availble. + * NOTE: During evaluation of the in expression the variable references {@link Variable#THIS} and + * {@link Variable#VALUE} are available. * * @param expression must not be {@literal null}. * @return @@ -5195,7 +5395,11 @@ public interface AggregationExpressions { private final String propertyName; private final AggregationExpression aggregationExpression; - public PropertyExpression(String propertyName, AggregationExpression aggregationExpression) { + protected PropertyExpression(String propertyName, AggregationExpression aggregationExpression) { + + Assert.notNull(propertyName, "Property name must not be null!"); + Assert.notNull(aggregationExpression, "AggregationExpression must not be null!"); + this.propertyName = propertyName; this.aggregationExpression = aggregationExpression; } @@ -5207,7 +5411,9 @@ public interface AggregationExpressions { * @return */ public static AsBuilder property(final String name) { + return new AsBuilder() { + @Override public PropertyExpression definedAs(AggregationExpression expression) { return new PropertyExpression(name, expression); @@ -5215,11 +5421,17 @@ public interface AggregationExpressions { }; } + /* (non-Javadoc) + * @see org.springframework.data.mongodb.core.aggregation.AggregationExpression#toDocument(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext) + */ @Override public Document toDocument(AggregationOperationContext context) { return new Document(propertyName, aggregationExpression.toDocument(context)); } + /** + * @author Christoph Strobl + */ interface AsBuilder { /** @@ -5233,6 +5445,7 @@ public interface AggregationExpressions { } public enum Variable implements Field { + THIS { @Override public String getName() { @@ -5254,6 +5467,7 @@ public interface AggregationExpressions { return getName(); } }, + VALUE { @Override public String getName() { @@ -5283,7 +5497,7 @@ public interface AggregationExpressions { * @param property must not be {@literal null}. * @return */ - public Field referingTo(final String property) { + public Field referringTo(final String property) { return new Field() { @Override @@ -5312,6 +5526,8 @@ public interface AggregationExpressions { /** * {@link AggregationExpression} for {@code $zip}. + * + * @author Christoph Strobl */ class Zip extends AbstractAggregationExpression { @@ -5397,7 +5613,7 @@ public interface AggregationExpressions { private final List sourceArrays; - public ZipBuilder(Object sourceArray) { + private ZipBuilder(Object sourceArray) { this.sourceArrays = new ArrayList(); this.sourceArrays.add(sourceArray); @@ -5406,7 +5622,7 @@ public interface AggregationExpressions { /** * Creates new {@link Zip} that transposes an array of input arrays so that the first element of the output array * would be an array containing, the first element of the first input array, the first element of the second input - * array, etc + * array, etc. * * @param arrays arrays to zip the referenced one with. must not be {@literal null}. * @return @@ -5430,6 +5646,8 @@ public interface AggregationExpressions { /** * {@link AggregationExpression} for {@code $in}. + * + * @author Christoph Strobl */ class In extends AbstractAggregationExpression { @@ -5442,10 +5660,18 @@ public interface AggregationExpressions { return "$in"; } + /** + * Start creating {@link In}. + * + * @param fieldReference must not be {@literal null}. + * @return + */ public static InBuilder arrayOf(final String fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null!"); + return new InBuilder() { + @Override public In containsValue(Object value) { @@ -5455,10 +5681,18 @@ public interface AggregationExpressions { }; } + /** + * Start creating {@link In}. + * + * @param expression must not be {@literal null}. + * @return + */ public static InBuilder arrayOf(final AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null!"); + return new InBuilder() { + @Override public In containsValue(Object value) { @@ -5468,10 +5702,19 @@ public interface AggregationExpressions { }; } + /** + * @author Christoph Strobl + */ public interface InBuilder { + + /** + * Set the {@literal value} to check for existence in the array. + * + * @param value must not be {@literal value}. + * @return + */ In containsValue(Object value); } - } // ############ @@ -5942,7 +6185,9 @@ public interface AggregationExpressions { public static FormatBuilder dateOf(final String fieldReference) { Assert.notNull(fieldReference, "FieldReference must not be null!"); + return new FormatBuilder() { + @Override public DateToString toString(String format) { @@ -5961,12 +6206,13 @@ public interface AggregationExpressions { public static FormatBuilder dateOf(final AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null!"); + return new FormatBuilder() { + @Override public DateToString toString(String format) { Assert.notNull(format, "Format must not be null!"); - return new DateToString(argumentMap(expression, format)); } }; @@ -6181,6 +6427,9 @@ public interface AggregationExpressions { return new Sum(append(expression)); } + /* (non-Javadoc) + * @see org.springframework.data.mongodb.core.aggregation.AggregationExpressions.AbstractAggregationExpression#toDocument(java.lang.Object, org.springframework.data.mongodb.core.aggregation.AggregationOperationContext) + */ @Override public Document toDocument(Object value, AggregationOperationContext context) { @@ -6260,6 +6509,9 @@ public interface AggregationExpressions { return new Avg(append(expression)); } + /* (non-Javadoc) + * @see org.springframework.data.mongodb.core.aggregation.AggregationExpressions.AbstractAggregationExpression#toDocument(java.lang.Object, org.springframework.data.mongodb.core.aggregation.AggregationOperationContext) + */ @Override public Document toDocument(Object value, AggregationOperationContext context) { @@ -6339,6 +6591,9 @@ public interface AggregationExpressions { return new Max(append(expression)); } + /* (non-Javadoc) + * @see org.springframework.data.mongodb.core.aggregation.AggregationExpressions.AbstractAggregationExpression#toDocument(java.lang.Object, org.springframework.data.mongodb.core.aggregation.AggregationOperationContext) + */ @Override public Document toDocument(Object value, AggregationOperationContext context) { @@ -6418,6 +6673,9 @@ public interface AggregationExpressions { return new Min(append(expression)); } + /* (non-Javadoc) + * @see org.springframework.data.mongodb.core.aggregation.AggregationExpressions.AbstractAggregationExpression#toDocument(java.lang.Object, org.springframework.data.mongodb.core.aggregation.AggregationOperationContext) + */ @Override public Document toDocument(Object value, AggregationOperationContext context) { @@ -6497,6 +6755,9 @@ public interface AggregationExpressions { return new StdDevPop(append(expression)); } + /* (non-Javadoc) + * @see org.springframework.data.mongodb.core.aggregation.AggregationExpressions.AbstractAggregationExpression#toDocument(java.lang.Object, org.springframework.data.mongodb.core.aggregation.AggregationOperationContext) + */ @Override public Document toDocument(Object value, AggregationOperationContext context) { @@ -6576,6 +6837,9 @@ public interface AggregationExpressions { return new StdDevSamp(append(expression)); } + /* (non-Javadoc) + * @see org.springframework.data.mongodb.core.aggregation.AggregationExpressions.AbstractAggregationExpression#toDocument(java.lang.Object, org.springframework.data.mongodb.core.aggregation.AggregationOperationContext) + */ @Override public Document toDocument(Object value, AggregationOperationContext context) { @@ -7330,15 +7594,21 @@ public interface AggregationExpressions { */ static AsBuilder itemsOf(final String fieldReference) { + Assert.notNull(fieldReference, "FieldReference must not be null!"); + return new AsBuilder() { @Override public FunctionBuilder as(final String variableName) { + Assert.notNull(variableName, "VariableName must not be null!"); + return new FunctionBuilder() { @Override public Map andApply(final AggregationExpression expression) { + + Assert.notNull(expression, "AggregationExpression must not be null!"); return new Map(Fields.field(fieldReference), variableName, expression); } }; @@ -7356,15 +7626,21 @@ public interface AggregationExpressions { */ public static AsBuilder itemsOf(final AggregationExpression source) { + Assert.notNull(source, "AggregationExpression must not be null!"); + return new AsBuilder() { @Override public FunctionBuilder as(final String variableName) { + Assert.notNull(variableName, "VariableName must not be null!"); + return new FunctionBuilder() { @Override public Map andApply(final AggregationExpression expression) { + + Assert.notNull(expression, "AggregationExpression must not be null!"); return new Map(source, variableName, expression); } }; @@ -7372,6 +7648,9 @@ public interface AggregationExpressions { }; } + /* (non-Javadoc) + * @see org.springframework.data.mongodb.core.aggregation.AggregationExpression#toDocument(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext) + */ @Override public Document toDocument(final AggregationOperationContext context) { return toMap(ExposedFields.synthetic(Fields.fields(itemVariableName)), context); @@ -7444,8 +7723,8 @@ public interface AggregationExpressions { /** * Creates new {@link IfNull}. * - * @param fieldReference the field to check for a {@literal null} value, field reference must not be - * {@literal null}. + * @param fieldReference the field to check for a {@literal null} value, field reference must not be {@literal null} + * . * @return */ public static ThenBuilder ifNull(String fieldReference) { @@ -8093,6 +8372,7 @@ public interface AggregationExpressions { Assert.notNull(variables, "Variables must not be null!"); return new LetBuilder() { + @Override public Let andApply(final AggregationExpression expression) { @@ -8113,6 +8393,7 @@ public interface AggregationExpressions { Assert.notNull(variables, "Variables must not be null!"); return new LetBuilder() { + @Override public Let andApply(final AggregationExpression expression) { @@ -8133,6 +8414,9 @@ public interface AggregationExpressions { Let andApply(AggregationExpression expression); } + /* (non-Javadoc) + * @see org.springframework.data.mongodb.core.aggregation.AggregationExpression#toDocument(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext) + */ @Override public Document toDocument(final AggregationOperationContext context) { return toLet(ExposedFields.synthetic(Fields.fields(getVariableNames())), context); @@ -8234,7 +8518,6 @@ public interface AggregationExpressions { } } - /** * {@link AggregationExpression} for {@code $switch}. * @@ -8251,12 +8534,22 @@ public interface AggregationExpressions { return "$switch"; } + /** + * Creates new {@link Switch}. + * + * @param conditions must not be {@literal null}. + */ public static Switch switchCases(CaseOperator... conditions) { Assert.notNull(conditions, "Conditions must not be null!"); return switchCases(Arrays.asList(conditions)); } + /** + * Creates new {@link Switch}. + * + * @param conditions must not be {@literal null}. + */ public static Switch switchCases(List conditions) { Assert.notNull(conditions, "Conditions must not be null!"); @@ -8267,6 +8560,9 @@ public interface AggregationExpressions { return new Switch(append("default", value)); } + /** + * Encapsulates the aggregation framework case document inside a {@code $switch}-operation. + */ public static class CaseOperator implements AggregationExpression { private final AggregationExpression when; @@ -8281,7 +8577,9 @@ public interface AggregationExpressions { public static ThenBuilder when(final AggregationExpression condition) { Assert.notNull(condition, "Condition must not be null!"); + return new ThenBuilder() { + @Override public CaseOperator then(Object value) { @@ -8291,8 +8589,12 @@ public interface AggregationExpressions { }; } + /* (non-Javadoc) + * @see org.springframework.data.mongodb.core.aggregation.AggregationExpression#toDocument(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext) + */ @Override public Document toDocument(AggregationOperationContext context) { + Document document = new Document("case", when.toDocument(context)); if (then instanceof AggregationExpression) { @@ -8306,7 +8608,17 @@ public interface AggregationExpressions { return document; } + /** + * @author Christoph Strobl + */ public interface ThenBuilder { + + /** + * Set the then {@literal value}. + * + * @param value must not be {@literal null}. + * @return + */ CaseOperator then(Object value); } } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperationUnitTests.java index 675f89a72..8478bdd83 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperationUnitTests.java @@ -32,31 +32,13 @@ import org.hamcrest.Matchers; import org.junit.Test; import org.springframework.data.domain.Range; import org.springframework.data.mongodb.core.DocumentTestUtils; -import org.springframework.data.mongodb.core.aggregation.AggregationExpressions.And; -import org.springframework.data.mongodb.core.aggregation.AggregationExpressions.ArithmeticOperators; -import org.springframework.data.mongodb.core.aggregation.AggregationExpressions.ArrayOperators; -import org.springframework.data.mongodb.core.aggregation.AggregationExpressions.Avg; -import org.springframework.data.mongodb.core.aggregation.AggregationExpressions.BooleanOperators; -import org.springframework.data.mongodb.core.aggregation.AggregationExpressions.ComparisonOperators; -import org.springframework.data.mongodb.core.aggregation.AggregationExpressions.ConditionalOperators; -import org.springframework.data.mongodb.core.aggregation.AggregationExpressions.DateOperators; -import org.springframework.data.mongodb.core.aggregation.AggregationExpressions.Gte; import org.springframework.data.mongodb.core.aggregation.AggregationExpressions.Let.ExpressionVariable; -import org.springframework.data.mongodb.core.aggregation.AggregationExpressions.LiteralOperators; -import org.springframework.data.mongodb.core.aggregation.AggregationExpressions.Lt; -import org.springframework.data.mongodb.core.aggregation.AggregationExpressions.RangeOperator; import org.springframework.data.mongodb.core.aggregation.AggregationExpressions.Reduce.PropertyExpression; import org.springframework.data.mongodb.core.aggregation.AggregationExpressions.Reduce.Variable; -import org.springframework.data.mongodb.core.aggregation.AggregationExpressions.SetOperators; -import org.springframework.data.mongodb.core.aggregation.AggregationExpressions.StringOperators; import org.springframework.data.mongodb.core.aggregation.AggregationExpressions.Switch.CaseOperator; -import org.springframework.data.mongodb.core.aggregation.AggregationExpressions.Type; -import org.springframework.data.mongodb.core.aggregation.AggregationExpressions.VariableOperators; import org.springframework.data.mongodb.core.aggregation.ProjectionOperation.ProjectionOperationBuilder; import org.springframework.data.mongodb.core.aggregation.AggregationExpressions.*; -import com.mongodb.util.JSON; - /** * Unit tests for {@link ProjectionOperation}. * @@ -1827,7 +1809,8 @@ public class ProjectionOperationUnitTests { Document agg = project().and(StringOperators.valueOf("item").indexOf("foo")).as("byteLocation") .toDocument(Aggregation.DEFAULT_CONTEXT); - assertThat(agg, Matchers.is(Document.parse("{ $project: { byteLocation: { $indexOfBytes: [ \"$item\", \"foo\" ] } } }"))); + assertThat(agg, + Matchers.is(Document.parse("{ $project: { byteLocation: { $indexOfBytes: [ \"$item\", \"foo\" ] } } }"))); } /** @@ -1852,7 +1835,8 @@ public class ProjectionOperationUnitTests { Document agg = project().and(StringOperators.valueOf("item").indexOfCP("foo")).as("cpLocation") .toDocument(Aggregation.DEFAULT_CONTEXT); - assertThat(agg, Matchers.is(Document.parse("{ $project: { cpLocation: { $indexOfCP: [ \"$item\", \"foo\" ] } } }"))); + assertThat(agg, + Matchers.is(Document.parse("{ $project: { cpLocation: { $indexOfCP: [ \"$item\", \"foo\" ] } } }"))); } /** @@ -1913,7 +1897,8 @@ public class ProjectionOperationUnitTests { Document agg = project().and(StringOperators.valueOf("quarter").substringCP(0, 2)).as("yearSubstring") .toDocument(Aggregation.DEFAULT_CONTEXT); - assertThat(agg, Matchers.is(Document.parse("{ $project : { yearSubstring: { $substrCP: [ \"$quarter\", 0, 2 ] } } }"))); + assertThat(agg, + Matchers.is(Document.parse("{ $project : { yearSubstring: { $substrCP: [ \"$quarter\", 0, 2 ] } } }"))); } /** @@ -1950,7 +1935,8 @@ public class ProjectionOperationUnitTests { Document agg = project().and(ArrayOperators.arrayOf("favorites").reverse()).as("reverseFavorites") .toDocument(Aggregation.DEFAULT_CONTEXT); - assertThat(agg, Matchers.is(Document.parse("{ $project : { reverseFavorites: { $reverseArray: \"$favorites\" } } }"))); + assertThat(agg, + Matchers.is(Document.parse("{ $project : { reverseFavorites: { $reverseArray: \"$favorites\" } } }"))); } /** @@ -1975,9 +1961,9 @@ public class ProjectionOperationUnitTests { public void shouldRenderReduceWithComplexObjectCorrectly() { PropertyExpression sum = PropertyExpression.property("sum").definedAs( - ArithmeticOperators.valueOf(Variable.VALUE.referingTo("sum").getName()).add(Variable.THIS.getName())); + ArithmeticOperators.valueOf(Variable.VALUE.referringTo("sum").getName()).add(Variable.THIS.getName())); PropertyExpression product = PropertyExpression.property("product").definedAs(ArithmeticOperators - .valueOf(Variable.VALUE.referingTo("product").getName()).multiplyBy(Variable.THIS.getName())); + .valueOf(Variable.VALUE.referringTo("product").getName()).multiplyBy(Variable.THIS.getName())); Document agg = project() .and(ArrayOperators.arrayOf("probabilityArr").reduce(sum, product) @@ -2015,7 +2001,8 @@ public class ProjectionOperationUnitTests { Document agg = project().and(ArrayOperators.arrayOf("in_stock").containsValue("bananas")).as("has_bananas") .toDocument(Aggregation.DEFAULT_CONTEXT); - assertThat(agg, Matchers.is(Document.parse("{ $project : { has_bananas : { $in : [\"bananas\", \"$in_stock\" ] } } }"))); + assertThat(agg, + Matchers.is(Document.parse("{ $project : { has_bananas : { $in : [\"bananas\", \"$in_stock\" ] } } }"))); } /** @@ -2100,8 +2087,7 @@ public class ProjectionOperationUnitTests { @Test public void shouldTypeCorrectly() { - Document agg = project().and(Type.typeOf("a")).as("a") - .toDocument(Aggregation.DEFAULT_CONTEXT); + Document agg = project().and(Type.typeOf("a")).as("a").toDocument(Aggregation.DEFAULT_CONTEXT); assertThat(agg, Matchers.is(Document.parse("{ $project : { a: { $type: \"$a\" } } }"))); }