/*
Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved.
Contact:
SYSTAP, LLC DBA Blazegraph
2501 Calvert ST NW #106
Washington, DC 20008
licenses@blazegraph.com
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Created on Aug 7, 2008
*/
package com.bigdata.striterator;
import java.lang.reflect.Method;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Set;
import com.bigdata.service.ndx.PartitionedTupleIterator;
import cutthecrap.utils.striterators.ICloseable;
/**
* Streaming iterator pattern.
*
* @author <a href="mailto:thompsonbry@users.sourceforge.net">Bryan Thompson</a>
* @version $Id$
* @param <I>
* @param <E>
*/
public class Striterator<I extends Iterator<E>, E> implements IStriterator<I,E> {
/**
* Set to the source iterator by the ctor. This exists against the
* possibility that some patterns will require access to the source iterator
* as well. One example is the partitioned tuple iterator which needs to
* know the key for last tuple visited by the source iterator in order to
* advance the aggregate iterator efficiently to the next chunk without
* re-scanning tuples.
*
* @todo backport this concept into the {@link PartitionedTupleIterator}
*/
protected final I realSource;
/**
* Set to the source iterator by the ctor and then replaced each time we
* wrap the source iterator with another {@link IFilter}. This is always
* the iterator that realizes the stacked filter semantics.
*/
protected I src;
/**
* @param src The source iterator.
*/
public Striterator(final I src) {
if (src == null)
throw new IllegalArgumentException();
this.realSource = this.src = src;
}
/**
* Wraps the enumeration as an iterator.
*
* <strong>The constructor must be overridden for derived classes that
* specialize the type of the iterator.</strong>
*
* @param srcEnum
* The source enumeration.
*/
@SuppressWarnings("unchecked")
public Striterator(final Enumeration<E> srcEnum) {
this((I)new Iterator<E>() {
@Override
public boolean hasNext() {
return srcEnum.hasMoreElements();
}
@Override
public E next() {
return srcEnum.nextElement();
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
});
}
@Override
@SuppressWarnings("unchecked")
public IStriterator<I, E> addFilter(final IFilter<I, ?, E> filter) {
src = (I)filter.filter((I) src);
return this;
}
@Override
public IStriterator<I, E> addInstanceOfFilter(final Class<E> cls) {
return addFilter(new Filter<I, E>(cls) {
private static final long serialVersionUID = 1L;
@Override
protected boolean isValid(E e) {
return cls.isInstance(e);
}
});
}
@Override
public IStriterator<I, E> append(final I src) {
return addFilter(new Appender<I, E>(src));
}
/**
* Exclude elements found in the set.
*
* @param set
* The set of elements to be excluded.
*
* @return The filtered iterator.
*/
public IStriterator<I,E> exclude(final Set<E> set) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
// @todo use temporary store for scalable set to filter the instances.
public IStriterator<I,E> makeUnique() {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
public IStriterator<I,E> map(final Object client, final Method method) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
@Override
final public void close() {
if (src instanceof ICloseable) {
((ICloseable) src).close();
}
}
@Override
final public boolean hasMoreElements() {
return src.hasNext();
}
@Override
final public E nextElement() {
return src.next();
}
@Override
final public boolean hasNext() {
return src.hasNext();
}
@Override
final public E next() {
return src.next();
}
/**
* Unsupported operation.
* <p>
* Extreme care must be taken when implementing striterator patterns that
* support removal in order to ensure that the current iterator element is
* removed from the iteration source. In the general case, it may not be
* possible to implement {@link #remove()} for striterator patterns.
* <p>
* When the striterator is also an {@link IChunkedIterator} then
* {@link #remove()} semantics face an additional difficulty. If the source
* iterator is being consumed a {@link IChunkedIterator#nextChunk() chunk}
* at a time, then {@link #remove()} only has the semantics of removing the
* last element in the chunk.
*
* @throws UnsupportedOperationException
* For the above reasons, {@link #remove()} is NOT supported for
* chunked striterator patterns and this method will always
* throw an {@link UnsupportedOperationException}.
*/
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}