RecursiveFiles.java

1
/*-
2
 * #%L
3
 * io.earcam.instrumental.io.file
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.file;
20
21
import static java.nio.file.FileVisitOption.FOLLOW_LINKS;
22
import static java.nio.file.FileVisitResult.CONTINUE;
23
import static java.nio.file.LinkOption.NOFOLLOW_LINKS;
24
25
import java.io.IOException;
26
import java.nio.file.CopyOption;
27
import java.nio.file.FileVisitOption;
28
import java.nio.file.FileVisitResult;
29
import java.nio.file.Files;
30
import java.nio.file.LinkOption;
31
import java.nio.file.Path;
32
import java.nio.file.SimpleFileVisitor;
33
import java.nio.file.attribute.BasicFileAttributes;
34
import java.util.Arrays;
35
import java.util.EnumSet;
36
37
/**
38
 * Wise to invoke these methods with {@link LinkOption#NOFOLLOW_LINKS}
39
 */
40
public final class RecursiveFiles {
41
42
	private abstract static class AbstractVisitor extends SimpleFileVisitor<Path> {
43
44
		final Path sink;
45
		final Path source;
46
		final CopyOption[] options;
47
48
		Path sinkSub;
49
50
51
		public AbstractVisitor(Path source, Path sink, CopyOption... options)
52
		{
53
			this.source = source;
54
			this.sink = sink;
55
			this.options = options;
56
		}
57
58
59
		@Override
60
		public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException
61
		{
62
			sinkSub = sink.resolve(source.relativize(dir));
63
			sinkSub.toFile().mkdirs();
64 1 1. preVisitDirectory : mutated return of Object value for io/earcam/utilitarian/io/file/RecursiveFiles$AbstractVisitor::preVisitDirectory to ( if (x != null) null else throw new RuntimeException ) → KILLED
			return CONTINUE;
65
		}
66
67
68
		@Override
69
		public FileVisitResult postVisitDirectory(Path directory, IOException thrown) throws IOException
70
		{
71
			super.postVisitDirectory(directory, thrown);
72 1 1. postVisitDirectory : mutated return of Object value for io/earcam/utilitarian/io/file/RecursiveFiles$AbstractVisitor::postVisitDirectory to ( if (x != null) null else throw new RuntimeException ) → KILLED
			return postVisitDirectory(directory);
73
		}
74
75
76
		protected abstract FileVisitResult postVisitDirectory(Path directory) throws IOException;
77
78
79
		@Override
80
		public abstract FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException;
81
	}
82
83
	private static final class DeleteVisitor extends AbstractVisitor {
84
85
		public DeleteVisitor(Path source, CopyOption... options)
86
		{
87
			super(source, source, options);
88
		}
89
90
91
		@Override
92
		public FileVisitResult postVisitDirectory(Path directory) throws IOException
93
		{
94 1 1. postVisitDirectory : removed call to java/nio/file/Files::delete → KILLED
			Files.delete(directory);
95 1 1. postVisitDirectory : mutated return of Object value for io/earcam/utilitarian/io/file/RecursiveFiles$DeleteVisitor::postVisitDirectory to ( if (x != null) null else throw new RuntimeException ) → KILLED
			return CONTINUE;
96
		}
97
98
99
		@Override
100
		public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException
101
		{
102 1 1. visitFile : removed call to java/nio/file/Files::delete → KILLED
			Files.delete(file);
103 1 1. visitFile : mutated return of Object value for io/earcam/utilitarian/io/file/RecursiveFiles$DeleteVisitor::visitFile to ( if (x != null) null else throw new RuntimeException ) → KILLED
			return CONTINUE;
104
		}
105
	}
106
107
	private static final class MoveVisitor extends AbstractVisitor {
108
109
		public MoveVisitor(Path source, Path sink, CopyOption... options)
110
		{
111
			super(source, sink, options);
112
		}
113
114
115
		@Override
116
		protected FileVisitResult postVisitDirectory(Path directory) throws IOException
117
		{
118 1 1. postVisitDirectory : removed call to java/nio/file/Files::delete → KILLED
			Files.delete(directory);
119 1 1. postVisitDirectory : mutated return of Object value for io/earcam/utilitarian/io/file/RecursiveFiles$MoveVisitor::postVisitDirectory to ( if (x != null) null else throw new RuntimeException ) → KILLED
			return CONTINUE;
120
		}
121
122
123
		@Override
124
		public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException
125
		{
126
			Files.move(file, sinkSub.resolve(file.getFileName()), options);
127 1 1. visitFile : mutated return of Object value for io/earcam/utilitarian/io/file/RecursiveFiles$MoveVisitor::visitFile to ( if (x != null) null else throw new RuntimeException ) → KILLED
			return CONTINUE;
128
		}
129
	}
130
131
	private static final class CopyVisitor extends AbstractVisitor {
132
133
		public CopyVisitor(Path source, Path sink, CopyOption... options)
134
		{
135
			super(source, sink, options);
136
		}
137
138
139
		@Override
140
		protected FileVisitResult postVisitDirectory(Path directory)
141
		{
142 1 1. postVisitDirectory : mutated return of Object value for io/earcam/utilitarian/io/file/RecursiveFiles$CopyVisitor::postVisitDirectory to ( if (x != null) null else throw new RuntimeException ) → KILLED
			return CONTINUE;
143
		}
144
145
146
		@Override
147
		public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException
148
		{
149
			Files.copy(file, sinkSub.resolve(file.getFileName()), options);
150 1 1. visitFile : mutated return of Object value for io/earcam/utilitarian/io/file/RecursiveFiles$CopyVisitor::visitFile to ( if (x != null) null else throw new RuntimeException ) → KILLED
			return CONTINUE;
151
		}
152
	}
153
154
155
	private RecursiveFiles()
156
	{}
157
158
159
	/**
160
	 * Wise to invoke this with {@link LinkOption#NOFOLLOW_LINKS}
161
	 * 
162
	 * @param path
163
	 * @param options
164
	 * @throws IOException
165
	 */
166
	public static void delete(Path path, LinkOption... options) throws IOException
167
	{
168 1 1. delete : removed call to io/earcam/utilitarian/io/file/RecursiveFiles::recurse → KILLED
		recurse(path, new DeleteVisitor(path, options));
169
	}
170
171
172
	/**
173
	 * Wise to invoke this with {@link LinkOption#NOFOLLOW_LINKS}
174
	 * 
175
	 * @param source
176
	 * @param sink
177
	 * @param options
178
	 * @throws IOException
179
	 */
180
	public static void move(Path source, Path sink, CopyOption... options) throws IOException
181
	{
182 1 1. move : removed call to io/earcam/utilitarian/io/file/RecursiveFiles::recurse → KILLED
		recurse(source, new MoveVisitor(source, sink, options));
183
	}
184
185
186
	private static void recurse(Path source, AbstractVisitor visitor) throws IOException
187
	{
188
		boolean noFollow = Arrays.asList(visitor.options).contains(NOFOLLOW_LINKS);
189 1 1. recurse : negated conditional → KILLED
		EnumSet<FileVisitOption> options = noFollow ? EnumSet.noneOf(FileVisitOption.class) : EnumSet.of(FOLLOW_LINKS);
190
191
		Files.walkFileTree(source, options, Integer.MAX_VALUE, visitor);
192
	}
193
194
195
	/**
196
	 * Wise to invoke this with {@link LinkOption#NOFOLLOW_LINKS}
197
	 * 
198
	 * @param source
199
	 * @param sink
200
	 * @param options
201
	 * @throws IOException
202
	 */
203
	public static void copy(Path source, Path sink, CopyOption... options) throws IOException
204
	{
205 1 1. copy : removed call to io/earcam/utilitarian/io/file/RecursiveFiles::recurse → KILLED
		recurse(source, new CopyVisitor(source, sink, options));
206
	}
207
}

