1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package net.sf.collections15.collection;
17
18 import java.util.Collection;
19
20 import net.sf.collections15.Predicate;
21
22
23 /***
24 * Decorates another <code>Collection</code> to validate that additions
25 * match a specified predicate.
26 * <p>
27 * This collection exists to provide validation for the decorated collection.
28 * It is normally created to decorate an empty collection.
29 * If an object cannot be added to the collection, an IllegalArgumentException is thrown.
30 * <p>
31 * One usage would be to ensure that no null entries are added to the collection.
32 * <pre>Collection<String> coll =
33 * PredicatedCollection.<String>decorate(new ArrayList<String>(),
34 * NotNullPredicate.<String>getInstance());</pre>
35 * <p>
36 * This class is Serializable from Commons Collections 3.1.
37 *
38 * @since Commons Collections 3.0
39 * @version $Revision: 1.2 $ $Date: 2005/05/25 21:25:25 $
40 *
41 * @author Stephen Colebourne
42 * @author Paul Jack
43 */
44 public class PredicatedCollection<E> extends AbstractSerializableCollectionDecorator<E> {
45
46 /*** Serialization version */
47 private static final long serialVersionUID = 3546923589023708721L;
48
49 /*** The predicate to use */
50 protected final Predicate<? super E> predicate;
51
52 /***
53 * Factory method to create a predicated (validating) collection.
54 * <p>
55 * If there are any elements already in the collection being decorated, they
56 * are validated.
57 *
58 * @param coll the collection to decorate, must not be null
59 * @param predicate the predicate to use for validation, must not be null
60 * @return a new predicated collection
61 * @throws IllegalArgumentException if collection or predicate is null
62 * @throws IllegalArgumentException if the collection contains invalid elements
63 */
64 public static <T> Collection<T> decorate(Collection<T> coll, Predicate<? super T> predicate) {
65 return new PredicatedCollection<T>(coll, predicate);
66 }
67
68
69 /***
70 * Constructor that wraps (not copies).
71 * <p>
72 * If there are any elements already in the collection being decorated, they
73 * are validated.
74 *
75 * @param coll the collection to decorate, must not be null
76 * @param predicate the predicate to use for validation, must not be null
77 * @throws IllegalArgumentException if collection or predicate is null
78 * @throws IllegalArgumentException if the collection contains invalid elements
79 */
80 protected PredicatedCollection(Collection<E> coll, Predicate<? super E> predicate) {
81 super(coll);
82 if (predicate == null) {
83 throw new IllegalArgumentException("Predicate must not be null");
84 }
85 this.predicate = predicate;
86 for( E object : coll ) {
87 validate(object);
88 }
89 }
90
91 /***
92 * Validates the object being added to ensure it matches the predicate.
93 * <p>
94 * The predicate itself should not throw an exception, but return false to
95 * indicate that the object cannot be added.
96 *
97 * @param object the object being added
98 * @throws IllegalArgumentException if the add is invalid
99 */
100 protected void validate(E object) {
101 if (predicate.evaluate(object) == false) {
102 throw new IllegalArgumentException("Cannot add Object '" + object + "' - Predicate rejected it");
103 }
104 }
105
106
107 /***
108 * Override to validate the object being added to ensure it matches
109 * the predicate.
110 *
111 * @param object the object being added
112 * @return the result of adding to the underlying collection
113 * @throws IllegalArgumentException if the add is invalid
114 */
115 public boolean add(E object) {
116 validate(object);
117 return getCollection().add(object);
118 }
119
120 /***
121 * Override to validate the objects being added to ensure they match
122 * the predicate. If any one fails, no update is made to the underlying
123 * collection.
124 *
125 * @param coll the collection being added
126 * @return the result of adding to the underlying collection
127 * @throws IllegalArgumentException if the add is invalid
128 */
129 public boolean addAll(Collection<? extends E> coll) {
130 for( E object : coll ) {
131 validate(object);
132 }
133 return getCollection().addAll(coll);
134 }
135
136 }