-
Notifications
You must be signed in to change notification settings - Fork 0
/
ConstrainableCollection.java
111 lines (96 loc) · 3.66 KB
/
ConstrainableCollection.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package pl.ais.commons.bean.validation.constrainable;
import pl.ais.commons.bean.validation.Constraint;
import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.stream.Collectors;
/**
* Collection of constrainable values.
*
* @author Warlock, AIS.PL
* @since 1.2.1
*/
@SuppressWarnings("PMD.AbstractNaming")
public abstract class ConstrainableCollection<T> implements Constrainable<T> {
protected final Collection<T> elements;
protected ConstrainableCollection(final T first, final T second, final T... rest) {
elements = new ArrayList<>(2 + rest.length);
elements.add(first);
elements.add(second);
elements.addAll(Arrays.asList(rest));
}
/**
* Creates and returns constrainable over collection of all given values.
*
* <p>Constrainable created by this method is satisfying some constraint if and only if all constrainable values
* enclosed by it are satisfying the constraint.
*
* @param <T> the type of constrainable values
* @param first first constrainable value
* @param second second constrainable value
* @param rest remaining constrainable values
* @return constrainable over collection of all given values
*/
public static <T> Constrainable<T> allOf(final T first, final T second, final T... rest) {
return new ConstrainableCollection<T>(first, second, rest) {
/**
* {@inheritDoc}
*/
@Override
public Boolean apply(final Constraint<?, ? super T> constraint) {
return elements.stream()
.allMatch(constraint::test);
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return elements.stream()
.map(element -> (null == element) ? "null" : "'" + element + "'")
.collect(Collectors.joining(", ", "All values of Collection composed of: [", "]"));
}
};
}
/**
* Creates and returns constrainable over any element of given collection values.
*
* <p>Constrainable created by this method is satisfying some constraint if and only if any constrainable value
* enclosed by it is satisfying the constraint.
*
* @param <T> the type of constrainable values
* @param first first constrainable value
* @param second second constrainable value
* @param rest remaining constrainable values
* @return constrainable over any element of given collection of values
*/
public static <T> Constrainable<T> anyOf(final T first, final T second, final T... rest) {
return new ConstrainableCollection<T>(first, second, rest) {
/**
* {@inheritDoc}
*/
@Override
public Boolean apply(final Constraint<?, ? super T> constraint) {
return elements.stream()
.anyMatch(constraint::test);
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return elements.stream()
.map(element -> (null == element) ? "null" : "'" + element + "'")
.collect(Collectors.joining(", ", "Any value from Collection composed of : [", "]"));
}
};
}
/**
* {@inheritDoc}
*/
@Override
public <R> R accept(@Nonnull final ConstrainableVisitor<R> visitor) {
return visitor.visit(this);
}
}