package com.revolsys.collection.iterator;
import java.util.Iterator;
import java.util.NoSuchElementException;
import javax.annotation.PreDestroy;
import com.revolsys.io.Reader;
import com.revolsys.properties.BaseObjectWithProperties;
public abstract class AbstractIterator<T> extends BaseObjectWithProperties
implements Iterator<T>, Reader<T> {
private boolean hasNext = true;
private boolean initialized;
private boolean loadNext = true;
private T object;
@Override
@PreDestroy
public final void close() {
this.hasNext = false;
this.object = null;
closeDo();
}
protected void closeDo() {
}
@Override
protected void finalize() throws Throwable {
close();
}
protected abstract T getNext() throws NoSuchElementException;
protected T getObject() {
return this.object;
}
@Override
public synchronized final boolean hasNext() {
if (this.hasNext) {
init();
if (this.loadNext) {
try {
this.object = getNext();
this.loadNext = false;
} catch (final NoSuchElementException e) {
close();
this.hasNext = false;
}
}
}
return this.hasNext;
}
public synchronized void init() {
if (!this.initialized) {
this.initialized = true;
initDo();
}
}
protected void initDo() {
}
@Override
public Iterator<T> iterator() {
return this;
}
@Override
public synchronized final T next() {
if (hasNext()) {
final T currentObject = this.object;
this.loadNext = true;
return currentObject;
} else {
throw new NoSuchElementException();
}
}
@Override
public void open() {
init();
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
protected void setLoadNext(final boolean loadNext) {
this.loadNext = loadNext;
this.hasNext = true;
}
}