1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package net.sourceforge.domian.specification;
17
18
19 import java.text.ParseException;
20 import java.text.SimpleDateFormat;
21 import java.util.Collection;
22 import java.util.Date;
23
24 import org.apache.commons.lang.Validate;
25
26 import net.sourceforge.domian.entity.Entity;
27
28 import static java.util.Arrays.asList;
29 import static net.sourceforge.domian.specification.CollectionSpecification.CollectionSpecificationScope;
30
31
32
33
34
35
36
37
38
39
40
41
42
43 public final class SpecificationFactory {
44
45
46
47
48
49
50
51
52
53
54 public static <T> CompositeSpecification<T> createSpecificationFor(final Class<T> type) {
55
56 return new ConjunctionSpecification<T>(type);
57 }
58
59 public static <T> CompositeSpecification<T> the(final Class<T> type) {
60 return createSpecificationFor(type);
61 }
62
63 public static <T> CompositeSpecification<T> a(final Class<T> type) {
64 return createSpecificationFor(type);
65 }
66
67 public static <T> CompositeSpecification<T> an(final Class<T> type) {
68 return createSpecificationFor(type);
69 }
70
71 public static <T> CompositeSpecification<T> isA(final Class<T> type) {
72 return createSpecificationFor(type);
73 }
74
75 public static <T> CompositeSpecification<T> isAn(final Class<T> type) {
76 return createSpecificationFor(type);
77 }
78
79 public static <T> CompositeSpecification<T> all(final Class<T> type) {
80 return createSpecificationFor(type);
81 }
82
83 public static <T> CompositeSpecification<T> instanceOf(final Class<T> type) {
84 return createSpecificationFor(type);
85 }
86
87 public static <T> CompositeSpecification<T> instancesOf(final Class<T> type) {
88 return createSpecificationFor(type);
89 }
90
91 public static <T> CompositeSpecification<T> instanceOfType(final Class<T> type) {
92 return createSpecificationFor(type);
93 }
94
95 public static <T> CompositeSpecification<T> instancesOfType(final Class<T> type) {
96 return createSpecificationFor(type);
97 }
98
99 public static <T> CompositeSpecification<T> anInstanceOfType(final Class<T> type) {
100 return createSpecificationFor(type);
101 }
102
103 public static <T> CompositeSpecification<T> allOfType(final Class<T> type) {
104 return createSpecificationFor(type);
105 }
106
107 public static <T> CompositeSpecification<T> allInstancesOfType(final Class<T> type) {
108 return createSpecificationFor(type);
109 }
110
111 public static <T> CompositeSpecification<T> specify(final Class<T> type) {
112 return createSpecificationFor(type);
113 }
114
115 public static <T> CompositeSpecification<T> specifyA(final Class<T> type) {
116 return createSpecificationFor(type);
117 }
118
119 public static <T> CompositeSpecification<T> specifyAn(final Class<T> type) {
120 return createSpecificationFor(type);
121 }
122
123
124
125
126
127
128
129
130
131
132
133 public static Specification<?> createAlwaysFalseSpecification() {
134 return new AlwaysFalseSpecification();
135 }
136
137
138 public static Specification<?> createContradiction() {
139 return createAlwaysFalseSpecification();
140 }
141
142
143 public static Specification<?> createAlwaysTrueSpecification() {
144 return new AlwaysTrueSpecification();
145 }
146
147
148 public static Specification<?> createTautology() {
149 return createAlwaysTrueSpecification();
150 }
151
152
153 public static <T> Specification<T> createNotNullSpecification(final Class<T> type) {
154 return new NotNullSpecification<T>(type);
155 }
156
157
158 public static Specification allObjects() {
159 return createNotNullSpecification(Object.class);
160 }
161
162
163 public static Specification<? extends Entity> allEntities() {
164 return createNotNullSpecification(Entity.class);
165 }
166
167
168 public static Specification<? extends Entity> entities() {
169 return createNotNullSpecification(Entity.class);
170 }
171
172
173 public static Specification<? extends Entity> entity() {
174 return createNotNullSpecification(Entity.class);
175 }
176
177
178 public static Specification<?> isNull() {
179 return not(isNotNull());
180 }
181
182
183 public static Specification<?> isNotNull() {
184 return createNotNullSpecification(Object.class);
185 }
186
187
188 static <T> Specification<T> createDefaultValueOfTypeSpecification(final Class<T> type) {
189 return new DefaultValueSpecification<T>(type);
190 }
191
192
193 static <T> Specification<T> isDefaultValueOfType(final Class<T> type) {
194 return createDefaultValueOfTypeSpecification(type);
195 }
196
197
198 static <T> Specification<T> defaultValueOfType(final Class<T> type) {
199 return createDefaultValueOfTypeSpecification(type);
200 }
201
202
203 public static Specification<Number> createDefaultNumberSpecification() {
204 return createDefaultValueOfTypeSpecification(Number.class);
205 }
206
207
208 public static Specification<Number> isDefaultNumber() {
209 return createDefaultValueOfTypeSpecification(Number.class);
210 }
211
212
213 public static Specification<Number> defaultNumber() {
214 return createDefaultValueOfTypeSpecification(Number.class);
215 }
216
217
218 public static Specification<String> createBlankStringSpecification() {
219 return createDefaultValueOfTypeSpecification(String.class);
220 }
221
222
223 public static Specification<String> isBlankString() {
224 return createDefaultValueOfTypeSpecification(String.class);
225 }
226
227
228 public static Specification<String> blankString() {
229 return createDefaultValueOfTypeSpecification(String.class);
230 }
231
232
233 public static Specification<String> createEqualIgnoreCaseStringSpecification(final String string) {
234 return new EqualIgnoreCaseStringSpecification(string);
235 }
236
237
238 public static Specification<String> equalIgnoringCase(final String string) {
239 return createEqualIgnoreCaseStringSpecification(string);
240 }
241
242
243 public static Specification<String> equalsIgnoringCase(final String string) {
244 return createEqualIgnoreCaseStringSpecification(string);
245 }
246
247
248 public static Specification<String> isEqualIgnoringCase(final String string) {
249 return createEqualIgnoreCaseStringSpecification(string);
250 }
251
252
253 public static Specification<String> createDateStringSpecification(final String dateString) {
254 return new DateStringSpecification(dateString);
255 }
256
257
258 public static Specification<String> isDate(final String dateString) {
259 return createDateStringSpecification(dateString);
260 }
261
262
263 public static <E extends Enum> Specification<String> createEnumNameStringSpecification(Class<E> enumClass) {
264 return new EnumNameStringSpecification<E>(enumClass);
265 }
266
267
268 public static <E extends Enum> Specification<String> isEnum(Class<E> enumClass) {
269 return createEnumNameStringSpecification(enumClass);
270 }
271
272
273
274
275
276
277 public static <T> Specification<T> createEqualSpecification(final T value) {
278 return new EqualSpecification<T>(value);
279 }
280
281
282 public static <T> Specification<T> anObjectEqualTo(final T value) {
283 return new EqualSpecification<T>(value);
284 }
285
286
287 public static <T> Specification<T> objectEqualTo(final T value) {
288 return new EqualSpecification<T>(value);
289 }
290
291
292 public static <T> Specification<T> isEqualTo(final T value) {
293 return createEqualSpecification(value);
294 }
295
296
297 public static <T> Specification<T> equalTo(final T value) {
298 return createEqualSpecification(value);
299 }
300
301
302 public static <T> Specification<T> exactly(final T value) {
303 return createEqualSpecification(value);
304 }
305
306
307 public static <T> Specification<T> is(final T value) {
308 return createEqualSpecification(value);
309 }
310
311
312 public static Specification<Date> isAtTheSameTimeAs(final Date date) {
313 return createEqualSpecification(date);
314 }
315
316
317 public static Specification<Date> atTheSameTimeAs(final Date date) {
318 return createEqualSpecification(date);
319 }
320
321
322 public static Specification<Date> at(final Date date) {
323 return createEqualSpecification(date);
324 }
325
326
327 public static Specification<Boolean> isTrue() {
328 return createEqualSpecification(Boolean.TRUE);
329 }
330
331
332 public static Specification<Boolean> isFalse() {
333 return createEqualSpecification(Boolean.FALSE);
334 }
335
336
337
338
339
340
341 static Specification<String> createRegularExpressionMatcherStringSpecification(final String regularExpression) {
342 return new RegularExpressionMatcherStringSpecification(regularExpression);
343 }
344
345
346 public static Specification<String> matchesRegularExpression(final String regularExpression) {
347 return createRegularExpressionMatcherStringSpecification(regularExpression);
348 }
349
350
351 public static Specification<String> matchesRegex(final String regularExpression) {
352 return createRegularExpressionMatcherStringSpecification(regularExpression);
353 }
354
355
356 public static Specification<String> matches(final String regularExpression) {
357 return createRegularExpressionMatcherStringSpecification(regularExpression);
358 }
359
360
361
362
363
364
365 static Specification<String> createWildcardExpressionMatcherStringSpecification(final String wildcardExpression) {
366 return new WildcardExpressionMatcherStringSpecification(wildcardExpression);
367 }
368
369
370 public static Specification<String> matchesWildcardExpression(final String wildcardExpression) {
371 return createWildcardExpressionMatcherStringSpecification(wildcardExpression);
372 }
373
374
375 public static Specification<String> like(final String wildcardExpression) {
376 return createWildcardExpressionMatcherStringSpecification(wildcardExpression);
377 }
378
379
380 static Specification<String> createWildcardExpressionIgnoringCaseMatcherStringSpecification(final String wildcardExpression) {
381 return new WildcardExpressionMatcherIgnoreCaseStringSpecification(wildcardExpression);
382 }
383
384
385 public static Specification<String> matchesWildcardExpressionIgnoringCase(final String wildcardExpression) {
386 return createWildcardExpressionIgnoringCaseMatcherStringSpecification(wildcardExpression);
387 }
388
389
390
391
392
393
394 static <T extends Comparable> Specification<T> createLessThanSpecification(final T value) {
395 return new LessThanSpecification<T>(value);
396 }
397
398
399 public static <T extends Comparable> Specification<T> isLessThan(final T value) {
400 return createLessThanSpecification(value);
401 }
402
403
404 public static <T extends Comparable> Specification<T> lessThan(final T value) {
405 return createLessThanSpecification(value);
406 }
407
408
409 public static <T extends Comparable> Specification<T> isBefore(final T value) {
410 return createLessThanSpecification(value);
411 }
412
413
414 public static <T extends Comparable> Specification<T> before(final T value) {
415 return createLessThanSpecification(value);
416 }
417
418
419 public static Specification<Date> isBefore(final String dateString) {
420 return before(dateString);
421 }
422
423
424 public static Specification<Date> before(final String dateString) {
425 try {
426 final String datePattern = validateDateString(dateString);
427 return createLessThanSpecification(new SimpleDateFormat(datePattern).parse(dateString));
428
429 } catch (ParseException e) {
430 throw new IllegalArgumentException("\"" + dateString + "\"" + DATE_PARSING_ERROR_MSG_ENDING);
431 }
432 }
433
434
435
436
437
438
439 static <T extends Comparable> Specification<T> createLessThanOrEqualSpecification(final T value) {
440 return anyOf(lessThan(value), equalTo(value));
441 }
442
443
444 public static <T extends Comparable> Specification<T> isLessThanOrEqualTo(final T value) {
445 return createLessThanOrEqualSpecification(value);
446 }
447
448
449 public static <T extends Comparable> Specification<T> lessThanOrEqualTo(final T value) {
450 return createLessThanOrEqualSpecification(value);
451 }
452
453
454 public static <T extends Comparable> Specification<T> atMost(final T value) {
455 return createLessThanOrEqualSpecification(value);
456 }
457
458
459 public static <T extends Comparable> Specification<T> isBeforeOrAtTheSameTimeAs(final T dateOrLongValue) {
460 return createLessThanOrEqualSpecification(dateOrLongValue);
461 }
462
463
464 public static <T extends Comparable> Specification<T> beforeOrAtTheSameTimeAs(final T dateOfLongValue) {
465 return createLessThanOrEqualSpecification(dateOfLongValue);
466 }
467
468
469 public static Specification<Date> isBeforeOrAtTheSameTimeAs(final String dateString) {
470 return beforeOrAtTheSameTimeAs(dateString);
471 }
472
473
474 public static Specification<Date> beforeOrAtTheSameTimeAs(final String dateString) {
475 try {
476 return createLessThanOrEqualSpecification(new SimpleDateFormat(validateDateString(dateString)).parse(dateString));
477
478 } catch (ParseException e) {
479 throw new IllegalArgumentException("\"" + dateString + "\"" + DATE_PARSING_ERROR_MSG_ENDING);
480 }
481 }
482
483
484
485
486
487
488 static <T extends Comparable> Specification<T> createGreaterThanSpecification(final T value) {
489 return new GreaterThanSpecification<T>(value);
490 }
491
492
493 public static <T extends Comparable> Specification<T> isGreaterThan(final T value) {
494 return createGreaterThanSpecification(value);
495 }
496
497
498 public static <T extends Comparable> Specification<T> greaterThan(final T value) {
499 return createGreaterThanSpecification(value);
500 }
501
502
503 public static <T extends Comparable> Specification<T> moreThan(final T value) {
504 return createGreaterThanSpecification(value);
505 }
506
507
508 public static <T extends Comparable> Specification<T> isAfter(final T value) {
509 return createGreaterThanSpecification(value);
510 }
511
512
513 public static <T extends Comparable> Specification<T> after(final T value) {
514 return createGreaterThanSpecification(value);
515 }
516
517
518 public static Specification<Date> isAfter(final String dateString) {
519 return after(dateString);
520 }
521
522
523 public static Specification<Date> after(final String dateString) {
524 try {
525 final String datePattern = validateDateString(dateString);
526 return createGreaterThanSpecification(new SimpleDateFormat(datePattern).parse(dateString));
527
528 } catch (ParseException e) {
529 throw new IllegalArgumentException("\"" + dateString + "\"" + DATE_PARSING_ERROR_MSG_ENDING);
530 }
531 }
532
533
534
535
536
537
538 static <T extends Comparable> Specification<T> createGreaterThanOrEqualSpecification(final T value) {
539 return anyOf(greaterThan(value), equalTo(value));
540 }
541
542
543 public static <T extends Comparable> Specification<T> isGreaterThanOrEqualTo(final T value) {
544 return createGreaterThanOrEqualSpecification(value);
545 }
546
547
548 public static <T extends Comparable> Specification<T> greaterThanOrEqualTo(final T value) {
549 return createGreaterThanOrEqualSpecification(value);
550 }
551
552
553 public static <T extends Comparable> Specification<T> atLeast(final T value) {
554 return createGreaterThanOrEqualSpecification(value);
555 }
556
557
558 public static <T extends Comparable> Specification<T> isAfterOrAtTheSameTimeAs(final T dateOrLongValue) {
559 return createGreaterThanOrEqualSpecification(dateOrLongValue);
560 }
561
562
563 public static <T extends Comparable> Specification<T> afterOrAtTheSameTimeAs(final T dateOrLongValue) {
564 return createGreaterThanOrEqualSpecification(dateOrLongValue);
565 }
566
567
568 public static Specification<Date> isAfterOrAtTheSameTimeAs(final String dateString) {
569 return afterOrAtTheSameTimeAs(dateString);
570 }
571
572
573 public static Specification<Date> afterOrAtTheSameTimeAs(final String dateString) {
574 try {
575 return createLessThanOrEqualSpecification(new SimpleDateFormat(validateDateString(dateString)).parse(dateString));
576
577 } catch (ParseException e) {
578 throw new IllegalArgumentException("\"" + dateString + "\"" + DATE_PARSING_ERROR_MSG_ENDING);
579 }
580 }
581
582
583
584
585
586
587
588
589
590
591
592 @SuppressWarnings("unchecked")
593 public static <T> Specification<T> allOf(final Specification<T>... specifications) {
594 Validate.notNull(specifications, "Specification varargs cannot be null");
595 Validate.isTrue(specifications.length > 0, "Specification varargs cannot be empty");
596 if (specifications.length == 1) {
597 Validate.notNull(specifications[0], "Specification varargs cannot be null");
598 }
599 final Specification<T> firstSpecParameter = specifications[0];
600 final ConjunctionSpecification<T> conjunctionSpecification;
601
602 if (firstSpecParameter instanceof CollectionSpecification) {
603
604
605 conjunctionSpecification = new ConjunctionSpecification(Collection.class);
606 conjunctionSpecification.specifications.addAll(asList(specifications));
607 } else {
608 conjunctionSpecification = new ConjunctionSpecification<T>(firstSpecParameter.getType());
609 conjunctionSpecification.specifications.addAll(asList(specifications));
610 }
611 return conjunctionSpecification.purify(true);
612 }
613
614
615 public static <T> Specification<T> shouldBeAllOf(final Specification<T>... specifications) {
616 return allOf(specifications);
617 }
618
619
620 public static <T> Specification<T> shouldBeBoth(final Specification<T>... specifications) {
621 return allOf(specifications);
622 }
623
624
625 public static <T> Specification<T> shouldBe(final Specification<T>... specifications) {
626 return allOf(specifications);
627 }
628
629
630 public static <T> Specification<T> isAllOf(final Specification<T>... specifications) {
631 return allOf(specifications);
632 }
633
634
635 public static <T> Specification<T> isBoth(final Specification<T>... specifications) {
636 return allOf(specifications);
637 }
638
639
640 public static <T> Specification<T> both(final Specification<T>... specifications) {
641 return allOf(specifications);
642 }
643
644
645
646
647
648
649 @SuppressWarnings("unchecked")
650 public static <T> Specification<T> anyOf(final Specification<T>... specifications) {
651 Validate.notNull(specifications, "Specification varargs cannot be null");
652 Validate.isTrue(specifications.length > 0, "Specification varargs cannot be empty");
653 if (specifications.length == 1) {
654 Validate.notNull(specifications[0], "Specification varargs cannot be null");
655 }
656 final Specification<T> firstSpecParameter = specifications[0];
657 final DisjunctionSpecification<T> disjunctionSpecification;
658
659 if (firstSpecParameter instanceof CollectionSpecification) {
660
661
662 disjunctionSpecification = new DisjunctionSpecification(Collection.class);
663 disjunctionSpecification.specifications.addAll(asList(specifications));
664 } else {
665 disjunctionSpecification = new DisjunctionSpecification<T>(firstSpecParameter.getType());
666 disjunctionSpecification.specifications.addAll(asList(specifications));
667 }
668 return disjunctionSpecification.purify(true);
669 }
670
671
672 public static <T> Specification<T> shouldBeOneOf(final Specification<T>... specifications) {
673 return anyOf(specifications);
674 }
675
676
677 public static <T> Specification<T> shouldBeEitherOf(final Specification<T>... specifications) {
678 return anyOf(specifications);
679 }
680
681
682 public static <T> Specification<T> isOneOf(final Specification<T>... specifications) {
683 return anyOf(specifications);
684 }
685
686
687 public static <T> Specification<T> isEitherOf(final Specification<T>... specifications) {
688 return anyOf(specifications);
689 }
690
691
692 public static <T> Specification<T> isEitherThe(final Specification<T>... specifications) {
693 return anyOf(specifications);
694 }
695
696
697 public static <T> Specification<T> isEither(final Specification<T>... specifications) {
698 return anyOf(specifications);
699 }
700
701
702 public static <T> Specification<T> oneOf(final Specification<T>... specifications) {
703 return anyOf(specifications);
704 }
705
706
707 public static <T> Specification<T> eitherOf(final Specification<T>... specifications) {
708 return anyOf(specifications);
709 }
710
711
712 public static <T> Specification<T> either(final Specification<T>... specifications) {
713 return anyOf(specifications);
714 }
715
716
717 public static <T> Specification<T> in(final Specification<T>... specifications) {
718 return anyOf(specifications);
719 }
720
721
722
723
724
725
726 @SuppressWarnings("unchecked")
727 public static <F> Specification<F> anyOf(final F... values) {
728
729 final Specification<F>[] specsArray = new Specification[values.length];
730 for (int i = 0; i < values.length; ++i) {
731 if (values[i] instanceof Specification) {
732
733
734 specsArray[i] = (Specification<F>) values[i];
735 } else {
736 specsArray[i] = createEqualSpecification(values[i]);
737 }
738 }
739 return anyOf(specsArray);
740 }
741
742
743 public static <F> Specification<F> shouldBeOneOf(final F... values) {
744 return anyOf(values);
745 }
746
747
748 public static <F> Specification<F> shouldBeEitherOf(final F... values) {
749 return anyOf(values);
750 }
751
752
753 public static <F> Specification<F> isOneOf(final F... values) {
754 return anyOf(values);
755 }
756
757
758 public static <F> Specification<F> isEitherOf(final F... values) {
759 return anyOf(values);
760 }
761
762
763 public static <F> Specification<F> isEitherThe(final F... values) {
764 return anyOf(values);
765 }
766
767
768 public static <F> Specification<F> isEither(final F... values) {
769 return anyOf(values);
770 }
771
772
773 public static <F> Specification<F> oneOf(final F... values) {
774 return anyOf(values);
775 }
776
777
778 public static <F> Specification<F> eitherOf(final F... values) {
779 return anyOf(values);
780 }
781
782
783 public static <F> Specification<F> either(final F... values) {
784 return anyOf(values);
785 }
786
787
788 public static <F> Specification<F> in(final F... values) {
789 return anyOf(values);
790 }
791
792
793
794
795
796
797 @SuppressWarnings("unchecked")
798 public static <T> Specification<T> neitherOf(final Specification<T>... specifications) {
799 Validate.notNull(specifications, "Specification varargs cannot be null");
800 Validate.isTrue(specifications.length > 0, "Specification varargs cannot be empty");
801 if (specifications.length == 1) {
802 Validate.notNull(specifications[0], "Specification varargs cannot be null");
803 }
804 final Specification<T> firstSpecParameter = specifications[0];
805 final JointDenialSpecification<T> jointDenialSpecification;
806
807 if (firstSpecParameter instanceof CollectionSpecification) {
808
809
810 jointDenialSpecification = new JointDenialSpecification(Collection.class);
811 jointDenialSpecification.specifications.addAll(asList(specifications));
812 } else {
813 jointDenialSpecification = new JointDenialSpecification<T>(firstSpecParameter.getType());
814 jointDenialSpecification.specifications.addAll(asList(specifications));
815 }
816 return jointDenialSpecification.purify(false);
817 }
818
819
820 public static <T> Specification<T> not(final Specification<T> specification) {
821 return neitherOf(specification);
822 }
823
824
825 public static <T> Specification<T> not(final T object) {
826 return not(equalTo(object));
827 }
828
829
830
831
832
833 public static <T> Specification<T> isSatisfiedBy(final Specification<T> specification) {
834 return allOf(specification);
835 }
836
837 public static <T> Specification<T> a(final Specification<T> specification) {
838 return isSatisfiedBy(specification);
839 }
840
841 public static <T> Specification<T> an(final Specification<T> specification) {
842 return isSatisfiedBy(specification);
843 }
844
845 public static <T> Specification<T> is(final Specification<T> specification) {
846 return isSatisfiedBy(specification);
847 }
848
849 public static <T> Specification<T> isA(final Specification<T> specification) {
850 return isSatisfiedBy(specification);
851 }
852
853 public static <T> Specification<T> isAn(final Specification<T> specification) {
854 return isSatisfiedBy(specification);
855 }
856
857 public static <T> Specification<T> are(final Specification<T> specification) {
858 return isSatisfiedBy(specification);
859 }
860
861 public static <T> Specification<T> isFrom(final Specification<T> specification) {
862 return isSatisfiedBy(specification);
863 }
864
865
866
867
868
869
870 public static <F> CollectionSpecification<F> hasSize(final Specification<Integer> collectionSpecification, Class<F> elementType) {
871 return new CollectionSpecification<F>(CollectionSpecificationScope.SIZE, collectionSpecification, new NotNullSpecification<F>(elementType));
872 }
873
874
875 public static <F> CollectionSpecification<F> haveSize(final Specification<Integer> collectionSpecification, Class<F> elementType) {
876 return hasSize(collectionSpecification, elementType);
877 }
878
879
880 public static <F> CollectionSpecification<F> hasSizeOf(final Specification<Integer> collectionSpecification, Class<F> elementType) {
881 return hasSize(collectionSpecification, elementType);
882 }
883
884
885 public static <F> CollectionSpecification<F> haveSizeOf(final Specification<Integer> collectionSpecification, Class<F> elementType) {
886 return hasSize(collectionSpecification, elementType);
887 }
888
889
890 public static Specification<?> hasSize(final Specification<Integer> collectionSpecification) {
891 return new CollectionSpecification<Object>(CollectionSpecificationScope.SIZE, collectionSpecification, Object.class);
892 }
893
894
895 public static Specification<?> haveSize(final Specification<Integer> collectionSpecification) {
896 return hasSize(collectionSpecification);
897 }
898
899
900 public static Specification<?> hasSizeOf(final Specification<Integer> collectionSpecification) {
901 return hasSize(collectionSpecification);
902 }
903
904
905 public static Specification<?> haveSizeOf(final Specification<Integer> collectionSpecification) {
906 return hasSize(collectionSpecification);
907 }
908
909
910 public static Specification<?> isEmpty() {
911 return hasSize(equalTo(0));
912 }
913
914
915 public static Specification<?> empty() {
916 return hasSize(equalTo(0));
917 }
918
919
920 public static <F> CollectionSpecification<F> include(final Specification<Integer> collectionSpecification, final Specification<F> elementSpecification) {
921 return new CollectionSpecification<F>(CollectionSpecificationScope.NUMBER_OF_APPROVED_ELEMENTS, collectionSpecification, elementSpecification);
922 }
923
924
925 public static <F> CollectionSpecification<F> includes(final Specification<Integer> collectionSpecification, final Specification<F> elementSpecification) {
926 return include(collectionSpecification, elementSpecification);
927 }
928
929
930 public static <F> CollectionSpecification<F> includeAPercentageOf(Specification<Integer> collectionSpecification, Specification<F> elementSpecification) {
931 return new CollectionSpecification<F>(CollectionSpecificationScope.PERCENTAGE_OF_APPROVED_ELEMENTS, collectionSpecification, elementSpecification);
932 }
933
934
935 public static <F> CollectionSpecification<F> includesAPercentageOf(Specification<Integer> collectionSpecification, Specification<F> elementSpecification) {
936 return includeAPercentageOf(collectionSpecification, elementSpecification);
937 }
938
939
940
941
942
943 private static final String DATE_PARSING_ERROR_MSG_ENDING = " is not recognized as a valid date string -" +
944 " use a method with java.util.Date as parameter type to see whether" +
945 " the provided date parameter is actually illegal, or expressed in a not-supported format";
946
947 private static String validateDateString(String dateString) {
948 if (dateString.length() != 8 && dateString.length() != 10) {
949 throw new IllegalArgumentException("\"" + dateString + "\"" + DATE_PARSING_ERROR_MSG_ENDING);
950 }
951 if (dateString.length() == 8) {
952 final DateStringSpecification spec = new DateStringSpecification("yyyyMMdd");
953 if (spec.isSatisfiedBy(dateString)) {
954 return spec.getValue();
955 }
956 } else {
957 if (dateString.contains(".")) {
958 if (dateString.charAt(2) == '.') {
959 final DateStringSpecification spec = new DateStringSpecification("dd.MM.yyyy");
960 if (spec.isSatisfiedBy(dateString)) {
961 return spec.getValue();
962 }
963 }
964 final DateStringSpecification spec = new DateStringSpecification("yyyy.MM.dd");
965 if (spec.isSatisfiedBy(dateString)) {
966 return spec.getValue();
967 }
968 } else if (dateString.contains("-")) {
969 if (dateString.charAt(2) == '-') {
970 final DateStringSpecification spec = new DateStringSpecification("dd-MM-yyyy");
971 if (spec.isSatisfiedBy(dateString)) {
972 return spec.getValue();
973 }
974 }
975 final DateStringSpecification spec = new DateStringSpecification("yyyy-MM-dd");
976 if (spec.isSatisfiedBy(dateString)) {
977 return spec.getValue();
978 }
979 } else if (dateString.contains("/")) {
980 if (dateString.charAt(2) == '/') {
981 final DateStringSpecification spec = new DateStringSpecification("dd/MM/yyyy");
982 if (spec.isSatisfiedBy(dateString)) {
983 return spec.getValue();
984 }
985 }
986 final DateStringSpecification spec = new DateStringSpecification("yyyy/MM/dd");
987 if (spec.isSatisfiedBy(dateString)) {
988 return spec.getValue();
989 }
990 }
991 }
992 throw new IllegalArgumentException("\"" + dateString + "\"" + DATE_PARSING_ERROR_MSG_ENDING);
993 }
994 }