Mutations

64

1.1
Location : preVisitDirectory
Killed by : io.earcam.utilitarian.io.file.RecursiveFilesTest.deleteStillSucceedsWhenAFileIsReadOnly()
mutated return of Object value for io/earcam/utilitarian/io/file/RecursiveFiles$AbstractVisitor::preVisitDirectory to ( if (x != null) null else throw new RuntimeException ) → KILLED

72

1.1
Location : postVisitDirectory
Killed by : io.earcam.utilitarian.io.file.RecursiveFilesTest.deleteStillSucceedsWhenAFileIsReadOnly()
mutated return of Object value for io/earcam/utilitarian/io/file/RecursiveFiles$AbstractVisitor::postVisitDirectory to ( if (x != null) null else throw new RuntimeException ) → KILLED

94

1.1
Location : postVisitDirectory
Killed by : io.earcam.utilitarian.io.file.RecursiveFilesTest.deleteStillSucceedsWhenAFileIsReadOnly()
removed call to java/nio/file/Files::delete → KILLED

95

1.1
Location : postVisitDirectory
Killed by : io.earcam.utilitarian.io.file.RecursiveFilesTest.deleteStillSucceedsWhenAFileIsReadOnly()
mutated return of Object value for io/earcam/utilitarian/io/file/RecursiveFiles$DeleteVisitor::postVisitDirectory to ( if (x != null) null else throw new RuntimeException ) → KILLED

