/*
* This file is part of the Wayback archival access software
* (http://archive-access.sourceforge.net/projects/wayback/).
*
* Licensed to the Internet Archive (IA) by one or more individual
* contributors.
*
* The IA licenses this file to You 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 org.archive.wayback.util;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.logging.Logger;
import org.archive.util.iterator.CloseableIterator;
/**
* Composite of multiple Iterators that returns the next from a series of
* all component Iterators based on Comparator constructor argument.
*
* @author brad
* @version $Date$, $Revision$
* @param <E>
*/
public class CompositeSortedIterator<E> implements CloseableIterator<E> {
private final static Logger LOGGER = Logger.getLogger(CompositeSortedIterator.class.getName());
private ArrayList<PeekableIterator<E>> components;
private E next;
private Comparator<E> comparator;
/**
* @param comparator Comparator to use for sorting order
*/
public CompositeSortedIterator(Comparator<E> comparator) {
this.comparator = comparator;
components = new ArrayList<PeekableIterator<E>>();
next = null;
}
/**
* @param itr Iterator which is a component of this composite
*/
public void addComponent(Iterator<E> itr) {
components.add(new PeekableIterator<E>(itr));
}
/* (non-Javadoc)
* @see java.util.Iterator#hasNext()
*/
public boolean hasNext() {
if(next != null) {
return true;
}
// find lowest next:
PeekableIterator<E> nextSource = null;
for(int i = 0; i < components.size(); i++) {
PeekableIterator<E> pi = components.get(i);
if(pi.hasNext()) {
E piNext = pi.peekNext();
if((next == null) || (comparator.compare(next,piNext) > 0)) {
nextSource = pi;
next = piNext;
}
}
}
if(nextSource != null) {
nextSource.next();
}
return next != null;
}
/* (non-Javadoc)
* @see java.util.Iterator#next()
*/
public E next() {
if(!hasNext()) {
throw new NoSuchElementException();
}
E retObject = next;
next = null;
return retObject;
}
/* (non-Javadoc)
* @see java.util.Iterator#remove()
*/
public void remove() {
throw new UnsupportedOperationException();
}
/* (non-Javadoc)
* @see org.archive.wayback.util.Cleanable#clean()
*/
public void close() throws IOException {
for(int i = 0; i < components.size(); i++) {
PeekableIterator<E> pi = components.get(i);
// Catch exception so that we can still close others
try {
pi.close();
} catch (IOException io) {
LOGGER.warning(io.toString());
}
}
}
}