package org.archive.wayback.util.iterator; import java.io.BufferedReader; import java.io.IOException; import java.util.Comparator; import java.util.Iterator; import java.util.NoSuchElementException; public abstract class AbstractPeekableIterator<E> implements IPeekableIterator<E> { private E cachedNext = null; private boolean done = false; // returns next E, or null if hasNext() would return false; public abstract E getNextInner(); public boolean hasNext() { if(cachedNext != null) { return true; } if(done) { return false; } cachedNext = getNextInner(); return (cachedNext != null); } public E next() { if(cachedNext == null) { if(!hasNext()) { throw new NoSuchElementException("Call hasNext!"); } } E tmp = cachedNext; cachedNext = null; return tmp; } public void remove() { throw new UnsupportedOperationException("No remove"); } public E peek() { if(cachedNext == null) { if(!hasNext()) { throw new NoSuchElementException("Call hasNext!"); } } return cachedNext; } public static <T> IPeekableIterator<T> wrap(Iterator<T> itr) { return new IteratorWrappedPeekableIterator<T>(itr); } public static IPeekableIterator<String> wrapReader(BufferedReader reader) { return new BufferedReaderPeekableIterator(reader); } private static class IteratorWrappedPeekableIterator<C> extends AbstractPeekableIterator<C> { private Iterator<C> wrapped = null; public IteratorWrappedPeekableIterator(Iterator<C> wrapped) { this.wrapped = wrapped; } @Override public C getNextInner() { C next = null; if(wrapped != null) { if(wrapped.hasNext()) { next = wrapped.next(); } } return next; } } private static class BufferedReaderPeekableIterator extends AbstractPeekableIterator<String> { private BufferedReader reader = null; public BufferedReaderPeekableIterator(BufferedReader reader) { this.reader = reader; } @Override public String getNextInner() { String next = null; if(reader != null) { try { next = reader.readLine(); } catch (IOException e) { e.printStackTrace(); } } return next; } } }