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   * @param <E> the type of the elements in the list.
49   * @since 3.0
50   */
51  public class PredicatedList<E> extends PredicatedCollection<E> implements List<E> {
52  
53      /**
54       * Inner class Iterator for the PredicatedList
55       */
56      protected class PredicatedListIterator extends AbstractListIteratorDecorator<E> {
57  
58          /**
59           * Create a new predicated list iterator.
60           *
61           * @param iterator  the list iterator to decorate
62           */
63          protected PredicatedListIterator(final ListIterator<E> iterator) {
64              super(iterator);
65          }
66  
67          @Override
68          public void add(final E object) {
69              validate(object);
70              getListIterator().add(object);
71          }
72  
73          @Override
74          public void set(final E object) {
75              validate(object);
76              getListIterator().set(object);
77          }
78      }
79  
80      /** Serialization version */
81      private static final long serialVersionUID = -5722039223898659102L;
82  
83      /**
84       * Factory method to create a predicated (validating) list.
85       * <p>
86       * If there are any elements already in the list being decorated, they
87       * are validated.
88       *
89       * @param <T> the type of the elements in the list
90       * @param list  the list to decorate, must not be null
91       * @param predicate  the predicate to use for validation, must not be null
92       * @return a new predicated list
93       * @throws NullPointerException if list or predicate is null
94       * @throws IllegalArgumentException if the list contains invalid elements
95       * @since 4.0
96       */
97      public static <T> PredicatedList<T> predicatedList(final List<T> list, final Predicate<? super T> predicate) {
98          return new PredicatedList<>(list, predicate);
99      }
100 
101     /**
102      * Constructor that wraps (not copies).
103      * <p>
104      * If there are any elements already in the list being decorated, they
105      * are validated.
106      *
107      * @param list  the list to decorate, must not be null
108      * @param predicate  the predicate to use for validation, must not be null
109      * @throws NullPointerException if list or predicate is null
110      * @throws IllegalArgumentException if the list contains invalid elements
111      */
112     protected PredicatedList(final List<E> list, final Predicate<? super E> predicate) {
113         super(list, predicate);
114     }
115 
116     @Override
117     public void add(final int index, final E object) {
118         validate(object);
119         decorated().add(index, object);
120     }
121 
122     @Override
123     public boolean addAll(final int index, final Collection<? extends E> coll) {
124         for (final E aColl : coll) {
125             validate(aColl);
126         }
127         return decorated().addAll(index, coll);
128     }
129 
130     /**
131      * Gets the list being decorated.
132      *
133      * @return the decorated list
134      */
135     @Override
136     protected List<E> decorated() {
137         return (List<E>) super.decorated();
138     }
139 
140     @Override
141     public boolean equals(final Object object) {
142         return object == this || decorated().equals(object);
143     }
144 
145     @Override
146     public E get(final int index) {
147         return decorated().get(index);
148     }
149 
150     @Override
151     public int hashCode() {
152         return decorated().hashCode();
153     }
154 
155     @Override
156     public int indexOf(final Object object) {
157         return decorated().indexOf(object);
158     }
159 
160     @Override
161     public int lastIndexOf(final Object object) {
162         return decorated().lastIndexOf(object);
163     }
164 
165     @Override
166     public ListIterator<E> listIterator() {
167         return listIterator(0);
168     }
169 
170     @Override
171     public ListIterator<E> listIterator(final int i) {
172         return new PredicatedListIterator(decorated().listIterator(i));
173     }
174 
175     @Override
176     public E remove(final int index) {
177         return decorated().remove(index);
178     }
179 
180     @Override
181     public E set(final int index, final E object) {
182         validate(object);
183         return decorated().set(index, object);
184     }
185 
186     @Override
187     public List<E> subList(final int fromIndex, final int toIndex) {
188         final List<E> sub = decorated().subList(fromIndex, toIndex);
189         return new PredicatedList<>(sub, predicate);
190     }
191 
192 }