View Javadoc

1   /*
2    *  Copyright 2003-2004 The Apache Software Foundation
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
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 }