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 *      https://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 java.util.Collection;
020import java.util.Iterator;
021import java.util.List;
022import java.util.ListIterator;
023import java.util.function.Predicate;
024
025import org.apache.commons.collections4.BoundedCollection;
026import org.apache.commons.collections4.iterators.AbstractListIteratorDecorator;
027import org.apache.commons.collections4.iterators.UnmodifiableIterator;
028
029/**
030 * Decorates another {@code List} to fix the size preventing add/remove.
031 * <p>
032 * The add, remove, clear and retain operations are unsupported.
033 * The set method is allowed (as it doesn't change the list size).
034 * </p>
035 * <p>
036 * NOTE:
037 * Modifying the decorated list directly would results in influencing the outcome
038 * of method calls on this object. For example, the bounds of this list would reflect
039 * a newly added object to the underlying list.
040 * </p>
041 * <p>
042 * This class is Serializable from Commons Collections 3.1.
043 * </p>
044 *
045 * @param <E> The type of elements in this collection
046 * @since 3.0
047 */
048public class FixedSizeList<E>
049        extends AbstractSerializableListDecorator<E>
050        implements BoundedCollection<E> {
051
052    /**
053     * List iterator that only permits changes via set()
054     */
055    private final class FixedSizeListIterator extends AbstractListIteratorDecorator<E> {
056        protected FixedSizeListIterator(final ListIterator<E> iterator) {
057            super(iterator);
058        }
059        @Override
060        public void add(final Object object) {
061            throw unsupportedOperationException();
062        }
063        @Override
064        public void remove() {
065            throw unsupportedOperationException();
066        }
067    }
068
069    /** Serialization version */
070    private static final long serialVersionUID = -2218010673611160319L;
071
072    /**
073     * Factory method to create a fixed size list.
074     *
075     * @param <E> The type of the elements in the list
076     * @param list  The list to decorate, must not be null
077     * @return A new fixed size list
078     * @throws NullPointerException if list is null
079     * @since 4.0
080     */
081    public static <E> FixedSizeList<E> fixedSizeList(final List<E> list) {
082        return new FixedSizeList<>(list);
083    }
084
085    /**
086     * Always throws {@link UnsupportedOperationException}.
087     *
088     * @throws UnsupportedOperationException Always thrown.
089     */
090    private static UnsupportedOperationException unsupportedOperationException() {
091        return new UnsupportedOperationException("List is fixed size");
092    }
093
094    /**
095     * Constructor that wraps (not copies).
096     *
097     * @param list  The list to decorate, must not be null
098     * @throws NullPointerException if list is null
099     */
100    protected FixedSizeList(final List<E> list) {
101        super(list);
102    }
103
104    @Override
105    public boolean add(final E object) {
106        throw unsupportedOperationException();
107    }
108
109    @Override
110    public void add(final int index, final E object) {
111        throw unsupportedOperationException();
112    }
113
114    @Override
115    public boolean addAll(final Collection<? extends E> coll) {
116        throw unsupportedOperationException();
117    }
118
119    @Override
120    public boolean addAll(final int index, final Collection<? extends E> coll) {
121        throw unsupportedOperationException();
122    }
123
124    @Override
125    public void clear() {
126        throw unsupportedOperationException();
127    }
128
129    @Override
130    public E get(final int index) {
131        return decorated().get(index);
132    }
133
134    @Override
135    public int indexOf(final Object object) {
136        return decorated().indexOf(object);
137    }
138
139    @Override
140    public boolean isFull() {
141        return true;
142    }
143
144    @Override
145    public Iterator<E> iterator() {
146        return UnmodifiableIterator.unmodifiableIterator(decorated().iterator());
147    }
148
149    @Override
150    public int lastIndexOf(final Object object) {
151        return decorated().lastIndexOf(object);
152    }
153
154    @Override
155    public ListIterator<E> listIterator() {
156        return new FixedSizeListIterator(decorated().listIterator(0));
157    }
158
159    @Override
160    public ListIterator<E> listIterator(final int index) {
161        return new FixedSizeListIterator(decorated().listIterator(index));
162    }
163
164    @Override
165    public int maxSize() {
166        return size();
167    }
168
169    @Override
170    public E remove(final int index) {
171        throw unsupportedOperationException();
172    }
173
174    @Override
175    public boolean remove(final Object object) {
176        throw unsupportedOperationException();
177    }
178
179    @Override
180    public boolean removeAll(final Collection<?> coll) {
181        throw unsupportedOperationException();
182    }
183
184    /**
185     * @since 4.4
186     */
187    @Override
188    public boolean removeIf(final Predicate<? super E> filter) {
189        throw unsupportedOperationException();
190    }
191
192    @Override
193    public boolean retainAll(final Collection<?> coll) {
194        throw unsupportedOperationException();
195    }
196
197    @Override
198    public E set(final int index, final E object) {
199        return decorated().set(index, object);
200    }
201
202    @Override
203    public List<E> subList(final int fromIndex, final int toIndex) {
204        final List<E> sub = decorated().subList(fromIndex, toIndex);
205        return new FixedSizeList<>(sub);
206    }
207
208}