package sk.stuba.fiit.perconik.utilities.io; import java.net.URI; import java.nio.file.Path; import java.util.Iterator; import com.google.common.collect.AbstractSequentialIterator; import static java.nio.file.Paths.get; import static com.google.common.base.Preconditions.checkState; import static com.google.common.collect.Iterators.toArray; public final class MorePaths { private MorePaths() {} public static Path path(final URI uri) { return get(uri); } public static Path path(final String segment, final String ... more) { return get(segment, more); } public static Path path(final Iterable<String> segments) { return path(segments.iterator()); } public static Path path(final Iterator<String> segments) { return path(segments.next(), toArray(segments, String.class)); } private static final class DownToBaseIterator<T extends Path> extends AbstractSequentialIterator<T> { private final int count; protected DownToBaseIterator(final T base, final T path) { super(path); checkState(path.startsWith(base)); this.count = base.getNameCount(); } @Override protected T computeNext(final T previous) { int count = previous.getNameCount(); if (this.count < count) { // safe cast as T overrides getParent() properly @SuppressWarnings("unchecked") T result = (T) previous.getParent(); return result; } return null; } } private static final class DownToRootIterator<T extends Path> extends AbstractSequentialIterator<T> { protected DownToRootIterator(final T path) { super(path); } @Override protected T computeNext(final T previous) { // safe cast as T overrides getParent() properly @SuppressWarnings("unchecked") T result = (T) previous.getParent(); return result; } } public static <T extends Path> Iterable<T> downToBase(final T base, final T path) { return new Iterable<T>() { public Iterator<T> iterator() { return new DownToBaseIterator<>(base, path); } }; } public static <T extends Path> Iterable<T> downToRoot(final T path) { return new Iterable<T>() { public Iterator<T> iterator() { return new DownToRootIterator<>(path); } }; } }