102

1.1
Location : visitFile
Killed by : io.earcam.utilitarian.io.file.RecursiveFilesTest.deleteStillSucceedsWhenAFileIsReadOnly()
removed call to java/nio/file/Files::delete → KILLED

103

1.1
Location : visitFile
Killed by : io.earcam.utilitarian.io.file.RecursiveFilesTest.deleteStillSucceedsWhenAFileIsReadOnly()
mutated return of Object value for io/earcam/utilitarian/io/file/RecursiveFiles$DeleteVisitor::visitFile to ( if (x != null) null else throw new RuntimeException ) → KILLED

118

1.1
Location : postVisitDirectory
Killed by : io.earcam.utilitarian.io.file.RecursiveFilesTest.move()
removed call to java/nio/file/Files::delete → KILLED

119

1.1
Location : postVisitDirectory
Killed by : io.earcam.utilitarian.io.file.RecursiveFilesTest.move()
mutated return of Object value for io/earcam/utilitarian/io/file/RecursiveFiles$MoveVisitor::postVisitDirectory to ( if (x != null) null else throw new RuntimeException ) → KILLED

127

1.1
Location : visitFile
Killed by : io.earcam.utilitarian.io.file.RecursiveFilesTest.move()
mutated return of Object value for io/earcam/utilitarian/io/file/RecursiveFiles$MoveVisitor::visitFile to ( if (x != null) null else throw new RuntimeException ) → KILLED

142

1.1
Location : postVisitDirectory
Killed by : io.earcam.utilitarian.io.file.RecursiveFilesTest.deleteStillSucceedsWhenAFileIsReadOnly()
mutated return of Object value for io/earcam/utilitarian/io/file/RecursiveFiles$CopyVisitor::postVisitDirectory to ( if (x != null) null else throw new RuntimeException ) → KILLED

150

1.1
Location : visitFile
Killed by : io.earcam.utilitarian.io.file.RecursiveFilesTest.deleteStillSucceedsWhenAFileIsReadOnly()
mutated return of Object value for io/earcam/utilitarian/io/file/RecursiveFiles$CopyVisitor::visitFile to ( if (x != null) null else throw new RuntimeException ) → KILLED

168

1.1
Location : delete
Killed by : io.earcam.utilitarian.io.file.RecursiveFilesTest.deleteStillSucceedsWhenAFileIsReadOnly()
removed call to io/earcam/utilitarian/io/file/RecursiveFiles::recurse → KILLED

182

1.1
Location : move
Killed by : io.earcam.utilitarian.io.file.RecursiveFilesTest.move()
removed call to io/earcam/utilitarian/io/file/RecursiveFiles::recurse → KILLED

189

1.1
Location : recurse
Killed by : io.earcam.utilitarian.io.file.RecursiveFilesTest.doNotFollowSymbolicLink()
negated conditional → KILLED

205

1.1
Location : copy
Killed by : io.earcam.utilitarian.io.file.RecursiveFilesTest.deleteStillSucceedsWhenAFileIsReadOnly()
removed call to io/earcam/utilitarian/io/file/RecursiveFiles::recurse → KILLED

Active mutators

Tests examined


Report generated by PIT 1.4.3