blob: 6df6dacd5ab66c5dc1af257db6b2c1d66a6ce05b [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2010 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.metadata.expression;
import java.util.*;
import org.eclipse.equinox.p2.metadata.index.IIndexProvider;
import org.eclipse.equinox.p2.query.IQueryResult;
public class RepeatableIterator<T> implements IRepeatableIterator<T> {
private final Collection<T> values;
private final Iterator<T> iterator;
@SuppressWarnings("unchecked")
public static <T> IRepeatableIterator<T> create(Object unknown) {
if (unknown.getClass().isArray())
return create((T[]) unknown);
if (unknown instanceof Iterator<?>)
return create((Iterator<T>) unknown);
if (unknown instanceof List<?>)
return create((List<T>) unknown);
if (unknown instanceof Collection<?>)
return create((Collection<T>) unknown);
if (unknown instanceof Map<?, ?>)
return create((Set<T>) ((Map<?, ?>) unknown).entrySet());
if (unknown instanceof IQueryResult<?>)
return create((IQueryResult<T>) unknown);
if (unknown instanceof IIndexProvider<?>)
return create((IIndexProvider<T>) unknown);
throw new IllegalArgumentException("Cannot convert a " + unknown.getClass().getName() + " into an iterator"); //$NON-NLS-1$ //$NON-NLS-2$
}
public static <T> IRepeatableIterator<T> create(Iterator<T> iterator) {
return iterator instanceof IRepeatableIterator<?> ? ((IRepeatableIterator<T>) iterator).getCopy() : new RepeatableIterator<T>(iterator);
}
public static <T> IRepeatableIterator<T> create(Collection<T> values) {
return new RepeatableIterator<T>(values);
}
public static <T> IRepeatableIterator<T> create(IQueryResult<T> values) {
return new QueryResultIterator<T>(values);
}
public static <T> IRepeatableIterator<T> create(T[] values) {
return new ArrayIterator<T>(values);
}
public static <T> IRepeatableIterator<T> create(IIndexProvider<T> values) {
return new IndexProviderIterator<T>(values);
}
RepeatableIterator(Iterator<T> iterator) {
HashSet<T> v = new HashSet<T>();
while (iterator.hasNext())
v.add(iterator.next());
values = v;
this.iterator = v.iterator();
}
RepeatableIterator(Collection<T> values) {
this.values = values;
this.iterator = values.iterator();
}
public IRepeatableIterator<T> getCopy() {
return new RepeatableIterator<T>(values);
}
public boolean hasNext() {
return iterator.hasNext();
}
public T next() {
return iterator.next();
}
public void remove() {
throw new UnsupportedOperationException();
}
public Object getIteratorProvider() {
return values;
}
static class ArrayIterator<T> implements IRepeatableIterator<T> {
private final T[] array;
private int position = -1;
public ArrayIterator(T[] array) {
this.array = array;
}
public Object getIteratorProvider() {
return array;
}
public boolean hasNext() {
return position + 1 < array.length;
}
public T next() {
if (++position >= array.length)
throw new NoSuchElementException();
return array[position];
}
public void remove() {
throw new UnsupportedOperationException();
}
public IRepeatableIterator<T> getCopy() {
return new ArrayIterator<T>(array);
}
}
static class IndexProviderIterator<T> implements IRepeatableIterator<T> {
private final IIndexProvider<T> indexProvider;
private final Iterator<T> iterator;
IndexProviderIterator(IIndexProvider<T> indexProvider) {
this.iterator = indexProvider.everything();
this.indexProvider = indexProvider;
}
public IRepeatableIterator<T> getCopy() {
return new IndexProviderIterator<T>(indexProvider);
}
public Object getIteratorProvider() {
return indexProvider;
}
public boolean hasNext() {
return iterator.hasNext();
}
public T next() {
return iterator.next();
}
public void remove() {
throw new UnsupportedOperationException();
}
}
static class QueryResultIterator<T> implements IRepeatableIterator<T> {
private final IQueryResult<T> queryResult;
private final Iterator<T> iterator;
QueryResultIterator(IQueryResult<T> queryResult) {
this.queryResult = queryResult;
this.iterator = queryResult.iterator();
}
public IRepeatableIterator<T> getCopy() {
return new QueryResultIterator<T>(queryResult);
}
public Object getIteratorProvider() {
return queryResult;
}
public boolean hasNext() {
return iterator.hasNext();
}
public T next() {
return iterator.next();
}
public void remove() {
throw new UnsupportedOperationException();
}
}
}