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.collections.list;
18  
19  import org.apache.commons.collections.Predicate;
20  import org.apache.commons.collections.collection.PredicatedCollection;
21  import org.apache.commons.collections.iterators.AbstractListIteratorDecorator;
22  
23  import java.util.Collection;
24  import java.util.List;
25  import java.util.ListIterator;
26  
27  /**
28   * Decorates another <code>List</code> 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   * One usage would be to ensure that no null entries are added to the list.
36   * <pre>List list = PredicatedList.decorate(new ArrayList(), NotNullPredicate.INSTANCE);</pre>
37   * <p>
38   * This class is Serializable from Commons Collections 3.1.
39   *
40   * @since 3.0
41   * @version $Id: PredicatedList.java 1429905 2013-01-07 17:15:14Z ggregory $
42   */
43  public class PredicatedList<E> extends PredicatedCollection<E> implements List<E> {
44  
45      /** Serialization version */
46      private static final long serialVersionUID = -5722039223898659102L;
47  
48      /**
49       * Factory method to create a predicated (validating) list.
50       * <p>
51       * If there are any elements already in the list being decorated, they
52       * are validated.
53       * 
54       * @param <T> the type of the elements in the list
55       * @param list  the list to decorate, must not be null
56       * @param predicate  the predicate to use for validation, must not be null
57       * @return a new predicated list
58       * @throws IllegalArgumentException if list or predicate is null
59       * @throws IllegalArgumentException if the list contains invalid elements
60       */
61      public static <T> PredicatedList<T> predicatedList(final List<T> list, final Predicate<? super T> predicate) {
62          return new PredicatedList<T>(list, predicate);
63      }
64  
65      //-----------------------------------------------------------------------
66      /**
67       * Constructor that wraps (not copies).
68       * <p>
69       * If there are any elements already in the list being decorated, they
70       * are validated.
71       * 
72       * @param list  the list to decorate, must not be null
73       * @param predicate  the predicate to use for validation, must not be null
74       * @throws IllegalArgumentException if list or predicate is null
75       * @throws IllegalArgumentException if the list contains invalid elements
76       */
77      protected PredicatedList(final List<E> list, final Predicate<? super E> predicate) {
78          super(list, predicate);
79      }
80  
81      /**
82       * Gets the list being decorated.
83       * 
84       * @return the decorated list
85       */
86      @Override
87      protected List<E> decorated() {
88          return (List<E>) super.decorated();
89      }
90  
91      //-----------------------------------------------------------------------
92      
93      public E get(final int index) {
94          return decorated().get(index);
95      }
96  
97      public int indexOf(final Object object) {
98          return decorated().indexOf(object);
99      }
100 
101     public int lastIndexOf(final Object object) {
102         return decorated().lastIndexOf(object);
103     }
104 
105     public E remove(final int index) {
106         return decorated().remove(index);
107     }
108 
109     //-----------------------------------------------------------------------
110     
111     public void add(final int index, final E object) {
112         validate(object);
113         decorated().add(index, object);
114     }
115 
116     public boolean addAll(final int index, final Collection<? extends E> coll) {
117         for (final E aColl : coll) {
118             validate(aColl);
119         }
120         return decorated().addAll(index, coll);
121     }
122 
123     public ListIterator<E> listIterator() {
124         return listIterator(0);
125     }
126 
127     public ListIterator<E> listIterator(final int i) {
128         return new PredicatedListIterator(decorated().listIterator(i));
129     }
130 
131     public E set(final int index, final E object) {
132         validate(object);
133         return decorated().set(index, object);
134     }
135 
136     public List<E> subList(final int fromIndex, final int toIndex) {
137         final List<E> sub = decorated().subList(fromIndex, toIndex);
138         return new PredicatedList<E>(sub, predicate);
139     }
140 
141     /**
142      * Inner class Iterator for the PredicatedList
143      */
144     protected class PredicatedListIterator extends AbstractListIteratorDecorator<E> {
145         
146         /**
147          * Create a new predicated list iterator.
148          * 
149          * @param iterator  the list iterator to decorate
150          */
151         protected PredicatedListIterator(final ListIterator<E> iterator) {
152             super(iterator);
153         }
154         
155         @Override
156         public void add(final E object) {
157             validate(object);
158             iterator.add(object);
159         }
160         
161         @Override
162         public void set(final E object) {
163             validate(object);
164             iterator.set(object);
165         }
166     }
167 
168 }