/******************************************************************************* * Copyright (c) 2012-2015 Codenvy, S.A. * 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: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.eclipse.che.api.vfs.server; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; /** @author <a href="mailto:andrey.parfonov@exoplatform.com">Andrey Parfonov</a> */ public abstract class LazyIterator<T> implements Iterator<T> { public static final LazyIterator<Object> EMPTY_ITEMS_ITERATOR = new EmptyIterator(); private static class EmptyIterator extends LazyIterator<Object> { @Override protected void fetchNext() { } @Override public int size() { return 0; } } /** Empty iterator. */ @SuppressWarnings("unchecked") public static <T> LazyIterator<T> emptyIterator() { return (LazyIterator<T>)EMPTY_ITEMS_ITERATOR; } private static class ListWrapper<T> extends LazyIterator<T> { private final int size; private final Iterator<T> delegate; ListWrapper(List<T> list) { size = list.size(); delegate = list.iterator(); fetchNext(); } @Override protected void fetchNext() { next = null; while (next == null && delegate.hasNext()) { next = delegate.next(); } } @Override public int size() { return size; } } /** Wrapper for List which implements LazyIterator functionality. */ public static <T> LazyIterator<T> fromList(List<T> list) { return new ListWrapper<>(list); } private static class SingletonIterator<T> extends LazyIterator<T> { SingletonIterator(T value) { next = value; } @Override protected void fetchNext() { next = null; } @Override public int size() { return 1; } } /** Singleton iterator. */ public static <T> LazyIterator<T> singletonIterator(T value) { return new SingletonIterator<>(value); } // ----------------------------------- protected T next; /** To fetch next item and set it in field <code>next</code> */ protected abstract void fetchNext(); /** @see java.util.Iterator#hasNext() */ public boolean hasNext() { return next != null; } /** @see java.util.Iterator#next() */ public final T next() { if (next == null) { throw new NoSuchElementException(); } T n = next; fetchNext(); return n; } /** @see java.util.Iterator#remove() */ public final void remove() { throw new UnsupportedOperationException("remove"); } /** * Get total number of items in iterator. If not able determine number of items then -1 will be returned. * * @return number of items or -1 */ public int size() { return -1; } /** * Skip specified number of element in collection. * * @param skip * the number of items to skip * @throws NoSuchElementException * if skipped past the last item in the iterator */ public void skip(int skip) throws NoSuchElementException { while (skip-- > 0) { fetchNext(); if (next == null) { throw new NoSuchElementException(); } } } }