blob: 8b45db23fc0014de5f5582eacb7643c57f217573 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011, 2015 Oracle. 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:
* Oracle - initial API and implementation
******************************************************************************/
package org.eclipse.jpt.common.utility.internal.iterable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import org.eclipse.jpt.common.utility.closure.Closure;
import org.eclipse.jpt.common.utility.closure.InterruptibleClosure;
import org.eclipse.jpt.common.utility.exception.ExceptionHandler;
import org.eclipse.jpt.common.utility.internal.closure.DisabledClosure;
import org.eclipse.jpt.common.utility.internal.collection.CollectionTools;
import org.eclipse.jpt.common.utility.internal.collection.HashBag;
import org.eclipse.jpt.common.utility.internal.collection.ListTools;
import org.eclipse.jpt.common.utility.internal.iterator.CloneListIterator;
import org.eclipse.jpt.common.utility.internal.iterator.IteratorTools;
import org.eclipse.jpt.common.utility.internal.predicate.PredicateTools;
import org.eclipse.jpt.common.utility.iterable.ListIterable;
import org.eclipse.jpt.common.utility.predicate.Predicate;
import org.eclipse.jpt.common.utility.queue.Queue;
import org.eclipse.jpt.common.utility.stack.Stack;
import org.eclipse.jpt.common.utility.transformer.Transformer;
/**
* {@link Iterable} utility methods.
* @see org.eclipse.jpt.common.utility.internal.ArrayTools
* @see CollectionTools
* @see IteratorTools
* @see ListTools
*/
public final class IterableTools {
/**
* Return a bag corresponding to the specified iterable.
*/
public static <E> HashBag<E> bag(Iterable<? extends E> iterable) {
return IteratorTools.bag(iterable.iterator());
}
/**
* Return a bag corresponding to the specified iterable.
* The specified iterable size is a performance hint.
*/
public static <E> HashBag<E> bag(Iterable<? extends E> iterable, int iterableSize) {
return IteratorTools.bag(iterable.iterator(), iterableSize);
}
/**
* Return a hash bag corresponding to the specified iterable.
*/
public static <E> HashBag<E> hashBag(Iterable<? extends E> iterable) {
return IteratorTools.hashBag(iterable.iterator());
}
/**
* Return a hash bag corresponding to the specified iterable.
* The specified iterable size is a performance hint.
*/
public static <E> HashBag<E> hashBag(Iterable<? extends E> iterable, int iterableSize) {
return IteratorTools.hashBag(iterable.iterator(), iterableSize);
}
/**
* Return whether the specified iterable is <code>null</code>
* or, if it is not <code>null</code>, contains a <code>null</code>.
* Convenient for argument checking.
*/
public static boolean isOrContainsNull(Iterable<?> iterable) {
return (iterable == null) || contains(iterable, null);
}
/**
* Return whether the specified iterable contains a <code>null</code>.
*/
public static boolean containsNull(Iterable<?> iterable) {
return IteratorTools.containsNull(iterable.iterator());
}
/**
* Return whether the specified iterable contains the
* specified element.
*/
public static boolean contains(Iterable<?> iterable, Object value) {
return IteratorTools.contains(iterable.iterator(), value);
}
/**
* Return the number of times the specified element occurs in the specified
* iterable.
*/
public static int count(Iterable<?> iterable, Object value) {
return IteratorTools.count(iterable.iterator(), value);
}
/**
* Return the number of times the specified predicate evaluates to
* <code>false</code> with the elements in the specified iterable.
*/
public static <E> int countFalse(Iterable<? extends E> iterable, Predicate<? super E> predicate) {
return IteratorTools.countFalse(iterable.iterator(), predicate);
}
/**
* Return the number of times the specified predicate evaluates to
* <code>true</code> with the elements in the specified iterable.
*/
public static <E> int countTrue(Iterable<? extends E> iterable, Predicate<? super E> predicate) {
return IteratorTools.countTrue(iterable.iterator(), predicate);
}
/**
* Return whether the specified iterable contains all of the
* elements in the specified collection.
*/
public static boolean containsAll(Iterable<?> iterable, Collection<?> collection) {
return IteratorTools.containsAll(iterable.iterator(), collection);
}
/**
* Return whether the specified iterable contains all of the
* elements in the specified collection.
* The specified iterable size is a performance hint.
*/
public static boolean containsAll(Iterable<?> iterable, int iterableSize, Collection<?> collection) {
return IteratorTools.containsAll(iterable.iterator(), iterableSize, collection);
}
/**
* Return whether the specified iterable 1 contains all of the
* elements in the specified iterable 2.
*/
public static boolean containsAll(Iterable<?> iterable1, Iterable<?> iterable2) {
return IteratorTools.containsAll(iterable1.iterator(), iterable2);
}
/**
* Return whether the specified iterable 1 contains all of the
* elements in the specified iterable 2.
* The specified iterable 1 size is a performance hint.
*/
public static boolean containsAll(Iterable<?> iterable1, int iterable1Size, Iterable<?> iterable2) {
return IteratorTools.containsAll(iterable1.iterator(), iterable1Size, iterable2);
}
/**
* Return whether the specified iterable contains all of the
* elements in the specified iterator.
*/
public static boolean containsAll(Iterable<?> iterable, Iterator<?> iterator) {
return IteratorTools.containsAll(iterable.iterator(), iterator);
}
/**
* Return whether the specified iterable contains all of the
* elements in the specified iterator.
* The specified iterable size is a performance hint.
*/
public static boolean containsAll(Iterable<?> iterable, int iterableSize, Iterator<?> iterator) {
return IteratorTools.containsAll(iterable.iterator(), iterableSize, iterator);
}
/**
* Return whether the specified iterable contains all of the
* elements in the specified array.
*/
public static boolean containsAll(Iterable<?> iterable, Object... array) {
return IteratorTools.containsAll(iterable.iterator(), array);
}
/**
* Return whether the specified iterable contains all of the
* elements in the specified array.
* The specified iterable size is a performance hint.
*/
public static boolean containsAll(Iterable<?> iterable, int iterableSize, Object... array) {
return IteratorTools.containsAll(iterable.iterator(), iterableSize, array);
}
/**
* Return whether the specified iterables do not return the same elements
* in the same order.
*/
public static boolean elementsAreDifferent(Iterable<?> iterable1, Iterable<?> iterable2) {
return IteratorTools.elementsAreDifferent(iterable1.iterator(), iterable2.iterator());
}
/**
* Return whether the specified iterables return equal elements
* in the same order.
*/
public static boolean elementsAreEqual(Iterable<?> iterable1, Iterable<?> iterable2) {
return IteratorTools.elementsAreEqual(iterable1.iterator(), iterable2.iterator());
}
/**
* Return whether the specified iterables return the same elements.
*/
public static boolean elementsAreIdentical(Iterable<?> iterable1, Iterable<?> iterable2) {
return IteratorTools.elementsAreIdentical(iterable1.iterator(), iterable2.iterator());
}
/**
* Return whether the specified iterables do <em>not</em> return the same
* elements.
*/
public static boolean elementsAreNotIdentical(Iterable<?> iterable1, Iterable<?> iterable2) {
return IteratorTools.elementsAreNotIdentical(iterable1.iterator(), iterable2.iterator());
}
/**
* Execute the specified closure for each element in the specified iterable.
*/
public static <E> void execute(Iterable<? extends E> iterable, Closure<E> closure) {
IteratorTools.execute(iterable.iterator(), closure);
}
/**
* Execute the specified closure for each element in the specified iterable.
* If the closure throws an exception for an element, the exception will be
* handled by the specified exception handler and processing of the
* remaining elements will continue.
*/
public static <E> void execute(Iterable<? extends E> iterable, Closure<E> closure, ExceptionHandler exceptionHandler) {
IteratorTools.execute(iterable.iterator(), closure, exceptionHandler);
}
/**
* Execute the specified closure for each element in the specified iterable.
*/
public static <E> void execute(Iterable<? extends E> iterable, InterruptibleClosure<E> closure) throws InterruptedException {
IteratorTools.execute(iterable.iterator(), closure);
}
/**
* Execute the specified closure for each element in the specified iterable.
* If the closure throws an exception (other than an
* {@link InterruptedException}) for an element, the exception will be
* handled by the specified exception handler and processing of the
* remaining elements will continue.
*/
public static <E> void execute(Iterable<? extends E> iterable, InterruptibleClosure<E> closure, ExceptionHandler exceptionHandler) throws InterruptedException {
IteratorTools.execute(iterable.iterator(), closure, exceptionHandler);
}
/**
* Return the specified iterable's first element.
* @exception java.util.NoSuchElementException iterable is empty.
*/
public static <E> E first(Iterable<E> iterable) {
return IteratorTools.first(iterable.iterator());
}
/**
* Return the element corresponding to the specified index
* in the specified iterable.
*/
public static <E> E get(Iterable<? extends E> iterable, int index) {
return IteratorTools.get(iterable.iterator(), index);
}
/**
* Return a hash code corresponding to the elements in the specified iterable.
*/
public static int hashCode(Iterable<?> iterable) {
return (iterable == null) ? 0 : IteratorTools.hashCode(iterable.iterator());
}
/**
* Return the index of the first occurrence of the
* specified element in the specified iterable;
* return -1 if there is no such element.
*/
public static int indexOf(Iterable<?> iterable, Object value) {
return IteratorTools.indexOf(iterable.iterator(), value);
}
/**
* Return the index of the first occurrence of the
* specified element in the specified iterable, starting at the specified index;
* return -1 if there is no such element.
*/
public static int indexOf(Iterable<?> iterable, Object value, int startIndex) {
return IteratorTools.indexOf(iterable.iterator(), value, startIndex);
}
/**
* Return whether the specified iterable is empty.
* (Shortcut the iterator rather than calculating the entire size.)
*/
public static boolean isEmpty(Iterable<?> iterable) {
return IteratorTools.isEmpty(iterable.iterator());
}
/**
* Return whether the specified iterable is <em>not</em> empty.
* (Shortcut the iterator rather than calculating the entire size.)
*/
public static boolean isNotEmpty(Iterable<?> iterable) {
return IteratorTools.isNotEmpty(iterable.iterator());
}
/**
* Return the specified iterable's last element.
* @exception java.util.NoSuchElementException iterable is empty.
*/
public static <E> E last(Iterable<E> iterable) {
return IteratorTools.last(iterable.iterator());
}
/**
* Return the index of the last occurrence of the
* specified element in the specified iterable;
* return -1 if there is no such element.
*/
public static int lastIndexOf(Iterable<?> iterable, Object value) {
return IteratorTools.lastIndexOf(iterable.iterator(), value);
}
/**
* Return the index of the last occurrence of the
* specified element in the specified iterable, starting at the specified index;
* return -1 if there is no such element.
*/
public static int lastIndexOf(Iterable<?> iterable, Object value, int startIndex) {
return IteratorTools.lastIndexOf(iterable.iterator(), value, startIndex);
}
/**
* Return a list corresponding to the specified iterable.
*/
public static <E> ArrayList<E> list(Iterable<? extends E> iterable) {
return IteratorTools.list(iterable.iterator());
}
/**
* Return a list corresponding to the specified iterable.
* The specified iterable size is a performance hint.
*/
public static <E> ArrayList<E> list(Iterable<? extends E> iterable, int iterableSize) {
return IteratorTools.list(iterable.iterator(), iterableSize);
}
/**
* Return the number of elements returned by the specified iterable.
*/
public static int size(Iterable<?> iterable) {
return IteratorTools.size(iterable.iterator());
}
/**
* Return an iterable containing the sorted elements of the specified iterable.
*/
public static <E extends Comparable<? super E>> Iterable<E> sort(Iterable<? extends E> iterable) {
return sort(iterable, null);
}
/**
* Return an iterable containing the sorted elements of the specified iterable.
* The specified iterable size is a performance hint.
*/
public static <E extends Comparable<? super E>> Iterable<E> sort(Iterable<? extends E> iterable, int iterableSize) {
return sort(iterable, null, iterableSize);
}
/**
* Return an iterable containing the sorted elements of the specified iterable.
*/
public static <E> Iterable<E> sort(Iterable<? extends E> iterable, Comparator<? super E> comparator) {
Iterator<? extends E> iterator = iterable.iterator();
if (iterator.hasNext()) {
return ListTools.sort(ListTools.arrayList(iterator), comparator);
}
return emptyIterable();
}
/**
* Return an iterable containing the sorted elements of the specified iterable.
* The specified iterable size is a performance hint.
*/
public static <E> Iterable<E> sort(Iterable<? extends E> iterable, Comparator<? super E> comparator, int iterableSize) {
Iterator<? extends E> iterator = iterable.iterator();
if (iterator.hasNext()) {
return ListTools.sort(ListTools.arrayList(iterator, iterableSize), comparator);
}
return emptyIterable();
}
/**
* Convert the specified iterable into an array.
* @see Collection#toArray()
*/
public static Object[] toArray(Iterable<?> iterable) {
return IteratorTools.toArray(iterable.iterator());
}
/**
* Convert the specified iterable into an array.
* The specified iterable size is a performance hint.
* @see Collection#toArray()
*/
public static Object[] toArray(Iterable<?> iterable, int iterableSize) {
return IteratorTools.toArray(iterable.iterator(), iterableSize);
}
/**
* Convert the specified iterable into an array.
* @see Collection#toArray(Object[])
*/
public static <E> E[] toArray(Iterable<? extends E> iterable, E[] array) {
return IteratorTools.toArray(iterable.iterator(), array);
}
/**
* Convert the specified iterable into an array.
* The specified iterable size is a performance hint.
* @see Collection#toArray(Object[])
*/
public static <E> E[] toArray(Iterable<? extends E> iterable, int iterableSize, E[] array) {
return IteratorTools.toArray(iterable.iterator(), iterableSize, array);
}
// ********** factory methods **********
/**
* Return an iterable that provides simultaneous processing of the elements
* in the specified iterables.
* @see SimultaneousIterable
*/
public static <E, I extends Iterable<? extends E>> Iterable<List<E>> align(I... iterables) {
int len = iterables.length;
if (len == 0) {
return emptyIterable();
}
return align(iterable(iterables), len);
}
/**
* Return an iterable that provides simultaneous processing of the elements
* in the specified iterables.
* @see SimultaneousIterable
*/
public static <E, I extends Iterable<? extends E>> Iterable<List<E>> align(Iterable<I> iterables) {
return align(iterables, -1);
}
/**
* Return an iterable that provides simultaneous processing of the elements
* in the specified iterables.
* @see SimultaneousIterable
*/
public static <E, I extends Iterable<? extends E>> Iterable<List<E>> align(Iterable<I> iterables, int iterablesSize) {
return new SimultaneousIterable<E>(iterables, iterablesSize);
}
/**
* Return a list iterable that provides simultaneous processing of the elements
* in the specified iterables.
* @see SimultaneousListIterable
*/
public static <E, I extends ListIterable<E>> ListIterable<List<E>> alignList(I... iterables) {
int len = iterables.length;
if (len == 0) {
return emptyListIterable();
}
return alignList(iterable(iterables), len);
}
/**
* Return a list iterable that provides simultaneous processing of the elements
* in the specified iterables.
* @see SimultaneousListIterable
*/
public static <E, I extends ListIterable<E>> ListIterable<List<E>> alignList(Iterable<I> iterables) {
return alignList(iterables, -1);
}
/**
* Return a list iterable that provides simultaneous processing of the elements
* in the specified iterables.
* @see SimultaneousListIterable
*/
public static <E, I extends ListIterable<E>> ListIterable<List<E>> alignList(Iterable<I> iterables, int iterablesSize) {
return new SimultaneousListIterable<E>(iterables, iterablesSize);
}
/**
* Return an iterable that converts the specified iterable's element type.
* @see LateralIterableWrapper
*/
public static <E1, E2> Iterable<E2> cast(Iterable<E1> iterable) {
return new LateralIterableWrapper<E1, E2>(iterable);
}
/**
* Return a list iterable that converts the specified list iterable's element type.
* @see LateralIterableWrapper
*/
public static <E1, E2> ListIterable<E2> cast(ListIterable<E1> iterable) {
return new LateralListIterableWrapper<E1, E2>(iterable);
}
/**
* Return an iterable that converts the specified iterable's element type.
* @see SubIterableWrapper
*/
public static <E1, E2 extends E1> Iterable<E2> downCast(Iterable<E1> iterable) {
return new SubIterableWrapper<E1, E2>(iterable);
}
/**
* Return an iterable that converts the specified iterable's element type.
* @see SubListIterableWrapper
*/
public static <E1, E2 extends E1> ListIterable<E2> downCast(ListIterable<E1> iterable) {
return new SubListIterableWrapper<E1, E2>(iterable);
}
/**
* Return an iterable that converts the specified iterable's element type.
* @see SuperIterableWrapper
*/
public static <E> Iterable<E> upCast(Iterable<? extends E> iterable) {
return new SuperIterableWrapper<E>(iterable);
}
/**
* Return an iterable that converts the specified iterable's element type.
* @see SuperListIterableWrapper
*/
public static <E> ListIterable<E> upCast(ListIterable<? extends E> iterable) {
return new SuperListIterableWrapper<E>(iterable);
}
/**
* Return a chain iterable that starts with the specified element and uses
* the specified {@link Transformer transformer}.
* @see ChainIterable
*/
public static <E> Iterable<E> chainIterable(E first, Transformer<? super E, ? extends E> transformer) {
if (first == null) {
return emptyIterable();
}
return new ChainIterable<E>(first, transformer);
}
/**
* Return an iterable that clones the specified collection before returning
* elements.
* @see LiveCloneIterable
*/
public static <E> Iterable<E> cloneLive(Collection<? extends E> collection) {
return cloneLive(collection, DisabledClosure.instance());
}
/**
* Return an iterable that clones the specified collection before returning
* elements and uses the specified remove closure.
* @see LiveCloneIterable
*/
public static <E> Iterable<E> cloneLive(Collection<? extends E> collection, Closure<? super E> removeClosure) {
return new LiveCloneIterable<E>(collection, removeClosure);
}
/**
* Return a list iterable that clones the specified collection before returning
* elements.
* @see LiveCloneListIterable
*/
public static <E> ListIterable<E> cloneLive(List<? extends E> list) {
return cloneLive(list, CloneListIterator.Adapter.ReadOnly.<E>instance());
}
/**
* Return a list iterable that clones the specified collection before returning
* elements and uses the specified {@link org.eclipse.jpt.common.utility.internal.iterator.CloneListIterator.Adapter adapter}.
* @see LiveCloneListIterable
*/
public static <E> ListIterable<E> cloneLive(List<? extends E> list, CloneListIterator.Adapter<E> adapter) {
return new LiveCloneListIterable<E>(list, adapter);
}
/**
* Return an iterable that clones the specified collection before returning
* elements.
* @see SnapshotCloneIterable
*/
public static <E> Iterable<E> cloneSnapshot(Collection<? extends E> collection) {
return cloneSnapshot(collection, DisabledClosure.instance());
}
/**
* Return an iterable that clones the specified collection before returning
* elements and uses the specified remove closure.
* @see SnapshotCloneIterable
*/
public static <E> Iterable<E> cloneSnapshot(Collection<? extends E> collection, Closure<? super E> removeClosure) {
if (collection.isEmpty()) {
return emptyIterable();
}
return new SnapshotCloneIterable<E>(collection, removeClosure);
}
/**
* Return a list iterable that clones the specified collection before returning
* elements.
* @see SnapshotCloneListIterable
*/
public static <E> ListIterable<E> cloneSnapshot(List<? extends E> list) {
return cloneSnapshot(list, CloneListIterator.Adapter.ReadOnly.<E>instance());
}
/**
* Return a list iterable that clones the specified collection before returning
* elements and uses the specified {@link org.eclipse.jpt.common.utility.internal.iterator.CloneListIterator.Adapter adapter}.
* @see SnapshotCloneListIterable
*/
public static <E> ListIterable<E> cloneSnapshot(List<? extends E> list, CloneListIterator.Adapter<E> adapter) {
if (list.isEmpty()) {
return emptyListIterable();
}
return new SnapshotCloneListIterable<E>(list, adapter);
}
/**
* Return an iterable that returns the
* elements in the specified iterable followed by the specified object.
* @see CompositeIterable
*/
@SuppressWarnings("unchecked")
public static <E> Iterable<E> add(Iterable<? extends E> iterable, E object) {
return concatenate_(iterable, singletonIterable(object));
}
/**
* Return an iterable that returns the specified object followed by the
* elements in the specified iterable.
* @see CompositeIterable
*/
@SuppressWarnings("unchecked")
public static <E> Iterable<E> insert(E object, Iterable<? extends E> iterable) {
return concatenate_(singletonIterable(object), iterable);
}
/**
* Return an iterable that returns the
* elements in the specified iterables.
* @see CompositeIterable
*/
@SuppressWarnings("unchecked")
public static <E> Iterable<E> concatenate(Iterable<? extends E>... iterables) {
int len = iterables.length;
if (len == 0) {
return emptyIterable();
}
if (len == 1) {
return (Iterable<E>) iterables[0];
}
return concatenate_(iterables);
}
/**
* assume the list is not empty
*/
private static <E> Iterable<E> concatenate_(Iterable<? extends E>... iterables) {
return concatenate(Arrays.asList(iterables));
}
/**
* Return an iterable that returns the
* elements in the specified iterables.
* @see CompositeIterable
*/
public static <E> Iterable<E> concatenate(Iterable<? extends Iterable<? extends E>> iterables) {
return new CompositeIterable<E>(iterables);
}
/**
* Return an iterable on the children of the specified parents.
* Use the specified transformer to transform each parent into its children.
* @see CompositeIterable
*/
public static <P, E> Iterable<E> children(Iterable<? extends P> parents, Transformer<? super P, ? extends Iterable<? extends E>> childrenTransformer) {
return concatenate(transform(parents, childrenTransformer));
}
/**
* Return a list iterable that returns the
* elements in the specified iterable followed by the specified object.
* @see CompositeListIterable
*/
@SuppressWarnings("unchecked")
public static <E> ListIterable<E> add(ListIterable<E> iterable, E object) {
return concatenate_(iterable, singletonListIterable(object));
}
/**
* Return a list iterable that returns the specified object followed by the
* elements in the specified iterable.
* @see CompositeListIterable
*/
@SuppressWarnings("unchecked")
public static <E> ListIterable<E> insert(E object, ListIterable<E> iterable) {
return concatenate_(singletonListIterable(object), iterable);
}
/**
* Return a list iterable that returns the
* elements in the specified iterables.
* @see CompositeListIterable
*/
public static <E> ListIterable<E> concatenate(ListIterable<E>... iterables) {
int len = iterables.length;
if (len == 0) {
return emptyListIterable();
}
if (len == 1) {
return iterables[0];
}
return concatenate_(iterables);
}
/**
* assume the list is not empty
*/
private static <E> ListIterable<E> concatenate_(ListIterable<E>... iterables) {
return concatenate(listIterable(iterables));
}
/**
* Return a list iterable that returns the
* elements in the specified iterables.
* @see CompositeListIterable
*/
public static <E> ListIterable<E> concatenate(ListIterable<? extends ListIterable<E>> iterables) {
return new CompositeListIterable<E>(iterables);
}
/**
* Return a list iterable on the children of the specified parents.
* Use the specified transformer to transform each parent into its children.
* @see CompositeListIterable
*/
public static <P, E> ListIterable<E> children(ListIterable<? extends P> parents, Transformer<? super P, ? extends ListIterable<E>> childrenTransformer) {
return concatenate(transform(parents, childrenTransformer));
}
/**
* Return a list iterable that returns the
* elements in the specified iterable followed by the specified object.
* @see ReadOnlyCompositeListIterable
*/
@SuppressWarnings("unchecked")
public static <E> ListIterable<E> addReadOnly(ListIterable<? extends E> iterable, E object) {
return concatenateReadOnly_(iterable, singletonListIterable(object));
}
/**
* Return a list iterable that returns the specified object followed by the
* elements in the specified iterable.
* @see ReadOnlyCompositeListIterable
*/
@SuppressWarnings("unchecked")
public static <E> ListIterable<E> insertReadOnly(E object, ListIterable<? extends E> iterable) {
return concatenateReadOnly_(singletonListIterable(object), iterable);
}
/**
* Return a list iterable that returns the
* elements in the specified iterables.
* @see ReadOnlyCompositeListIterable
*/
@SuppressWarnings("unchecked")
public static <E> ListIterable<E> concatenateReadOnly(ListIterable<? extends E>... iterables) {
int len = iterables.length;
if (len == 0) {
return emptyListIterable();
}
if (len == 1) {
return (ListIterable<E>) iterables[0];
}
return concatenateReadOnly_(iterables);
}
/**
* assume the list is not empty
*/
private static <E> ListIterable<E> concatenateReadOnly_(ListIterable<? extends E>... iterables) {
return concatenateReadOnly(listIterable(iterables));
}
/**
* Return a list iterable that returns the
* elements in the specified iterables.
* @see ReadOnlyCompositeListIterable
*/
public static <E> ListIterable<E> concatenateReadOnly(ListIterable<? extends ListIterable<? extends E>> iterables) {
return new ReadOnlyCompositeListIterable<E>(iterables);
}
/**
* Return a list iterable on the children of the specified parents.
* Use the specified transformer to transform each parent into its children.
* @see ReadOnlyCompositeListIterable
*/
public static <P, E> ListIterable<E> readOnlyChildren(ListIterable<? extends P> parents, Transformer<? super P, ? extends ListIterable<? extends E>> childrenTransformer) {
return concatenateReadOnly(transform(parents, childrenTransformer));
}
/**
* Return an empty iterable.
*/
public static <E> Iterable<E> emptyIterable() {
return EmptyIterable.instance();
}
/**
* Return an empty list iterable.
*/
public static <E> ListIterable<E> emptyListIterable() {
return EmptyListIterable.instance();
}
/**
* Return an iterable that will use the specified predicate to filter the
* elements in the specified iterable.
* @see FilteringIterable
*/
public static <E> Iterable<E> filter(Iterable<? extends E> iterable, Predicate<? super E> predicate) {
return new FilteringIterable<E>(iterable, predicate);
}
/**
* Return an iterable that will return only the non-<code>null</code>
* elements in the specified iterable.
* @see FilteringIterable
*/
public static <E> Iterable<E> removeNulls(Iterable<? extends E> iterable) {
return filter(iterable, PredicateTools.isNotNull());
}
/**
* Return an iterable that will return the specified root element followed
* by its children etc. as determined by the specified transformer.
* @see GraphIterable
*/
public static <E> Iterable<E> graphIterable(E root, Transformer<? super E, ? extends Iterable<? extends E>> transformer) {
return graphIterable(singletonIterable(root), transformer);
}
/**
* Return an iterable that will return the specified root elements followed
* by their children etc. as determined by the specified transformer.
* @see GraphIterable
*/
public static <E> Iterable<E> graphIterable(E[] roots, Transformer<? super E, ? extends Iterable<? extends E>> transformer) {
if (roots.length == 0) {
return emptyIterable();
}
return graphIterable(Arrays.asList(roots), transformer);
}
/**
* Return an iterable that will return the specified root elements followed
* by their children etc. as determined by the specified transformer.
* @see GraphIterable
*/
public static <E> Iterable<E> graphIterable(Iterable<? extends E> roots, Transformer<? super E, ? extends Iterable<? extends E>> transformer) {
return new GraphIterable<E>(roots, transformer);
}
/**
* Return an iterable on the elements in the specified array.
*/
public static <E> Iterable<E> iterable(E... array) {
return iterable(array, 0);
}
/**
* Return an iterable on the elements in the specified array
* starting at the specified position in the array.
*/
public static <E> Iterable<E> iterable(E[] array, int start) {
return iterable(array, start, array.length);
}
/**
* Return an iterable on the elements in the specified array
* starting at the specified start index, inclusive, and continuing to
* the specified end index, exclusive.
*/
public static <E> Iterable<E> iterable(E[] array, int start, int end) {
if (start == end) {
return emptyIterable();
}
return new ArrayIterable<E>(array, start, end);
}
/**
* Return an iterable on the specified queue.
* @see Queue
*/
public static <E> Iterable<E> iterable(Queue<? extends E> queue) {
return new QueueIterable<E>(queue);
}
/**
* Return an iterable on the specified stack.
* @see Stack
*/
public static <E> Iterable<E> iterable(Stack<? extends E> stack) {
return new StackIterable<E>(stack);
}
/**
* Return a list iterable for the specified array.
*/
public static <E> ListIterable<E> listIterable(E... array) {
return listIterable(array, 0);
}
/**
* Return a list iterable for the specified array
* starting at the specified position in the array.
*/
public static <E> ListIterable<E> listIterable(E[] array, int start) {
return listIterable(array, start, array.length);
}
/**
* Return a list iterable for the specified array
* starting at the specified start index, inclusive, and continuing to
* the specified end index, exclusive.
*/
public static <E> ListIterable<E> listIterable(E[] array, int start, int end) {
if (start == end) {
return emptyListIterable();
}
return new ArrayListIterable<E>(array, start, end);
}
/**
* Return a list iterable for the specified list.
*/
public static <E> ListIterable<E> listIterable(List<E> list) {
return new ListListIterable<E>(list);
}
/**
* Construct an iterable that wraps the specified iterable and returns a
* {@link org.eclipse.jpt.common.utility.internal.iterator.PeekableIterator}.
* @see PeekableIterable
*/
public static <E> PeekableIterable<E> peekable(Iterable<? extends E> iterable) {
return new PeekableIterable<E>(iterable);
}
/**
* Convert the specified iterable to read-only.
* @see ReadOnlyIterable
*/
public static <E> Iterable<E> readOnly(Iterable<? extends E> iterable) {
return new ReadOnlyIterable<E>(iterable);
}
/**
* Convert the specified iterable to read-only.
* @see ReadOnlyListIterable
*/
public static <E> ListIterable<E> readOnly(ListIterable<? extends E> iterable) {
return new ReadOnlyListIterable<E>(iterable);
}
/**
* Return an iterable that returns only the single,
* specified object.
* @see SingleElementIterable
*/
public static <E> Iterable<E> singletonIterable(E value) {
return new SingleElementIterable<E>(value);
}
/**
* Return a list iterable that returns only the single,
* specified object.
* @see SingleElementListIterable
*/
public static <E> ListIterable<E> singletonListIterable(E value) {
return new SingleElementListIterable<E>(value);
}
/**
* Return an iterable that will use the specified transformer to transform the
* elements in the specified iterable.
* @see TransformationIterable
*/
public static <E1, E2> Iterable<E2> transform(Iterable<? extends E1> iterable, Transformer<? super E1, ? extends E2> transformer) {
return new TransformationIterable<E1, E2>(iterable, transformer);
}
/**
* Return an iterable that will use the specified transformer to transform the
* elements in the specified iterable.
* @see TransformationListIterable
*/
public static <E1, E2, T extends E1> ListIterable<E2> transform(ListIterable<T> iterable, Transformer<? super E1, ? extends E2> transformer) {
return new TransformationListIterable<E1, E2>(iterable, transformer);
}
/**
* Construct an iterable that returns the nodes of a tree
* with the specified root and transformer.
* @see TreeIterable
*/
public static <E> Iterable<E> treeIterable(E root, Transformer<? super E, ? extends Iterable<? extends E>> transformer) {
return treeIterable(singletonIterable(root), transformer);
}
/**
* Construct an iterable that returns the nodes of a tree
* with the specified roots and transformer.
* @see TreeIterable
*/
public static <E> Iterable<E> treeIterable(E[] roots, Transformer<? super E, ? extends Iterable<? extends E>> transformer) {
if (roots.length == 0) {
return emptyIterable();
}
return treeIterable(iterable(roots), transformer);
}
/**
* Construct an iterable that returns the nodes of a tree
* with the specified roots and transformer.
* @see TreeIterable
*/
public static <E> Iterable<E> treeIterable(Iterable<? extends E> roots, Transformer<? super E, ? extends Iterable<? extends E>> transformer) {
return new TreeIterable<E>(roots, transformer);
}
// ********** transformers **********
/**
* Return a transformer that transforms an {@link Iterable} into its
* corresponding {@link Iterator}.
*/
@SuppressWarnings("unchecked")
public static <E> Transformer<Iterable<? extends E>, Iterator<E>> iteratorTransformer() {
return ITERATOR_TRANSFORMER;
}
/**
* A transformer that transforms an {@link Iterable} into its
* corresponding {@link Iterator}.
*/
@SuppressWarnings("rawtypes")
public static final Transformer ITERATOR_TRANSFORMER = new IteratorTransformer();
/**
* A transformer that transforms an {@link Iterable} into its
* corresponding {@link Iterator}.
*/
public static class IteratorTransformer<E>
implements Transformer<Iterable<? extends E>, Iterator<E>>
{
@SuppressWarnings("unchecked")
public Iterator<E> transform(Iterable<? extends E> iterable) {
return (Iterator<E>) iterable.iterator();
}
@Override
public String toString() {
return this.getClass().getSimpleName();
}
}
/**
* Return a transformer that transforms a {@link ListIterable} into its
* corresponding {@link ListIterator}.
*/
@SuppressWarnings("unchecked")
public static <E> Transformer<ListIterable<E>, ListIterator<E>> listIteratorTransformer() {
return ListIterable.TRANSFORMER;
}
/**
* Return a transformer that transforms a {@link ListIterable} into a
* <em>read-only</em> {@link ListIterator}.
*/
@SuppressWarnings("unchecked")
public static <E> Transformer<ListIterable<? extends E>, ListIterator<? extends E>> readOnlyListIteratorTransformer() {
return READ_ONLY_LIST_ITERATOR_TRANSFORMER;
}
/**
* A transformer that transforms a {@link ListIterable} into a
* <em>read-only</em> {@link ListIterator}.
*/
@SuppressWarnings("rawtypes")
public static final Transformer READ_ONLY_LIST_ITERATOR_TRANSFORMER = new ReadOnlyListIteratorTransformer();
/**
* A transformer that transforms a {@link ListIterable} into a
* <em>read-only</em> {@link ListIterator}.
*/
public static class ReadOnlyListIteratorTransformer<E>
implements Transformer<ListIterable<? extends E>, ListIterator<? extends E>>
{
public ListIterator<? extends E> transform(ListIterable<? extends E> iterable) {
return IteratorTools.readOnly(iterable.iterator());
}
@Override
public String toString() {
return this.getClass().getSimpleName();
}
}
// ********** constructor **********
/**
* Suppress default constructor, ensuring non-instantiability.
*/
private IterableTools() {
super();
throw new UnsupportedOperationException();
}
}