| 1 | /*- | |
| 2 | * #%L | |
| 3 | * io.earcam.instrumental.io | |
| 4 | * %% | |
| 5 | * Copyright (C) 2018 earcam | |
| 6 | * %% | |
| 7 | * SPDX-License-Identifier: (BSD-3-Clause OR EPL-1.0 OR Apache-2.0 OR MIT) | |
| 8 | * | |
| 9 | * You <b>must</b> choose to accept, in full - any individual or combination of | |
| 10 | * the following licenses: | |
| 11 | * <ul> | |
| 12 | * <li><a href="https://opensource.org/licenses/BSD-3-Clause">BSD-3-Clause</a></li> | |
| 13 | * <li><a href="https://www.eclipse.org/legal/epl-v10.html">EPL-1.0</a></li> | |
| 14 | * <li><a href="https://www.apache.org/licenses/LICENSE-2.0">Apache-2.0</a></li> | |
| 15 | * <li><a href="https://opensource.org/licenses/MIT">MIT</a></li> | |
| 16 | * </ul> | |
| 17 | * #L% | |
| 18 | */ | |
| 19 | package io.earcam.utilitarian.io; | |
| 20 | ||
| 21 | import java.nio.file.DirectoryStream; | |
| 22 | import java.nio.file.Files; | |
| 23 | import java.nio.file.Path; | |
| 24 | import java.util.ArrayDeque; | |
| 25 | import java.util.Deque; | |
| 26 | import java.util.Iterator; | |
| 27 | import java.util.function.Function; | |
| 28 | ||
| 29 | import io.earcam.unexceptional.Exceptional; | |
| 30 | ||
| 31 | class RecursivePathIterator implements Iterator<Path> { | |
| 32 | ||
| 33 | private static final Function<Path, DirectoryStream<Path>> DEFAULT_STREAMER = Exceptional.uncheckFunction(Files::newDirectoryStream); | |
| 34 | private final Deque<Iterator<Path>> pending = new ArrayDeque<>(); | |
| 35 | private final Function<Path, DirectoryStream<Path>> streamer; | |
| 36 | private Iterator<Path> current; | |
| 37 | ||
| 38 | ||
| 39 | RecursivePathIterator(Path root) | |
| 40 | { | |
| 41 | this(root, DEFAULT_STREAMER); | |
| 42 | } | |
| 43 | ||
| 44 | ||
| 45 | RecursivePathIterator(Path root, Function<Path, DirectoryStream<Path>> directoryStreamer) | |
| 46 | { | |
| 47 | this(directoryStreamer.apply(root).iterator(), directoryStreamer); | |
| 48 | } | |
| 49 | ||
| 50 | ||
| 51 | RecursivePathIterator(Iterator<Path> iterator, Function<Path, DirectoryStream<Path>> directoryStreamer) | |
| 52 | { | |
| 53 | this.current = iterator; | |
| 54 | this.streamer = directoryStreamer; | |
| 55 | } | |
| 56 | ||
| 57 | ||
| 58 | @Override | |
| 59 | public boolean hasNext() | |
| 60 | { | |
| 61 |
2
1. hasNext : negated conditional → KILLED 2. hasNext : replaced return of integer sized value with (x == 0 ? 1 : 0) → KILLED |
return current.hasNext() |
| 62 |
1
1. hasNext : negated conditional → KILLED |
|| popPending(); |
| 63 | } | |
| 64 | ||
| 65 | ||
| 66 | private boolean popPending() | |
| 67 | { | |
| 68 |
1
1. popPending : negated conditional → KILLED |
if(pending.isEmpty()) { |
| 69 |
1
1. popPending : replaced return of integer sized value with (x == 0 ? 1 : 0) → KILLED |
return false; |
| 70 | } | |
| 71 | current = pending.pop(); | |
| 72 |
1
1. popPending : replaced return of integer sized value with (x == 0 ? 1 : 0) → KILLED |
return hasNext(); |
| 73 | } | |
| 74 | ||
| 75 | ||
| 76 | @Override | |
| 77 | public Path next() | |
| 78 | { | |
| 79 | Path next = current.next(); | |
| 80 |
1
1. next : negated conditional → KILLED |
if(next.toFile().isDirectory()) { |
| 81 |
1
1. next : removed call to java/util/Deque::push → KILLED |
pending.push(current); |
| 82 | current = streamer.apply(next).iterator(); | |
| 83 | } | |
| 84 |
1
1. next : mutated return of Object value for io/earcam/utilitarian/io/RecursivePathIterator::next to ( if (x != null) null else throw new RuntimeException ) → KILLED |
return next; |
| 85 | } | |
| 86 | ||
| 87 | } | |
Mutations | ||
| 61 |
1.1 2.2 |
|
| 62 |
1.1 |
|
| 68 |
1.1 |
|
| 69 |
1.1 |
|
| 72 |
1.1 |
|
| 80 |
1.1 |
|
| 81 |
1.1 |
|
| 84 |
1.1 |