View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.collections4.list;
18  
19  import java.util.Collection;
20  import java.util.List;
21  import java.util.ListIterator;
22  
23  import org.apache.commons.collections4.Predicate;
24  import org.apache.commons.collections4.collection.PredicatedCollection;
25  import org.apache.commons.collections4.iterators.AbstractListIteratorDecorator;
26  
27  /**
28   * Decorates another {@code List} to validate that all additions
29   * match a specified predicate.
30   * <p>
31   * This list exists to provide validation for the decorated list.
32   * It is normally created to decorate an empty list.
33   * If an object cannot be added to the list, an IllegalArgumentException is thrown.
34   * </p>
35   * <p>
36   * One usage would be to ensure that no null entries are added to the list.
37   * </p>
38   * <pre>
39   * {@code
40   * List<String> list =
41   *   PredicatedList.predicatedList(new ArrayList<String>(), PredicateUtils.notNullPredicate());
42   * }
43   * </pre>
44   * <p>
45   * This class is Serializable from Commons Collections 3.1.
46   * </p>
47   *
48   * @since 3.0
49   */
50  public class PredicatedList<E> extends PredicatedCollection<E> implements List<E> {
51  
52      /**
53       * Inner class Iterator for the PredicatedList
54       */
55      protected class PredicatedListIterator extends AbstractListIteratorDecorator<E> {
56  
57          /**
58           * Create a new predicated list iterator.
59           *
60           * @param iterator  the list iterator to decorate
61           */
62          protected PredicatedListIterator(final ListIterator<E> iterator) {
63              super(iterator);
64          }
65  
66          @Override
67          public void add(final E object) {
68              validate(object);
69              getListIterator().add(object);
70          }
71  
72          @Override
73          public void set(final E object) {
74              validate(object);
75              getListIterator().set(object);
76          }
77      }
78  
79      /** Serialization version */
80      private static final long serialVersionUID = -5722039223898659102L;
81  
82      /**
83       * Factory method to create a predicated (validating) list.
84       * <p>
85       * If there are any elements already in the list being decorated, they
86       * are validated.
87       *
88       * @param <T> the type of the elements in the list
89       * @param list  the list to decorate, must not be null
90       * @param predicate  the predicate to use for validation, must not be null
91       * @return a new predicated list
92       * @throws NullPointerException if list or predicate is null
93       * @throws IllegalArgumentException if the list contains invalid elements
94       * @since 4.0
95       */
96      public static <T> PredicatedList<T> predicatedList(final List<T> list, final Predicate<? super T> predicate) {
97          return new PredicatedList<>(list, predicate);
98      }
99  
100     /**
101      * Constructor that wraps (not copies).
102      * <p>
103      * If there are any elements already in the list being decorated, they
104      * are validated.
105      *
106      * @param list  the list to decorate, must not be null
107      * @param predicate  the predicate to use for validation, must not be null
108      * @throws NullPointerException if list or predicate is null
109      * @throws IllegalArgumentException if the list contains invalid elements
110      */
111     protected PredicatedList(final List<E> list, final Predicate<? super E> predicate) {
112         super(list, predicate);
113     }
114 
115     @Override
116     public void add(final int index, final E object) {
117         validate(object);
118         decorated().add(index, object);
119     }
120 
121     @Override
122     public boolean addAll(final int index, final Collection<? extends E> coll) {
123         for (final E aColl : coll) {
124             validate(aColl);
125         }
126         return decorated().addAll(index, coll);
127     }
128 
129     /**
130      * Gets the list being decorated.
131      *
132      * @return the decorated list
133      */
134     @Override
135     protected List<E> decorated() {
136         return (List<E>) super.decorated();
137     }
138 
139     @Override
140     public boolean equals(final Object object) {
141         return object == this || decorated().equals(object);
142     }
143 
144     @Override
145     public E get(final int index) {
146         return decorated().get(index);
147     }
148 
149     @Override
150     public int hashCode() {
151         return decorated().hashCode();
152     }
153 
154     @Override
155     public int indexOf(final Object object) {
156         return decorated().indexOf(object);
157     }
158 
159     @Override
160     public int lastIndexOf(final Object object) {
161         return decorated().lastIndexOf(object);
162     }
163 
164     @Override
165     public ListIterator<E> listIterator() {
166         return listIterator(0);
167     }
168 
169     @Override
170     public ListIterator<E> listIterator(final int i) {
171         return new PredicatedListIterator(decorated().listIterator(i));
172     }
173 
174     @Override
175     public E remove(final int index) {
176         return decorated().remove(index);
177     }
178 
179     @Override
180     public E set(final int index, final E object) {
181         validate(object);
182         return decorated().set(index, object);
183     }
184 
185     @Override
186     public List<E> subList(final int fromIndex, final int toIndex) {
187         final List<E> sub = decorated().subList(fromIndex, toIndex);
188         return new PredicatedList<>(sub, predicate);
189     }
190 
191 }