001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.collections4.list; 018 019import org.apache.commons.collections4.Predicate; 020import org.apache.commons.collections4.collection.PredicatedCollection; 021import org.apache.commons.collections4.iterators.AbstractListIteratorDecorator; 022 023import java.util.Collection; 024import java.util.List; 025import java.util.ListIterator; 026 027/** 028 * Decorates another <code>List</code> to validate that all additions 029 * match a specified predicate. 030 * <p> 031 * This list exists to provide validation for the decorated list. 032 * It is normally created to decorate an empty list. 033 * If an object cannot be added to the list, an IllegalArgumentException is thrown. 034 * <p> 035 * One usage would be to ensure that no null entries are added to the list. 036 * <pre>List list = PredicatedList.decorate(new ArrayList(), NotNullPredicate.INSTANCE);</pre> 037 * <p> 038 * This class is Serializable from Commons Collections 3.1. 039 * 040 * @since 3.0 041 * @version $Id: PredicatedList.html 972421 2015-11-14 20:00:04Z tn $ 042 */ 043public class PredicatedList<E> extends PredicatedCollection<E> implements List<E> { 044 045 /** Serialization version */ 046 private static final long serialVersionUID = -5722039223898659102L; 047 048 /** 049 * Factory method to create a predicated (validating) list. 050 * <p> 051 * If there are any elements already in the list being decorated, they 052 * are validated. 053 * 054 * @param <T> the type of the elements in the list 055 * @param list the list to decorate, must not be null 056 * @param predicate the predicate to use for validation, must not be null 057 * @return a new predicated list 058 * @throws IllegalArgumentException if list or predicate is null 059 * @throws IllegalArgumentException if the list contains invalid elements 060 * @since 4.0 061 */ 062 public static <T> PredicatedList<T> predicatedList(final List<T> list, final Predicate<? super T> predicate) { 063 return new PredicatedList<T>(list, predicate); 064 } 065 066 //----------------------------------------------------------------------- 067 /** 068 * Constructor that wraps (not copies). 069 * <p> 070 * If there are any elements already in the list being decorated, they 071 * are validated. 072 * 073 * @param list the list to decorate, must not be null 074 * @param predicate the predicate to use for validation, must not be null 075 * @throws IllegalArgumentException if list or predicate is null 076 * @throws IllegalArgumentException if the list contains invalid elements 077 */ 078 protected PredicatedList(final List<E> list, final Predicate<? super E> predicate) { 079 super(list, predicate); 080 } 081 082 /** 083 * Gets the list being decorated. 084 * 085 * @return the decorated list 086 */ 087 @Override 088 protected List<E> decorated() { 089 return (List<E>) super.decorated(); 090 } 091 092 //----------------------------------------------------------------------- 093 094 public E get(final int index) { 095 return decorated().get(index); 096 } 097 098 public int indexOf(final Object object) { 099 return decorated().indexOf(object); 100 } 101 102 public int lastIndexOf(final Object object) { 103 return decorated().lastIndexOf(object); 104 } 105 106 public E remove(final int index) { 107 return decorated().remove(index); 108 } 109 110 //----------------------------------------------------------------------- 111 112 public void add(final int index, final E object) { 113 validate(object); 114 decorated().add(index, object); 115 } 116 117 public boolean addAll(final int index, final Collection<? extends E> coll) { 118 for (final E aColl : coll) { 119 validate(aColl); 120 } 121 return decorated().addAll(index, coll); 122 } 123 124 public ListIterator<E> listIterator() { 125 return listIterator(0); 126 } 127 128 public ListIterator<E> listIterator(final int i) { 129 return new PredicatedListIterator(decorated().listIterator(i)); 130 } 131 132 public E set(final int index, final E object) { 133 validate(object); 134 return decorated().set(index, object); 135 } 136 137 public List<E> subList(final int fromIndex, final int toIndex) { 138 final List<E> sub = decorated().subList(fromIndex, toIndex); 139 return new PredicatedList<E>(sub, predicate); 140 } 141 142 /** 143 * Inner class Iterator for the PredicatedList 144 */ 145 protected class PredicatedListIterator extends AbstractListIteratorDecorator<E> { 146 147 /** 148 * Create a new predicated list iterator. 149 * 150 * @param iterator the list iterator to decorate 151 */ 152 protected PredicatedListIterator(final ListIterator<E> iterator) { 153 super(iterator); 154 } 155 156 @Override 157 public void add(final E object) { 158 validate(object); 159 getListIterator().add(object); 160 } 161 162 @Override 163 public void set(final E object) { 164 validate(object); 165 getListIterator().set(object); 166 } 167 } 168 169}