/*
* Copyright 2003-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package jetbrains.mps.util;
import org.jetbrains.annotations.NotNull;
import java.util.Iterator;
import java.util.ListIterator;
/**
* User: shatalin
* Date: 9/12/13
*/
public abstract class AbstractSequentialList<T> extends java.util.AbstractSequentialList<T> {
private final T myFirst;
private int mySize = -1;
public AbstractSequentialList(@NotNull T first) {
myFirst = first;
}
@Override
public ListIterator<T> listIterator(int index) {
if (index < 0) {
throw new IndexOutOfBoundsException();
}
ListIterator<T> iterator = createIterator(myFirst);
for (int i = 0; i < index; i++) {
if (iterator.hasNext()) {
iterator.next();
} else {
throw new IndexOutOfBoundsException();
}
}
return iterator;
}
@Override
public int size() {
if (mySize == -1) {
mySize = 0;
for (Iterator<T> iterator = iterator(); iterator.hasNext(); mySize++) {
iterator.next();
}
}
return mySize;
}
protected abstract AbstractSequentialIterator<T> createIterator(T first);
public static abstract class AbstractSequentialIterator<T> implements ListIterator<T> {
private T myCurrent;
private T myPrev;
private int myIndex;
public AbstractSequentialIterator(T node) {
assert node != null;
myCurrent = node;
myPrev = null;
myIndex = 0;
}
protected abstract T getNext(T node);
protected abstract T getPrev(T node);
protected T getCurrent() {
return myCurrent;
}
protected void setCurrent(T current) {
myCurrent = current;
}
protected T getPrev() {
return myPrev;
}
protected void setPrev(T prev) {
myPrev = prev;
}
@Override
public boolean hasNext() {
return getCurrent() != null;
}
@Override
public T next() {
T result = getCurrent();
if (result == null) {
//TODO: throw new NoSuchElementException();
return null;
}
setPrev(result);
myIndex++;
setCurrent(getNext(result));
return result;
}
@Override
public boolean hasPrevious() {
return getPrev() != null;
}
@Override
public T previous() {
T result = getPrev();
if (result == null) {
//TODO: throw new NoSuchElementException();
return null;
}
setCurrent(result);
myIndex--;
setPrev(myIndex == 0 ? null : getPrev(result));
return result;
}
@Override
public int nextIndex() {
return myIndex;
}
@Override
public int previousIndex() {
return myIndex - 1;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
@Override
public void set(T t) {
throw new UnsupportedOperationException();
}
@Override
public void add(T t) {
throw new UnsupportedOperationException();
}
}
}