package net.glowstone.util.collection; import java.util.List; import java.util.ListIterator; import java.util.NoSuchElementException; /** * An Iterator which delegates in other iterators. */ public class SuperListIterator<E> implements ListIterator<E> { private final ListIterator<List<E>> parentIterator; private ListIterator<E> childIterator; private int index; public SuperListIterator(List<List<E>> parents) { this(parents.listIterator()); } public SuperListIterator(ListIterator<List<E>> parentIterator) { this.parentIterator = parentIterator; } public SuperListIterator(List<List<E>> parents, int index) { this(parents); this.index = index; while (parentIterator.hasNext()) { List<E> child = parentIterator.next(); int childSize = child.size(); if (index <= childSize) { childIterator = child.listIterator(index); return; } index -= childSize; } throw new IndexOutOfBoundsException(); } @Override public boolean hasNext() { while (childIterator == null || !childIterator.hasNext()) { if (parentIterator.hasNext()) { childIterator = parentIterator.next().listIterator(); } else { return false; } } return true; } private void checkNext() { if (!hasNext()) { throw new NoSuchElementException(); } } @Override public int nextIndex() { checkNext(); return index + 1; } @Override public E next() { checkNext(); E obj = childIterator.next(); index++; return obj; } @Override public boolean hasPrevious() { while (childIterator == null || !childIterator.hasPrevious()) { if (parentIterator.hasPrevious()) { List<E> child = parentIterator.previous(); childIterator = child.listIterator(child.size()); } else { return false; } } return true; } private void checkPrevious() { if (!hasPrevious()) { throw new NoSuchElementException(); } } @Override public int previousIndex() { checkPrevious(); return index - 1; } @Override public E previous() { checkPrevious(); E obj = childIterator.previous(); index--; return obj; } @Override public void add(E object) { if (childIterator == null) { throw new IllegalStateException("next() must be called before using add()"); } childIterator.add(object); index++; } @Override public void remove() { if (childIterator == null) { throw new IllegalStateException("next() must be called before using remove()"); } childIterator.remove(); } @Override public void set(E object) { if (childIterator == null) { throw new IllegalStateException("next() must be called before using set(E)"); } childIterator.set(object); } }