/**
* Copyright (c) 2009 - 2017 Red Hat, Inc.
*
* This software is licensed to you under the GNU General Public License,
* version 2 (GPLv2). There is NO WARRANTY for this software, express or
* implied, including the implied warranties of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
* along with this software; if not, see
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
*
* Red Hat trademarks are not licensed under GPLv2. No permission is
* granted to use or replicate Red Hat trademarks that are incorporated
* in this software or its documentation.
*/
package org.candlepin.util;
import java.util.Collection;
import java.util.List;
import java.util.ListIterator;
/**
* The SetView is a pass-through collection which restricts adding elements to the backing set,
* allowing only reading and removing elements.
*
* Unlike the CollectionView, the ListView class can only be used to provides views of lists.
* However, this allows it to safely pass calls to .equals and .hashCode to its backing set.
*
* @param <E>
* The element type
*/
public class ListView<E> extends CollectionView<E> implements List<E> {
/**
* The ListViewIterator provides a restricted implementation of the ListIterator interface,
* allowing elements to be read or removed, but not added to the backing list.
* @param <E>
* The element type
*/
private static class ListViewIterator<E> implements ListIterator<E> {
protected final ListIterator<E> iterator;
public ListViewIterator(ListIterator<E> iterator) {
if (iterator == null) {
throw new IllegalArgumentException("iterator is null");
}
this.iterator = iterator;
}
/**
* Throws an UnsupportedOperationException
*
* @param element
*
* @throws UnsupportedOperationException
*/
public void add(E element) {
throw new UnsupportedOperationException();
}
/**
* {@inheritDoc}
*/
public boolean hasNext() {
return this.iterator.hasNext();
}
/**
* {@inheritDoc}
*/
public boolean hasPrevious() {
return this.iterator.hasPrevious();
}
/**
* {@inheritDoc}
*/
public E next() {
return this.iterator.next();
}
/**
* {@inheritDoc}
*/
public int nextIndex() {
return this.iterator.nextIndex();
}
/**
* {@inheritDoc}
*/
public E previous() {
return this.iterator.previous();
}
/**
* {@inheritDoc}
*/
public int previousIndex() {
return this.iterator.previousIndex();
}
/**
* {@inheritDoc}
*/
public void remove() {
this.iterator.remove();
}
/**
* Throws an UnsupportedOperationException
*
* @param element
*
* @throws UnsupportedOperationException
*/
public void set(E element) {
throw new UnsupportedOperationException();
}
}
/**
* Creates a new ListView instance backed by the provided list.
*
* @param list
* The list to use as the backing list
*
* @throws IllegalArgumentException
* if the provided list is null
*/
public ListView(List<E> list) {
super(list);
}
/**
* Throws an UnsupportedOperationException
*
* @param index
* @param element
*
* @throws UnsupportedOperationException
*/
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
/**
* Throws an UnsupportedOperationException
*
* @param index
* @param collection
*
* @throws UnsupportedOperationException
*
* @return boolean
*/
public boolean addAll(int index, Collection<? extends E> collection) {
throw new UnsupportedOperationException();
}
/**
* {@inheritDoc}
*/
public boolean equals(Object obj) {
return this.collection.equals(obj);
}
/**
* {@inheritDoc}
*/
public E get(int index) {
return ((List<E>) this.collection).get(index);
}
/**
* {@inheritDoc}
*/
public int hashCode() {
return this.collection.hashCode();
}
/**
* {@inheritDoc}
*/
public int indexOf(Object obj) {
return ((List<E>) this.collection).indexOf(obj);
}
/**
* {@inheritDoc}
*/
public int lastIndexOf(Object obj) {
return ((List<E>) this.collection).lastIndexOf(obj);
}
/**
* {@inheritDoc}
*/
public ListIterator<E> listIterator() {
return new ListViewIterator<E>(((List<E>) this.collection).listIterator());
}
/**
* {@inheritDoc}
*/
public ListIterator<E> listIterator(int index) {
return new ListViewIterator<E>(((List<E>) this.collection).listIterator(index));
}
/**
* {@inheritDoc}
*/
public E remove(int index) {
return ((List<E>) this.collection).remove(index);
}
public E set(int index, E element) {
throw new UnsupportedOperationException();
}
/**
* Returns a view of the portion of this list between the specified fromIndex, inclusive, and
* toIndex, exclusive (if fromIndex and toIndex are equal, the returned list is empty). The
* returned list is backed by this list, so non-structural changes in the returned list are
* reflected in this list, and vice-versa. The returned list supports all of the optional list
* operations supported by this list.
*
* The list returned by this method will inherit the same write restrictions present on this
* list. Reads and removals are allowed, but any addition will result in an
* UnsupportedOperationException
*
* @param fromIndex
* low endpoint (inclusive) of the subList
*
* @param toIndex
* high endpoint (exclusive) of the subList
*
* @throws IndexOutOfBoundsException
* for an illegal endpoint index value (fromIndex < 0 || toIndex > size || fromIndex > toIndex)
*
* @return
* a view of the specified range within this list
*/
public List<E> subList(int fromIndex, int toIndex) {
return new ListView<E>(((List<E>) this.collection).subList(fromIndex, toIndex));
}
}