blob: e1419e9a9132f10cc0499c006781c78270db6ce0 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009 Cloudsmith Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Cloudsmith Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.equinox.internal.p2.ql;
import java.util.*;
import org.eclipse.equinox.internal.provisional.p2.metadata.query.Collector;
public class RepeatableIterator implements IRepeatableIterator {
private final List values;
private int position = -1;
public static IRepeatableIterator create(Object unknown) {
if (unknown.getClass().isArray())
return create((Object[]) unknown);
if (unknown instanceof Iterator)
return create((Iterator) unknown);
if (unknown instanceof List)
return create((List) unknown);
if (unknown instanceof Collection)
return create((Collection) unknown);
if (unknown instanceof Map)
return create(((Map) unknown).entrySet());
if (unknown instanceof Collector)
return create((Collector) unknown);
throw new IllegalArgumentException("Cannot convert a " + unknown.getClass().getName() + " into an iterator"); //$NON-NLS-1$ //$NON-NLS-2$
}
public static IRepeatableIterator create(Iterator iterator) {
return iterator instanceof IRepeatableIterator ? ((IRepeatableIterator) iterator).getCopy() : new ElementRetainingIterator(iterator);
}
public static IRepeatableIterator create(List values) {
return new RepeatableIterator(values);
}
public static IRepeatableIterator create(Collection values) {
return new CollectionIterator(values);
}
public static IRepeatableIterator create(Collector values) {
return new CollectorIterator(values);
}
public static IRepeatableIterator create(Object[] values) {
return new ArrayIterator(values);
}
RepeatableIterator(List values) {
this.values = values;
}
public IRepeatableIterator getCopy() {
return new RepeatableIterator(values);
}
public boolean hasNext() {
return position + 1 < values.size();
}
public Object next() {
if (++position == values.size()) {
--position;
throw new NoSuchElementException();
}
return values.get(position);
}
public void remove() {
throw new UnsupportedOperationException();
}
public Object getIteratorProvider() {
return values;
}
void setPosition(int position) {
this.position = position;
}
List getValues() {
return values;
}
static class ArrayIterator implements IRepeatableIterator {
private final Object[] array;
private int position = -1;
public ArrayIterator(Object[] array) {
this.array = array;
}
public Object getIteratorProvider() {
return array;
}
public boolean hasNext() {
return position + 1 < array.length;
}
public Object next() {
if (++position >= array.length)
throw new NoSuchElementException();
return array[position];
}
public void remove() {
throw new UnsupportedOperationException();
}
public IRepeatableIterator getCopy() {
return new ArrayIterator(array);
}
}
static class CollectionIterator implements IRepeatableIterator {
private final Collection collection;
private final Iterator iterator;
CollectionIterator(Collection collection) {
this.collection = collection;
this.iterator = collection.iterator();
}
public IRepeatableIterator getCopy() {
return new CollectionIterator(collection);
}
public Object getIteratorProvider() {
return collection;
}
public boolean hasNext() {
return iterator.hasNext();
}
public Object next() {
return iterator.next();
}
public void remove() {
throw new UnsupportedOperationException();
}
}
static class CollectorIterator implements IRepeatableIterator {
private final Collector collector;
private final Iterator iterator;
CollectorIterator(Collector collector) {
this.collector = collector;
this.iterator = collector.iterator();
}
public IRepeatableIterator getCopy() {
return new CollectorIterator(collector);
}
public Object getIteratorProvider() {
return collector;
}
public boolean hasNext() {
return iterator.hasNext();
}
public Object next() {
return iterator.next();
}
public void remove() {
throw new UnsupportedOperationException();
}
}
static class ElementRetainingIterator extends RepeatableIterator {
private Iterator innerIterator;
ElementRetainingIterator(Iterator iterator) {
super(new ArrayList());
innerIterator = iterator;
}
public synchronized boolean hasNext() {
if (innerIterator != null) {
if (innerIterator.hasNext())
return true;
innerIterator = null;
setPosition(getValues().size());
}
return super.hasNext();
}
public synchronized Object next() {
if (innerIterator != null) {
Object val = innerIterator.next();
getValues().add(val);
return val;
}
return super.next();
}
public synchronized IRepeatableIterator getCopy() {
// If the current iterator still exists, we must exhaust it first
//
exhaustInnerIterator();
return super.getCopy();
}
public synchronized Object getIteratorProvider() {
exhaustInnerIterator();
return super.getIteratorProvider();
}
private void exhaustInnerIterator() {
if (innerIterator != null) {
List values = getValues();
int savePos = values.size() - 1;
while (innerIterator.hasNext())
values.add(innerIterator.next());
innerIterator = null;
setPosition(savePos);
}
}
}
}