/* * Copyright (c) 2011 LinkedIn, Inc * * Licensed 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 com.flaptor.indextank.util; import static com.google.common.base.Preconditions.checkNotNull; import java.util.Iterator; import java.util.NoSuchElementException; import com.google.common.base.Function; import com.google.common.base.Predicate; public class Skippables { private static final SkippableIterator<Object> EMPTY_ITERATOR = new SkippableIterator<Object>() { @Override public void skipTo(int i) { } @Override public boolean hasNext() { return false; } @Override public Object next() { throw new NoSuchElementException(); } @Override public void remove() { throw new IllegalStateException(); } }; private static final SkippableIterable<Object> EMPTY_ITERABLE = new AbstractSkippableIterable<Object>() { @Override public SkippableIterator<Object> iterator() { return EMPTY_ITERATOR; } }; @SuppressWarnings("unchecked") public static <E> SkippableIterator<E> emptyIterator() { return (SkippableIterator<E>) EMPTY_ITERATOR; } @SuppressWarnings("unchecked") public static <E> SkippableIterable<E> emptyIterable() { return (SkippableIterable<E>) EMPTY_ITERABLE; } public static <E> SkippableIterable<E> fromIterable(final Iterable<E> iterable) { return new AbstractSkippableIterable<E>() { @Override public SkippableIterator<E> iterator() { return fromIterator(iterable.iterator()); } }; } public static <E> SkippableIterator<E> fromIterator(final Iterator<E> iterator) { return new SkippableIterator<E>() { @Override public void skipTo(int i) { } @Override public boolean hasNext() { return iterator.hasNext(); } @Override public E next() { return iterator.next(); } @Override public void remove() { iterator.remove(); } }; } public static <F,T> SkippableIterable<T> transform(final SkippableIterable<F> fromIterable, final Function<F, T> function) { checkNotNull(fromIterable); checkNotNull(function); return new AbstractSkippableIterable<T>() { public SkippableIterator<T> iterator() { return transform(fromIterable.iterator(), function); } }; } public static <F,T> SkippableIterator<T> transform(final SkippableIterator<F> fromIterator, final Function<F, T> function) { checkNotNull(fromIterator); checkNotNull(function); return new SkippableIterator<T>() { public boolean hasNext() { return fromIterator.hasNext(); } public T next() { F from = fromIterator.next(); return function.apply(from); } public void remove() { fromIterator.remove(); } @Override public void skipTo(int i) { fromIterator.skipTo(i); } }; } public static <T> SkippableIterable<T> filter(final SkippableIterable<T> unfiltered, final Predicate<? super T> predicate) { checkNotNull(unfiltered); checkNotNull(predicate); return new AbstractSkippableIterable<T>() { public SkippableIterator<T> iterator() { return filter(unfiltered.iterator(), predicate); } }; } public static <T> SkippableIterator<T> filter(final SkippableIterator<T> unfiltered, final Predicate<? super T> predicate) { checkNotNull(unfiltered); checkNotNull(predicate); return new AbstractSkippableIterator<T>() { @Override protected T computeNext() { while (unfiltered.hasNext()) { T element = unfiltered.next(); if (predicate.apply(element)) { return element; } } return endOfData(); } @Override public void skipTo(int i) { unfiltered.skipTo(i); } }; } }