31
31
32
32
/**
33
33
* Specification in the sense of Domain Driven Design to handle Criteria Updates.
34
+ * <p>
35
+ * Specifications can be composed into higher order functions from other specifications using
36
+ * {@link #and(UpdateSpecification)}, {@link #or(UpdateSpecification)} or factory methods such as
37
+ * {@link #allOf(Iterable)}. Composition considers whether one or more specifications contribute to the overall
38
+ * predicate by returning a {@link Predicate} or {@literal null}. Specifications returning {@literal null} are
39
+ * considered to not contribute to the overall predicate and their result is not considered in the final predicate.
34
40
*
35
41
* @author Mark Paluch
36
42
* @since 4.0
39
45
public interface UpdateSpecification <T > extends Serializable {
40
46
41
47
/**
42
- * Simple static factory method to create a specification deleting all objects.
48
+ * Simple static factory method to create a specification updating all objects.
43
49
*
44
50
* @param <T> the type of the {@link Root} the resulting {@literal UpdateSpecification} operates on.
45
51
* @return guaranteed to be not {@literal null}.
46
52
*/
47
- static <T > UpdateSpecification <T > all () {
53
+ static <T > UpdateSpecification <T > unrestricted () {
48
54
return (root , query , builder ) -> null ;
49
55
}
50
56
51
57
/**
52
- * Simple static factory method to add some syntactic sugar around a {@literal UpdateSpecification }. For example:
58
+ * Simple static factory method to add some syntactic sugar around a {@literal UpdateOperation }. For example:
53
59
*
54
60
* <pre class="code">
55
- * UpdateSpecification<User> updateLastname = UpdateSpecification
61
+ * UpdateSpecification<User> updateLastname = UpdateOperation
56
62
* .<User> update((root, update, criteriaBuilder) -> update.set("lastname", "Heisenberg"))
57
63
* .where(userHasFirstname("Walter").and(userHasLastname("White")));
58
64
*
59
65
* repository.update(updateLastname);
60
66
* </pre>
61
67
*
62
- * @param <T> the type of the {@link Root} the resulting {@literal UpdateSpecification } operates on.
68
+ * @param <T> the type of the {@link Root} the resulting {@literal UpdateOperation } operates on.
63
69
* @param spec must not be {@literal null}.
64
70
* @return guaranteed to be not {@literal null}.
65
71
*/
@@ -172,13 +178,14 @@ static <T> UpdateSpecification<T> not(UpdateSpecification<T> spec) {
172
178
173
179
return (root , update , builder ) -> {
174
180
175
- Predicate not = spec .toPredicate (root , update , builder );
176
- return not != null ? builder .not (not ) : null ;
181
+ Predicate predicate = spec .toPredicate (root , update , builder );
182
+ return predicate != null ? builder .not (predicate ) : null ;
177
183
};
178
184
}
179
185
180
186
/**
181
- * Applies an AND operation to all the given {@link UpdateSpecification}s.
187
+ * Applies an AND operation to all the given {@link UpdateSpecification}s. If {@code specifications} is empty, the
188
+ * resulting {@link UpdateSpecification} will be unrestricted applying to all objects.
182
189
*
183
190
* @param specifications the {@link UpdateSpecification}s to compose.
184
191
* @return the conjunction of the specifications.
@@ -191,7 +198,8 @@ static <T> UpdateSpecification<T> allOf(UpdateSpecification<T>... specifications
191
198
}
192
199
193
200
/**
194
- * Applies an AND operation to all the given {@link UpdateSpecification}s.
201
+ * Applies an AND operation to all the given {@link UpdateSpecification}s. If {@code specifications} is empty, the
202
+ * resulting {@link UpdateSpecification} will be unrestricted applying to all objects.
195
203
*
196
204
* @param specifications the {@link UpdateSpecification}s to compose.
197
205
* @return the conjunction of the specifications.
@@ -201,11 +209,12 @@ static <T> UpdateSpecification<T> allOf(UpdateSpecification<T>... specifications
201
209
static <T > UpdateSpecification <T > allOf (Iterable <UpdateSpecification <T >> specifications ) {
202
210
203
211
return StreamSupport .stream (specifications .spliterator (), false ) //
204
- .reduce (UpdateSpecification .all (), UpdateSpecification ::and );
212
+ .reduce (UpdateSpecification .unrestricted (), UpdateSpecification ::and );
205
213
}
206
214
207
215
/**
208
- * Applies an OR operation to all the given {@link UpdateSpecification}s.
216
+ * Applies an OR operation to all the given {@link UpdateSpecification}s. If {@code specifications} is empty, the
217
+ * resulting {@link UpdateSpecification} will be unrestricted applying to all objects.
209
218
*
210
219
* @param specifications the {@link UpdateSpecification}s to compose.
211
220
* @return the disjunction of the specifications.
@@ -218,7 +227,8 @@ static <T> UpdateSpecification<T> anyOf(UpdateSpecification<T>... specifications
218
227
}
219
228
220
229
/**
221
- * Applies an OR operation to all the given {@link UpdateSpecification}s.
230
+ * Applies an OR operation to all the given {@link UpdateSpecification}s. If {@code specifications} is empty, the
231
+ * resulting {@link UpdateSpecification} will be unrestricted applying to all objects.
222
232
*
223
233
* @param specifications the {@link UpdateSpecification}s to compose.
224
234
* @return the disjunction of the specifications.
@@ -228,7 +238,7 @@ static <T> UpdateSpecification<T> anyOf(UpdateSpecification<T>... specifications
228
238
static <T > UpdateSpecification <T > anyOf (Iterable <UpdateSpecification <T >> specifications ) {
229
239
230
240
return StreamSupport .stream (specifications .spliterator (), false ) //
231
- .reduce (UpdateSpecification .all (), UpdateSpecification ::or );
241
+ .reduce (UpdateSpecification .unrestricted (), UpdateSpecification ::or );
232
242
}
233
243
234
244
/**
0 commit comments