78
78
* <p>Consult the Javadoc for {@link TempDir} for details on the contract.
79
79
*
80
80
* @since 5.4
81
- * @see TempDir
81
+ * @see TempDir @TempDir
82
82
* @see Files#createTempDirectory
83
83
*/
84
84
class TempDirectory implements BeforeAllCallback , BeforeEachCallback , ParameterResolver {
85
85
86
+ // package-private for testing purposes
86
87
static final Namespace NAMESPACE = Namespace .create (TempDirectory .class );
88
+ static final String FILE_OPERATIONS_KEY = "file.operations" ;
89
+
87
90
private static final String KEY = "temp.dir" ;
88
91
private static final String FAILURE_TRACKER = "failure.tracker" ;
89
92
private static final String CHILD_FAILED = "child.failed" ;
90
93
91
- // for testing purposes
92
- static final String FILE_OPERATIONS_KEY = "file.operations" ;
93
-
94
94
private final JupiterConfiguration configuration ;
95
95
96
96
public TempDirectory (JupiterConfiguration configuration ) {
@@ -127,9 +127,9 @@ public void beforeEach(ExtensionContext context) {
127
127
128
128
private static void installFailureTracker (ExtensionContext context ) {
129
129
context .getStore (NAMESPACE ).put (FAILURE_TRACKER , (CloseableResource ) () -> context .getParent () //
130
- .ifPresent (it -> {
130
+ .ifPresent (parentContext -> {
131
131
if (selfOrChildFailed (context )) {
132
- it .getStore (NAMESPACE ).put (CHILD_FAILED , true );
132
+ parentContext .getStore (NAMESPACE ).put (CHILD_FAILED , true );
133
133
}
134
134
}));
135
135
}
@@ -242,21 +242,22 @@ private TempDirFactory determineTempDirFactory(TempDir tempDir, Scope scope) {
242
242
: ReflectionSupport .newInstance (factory );
243
243
}
244
244
245
- private void assertNonFinalField (Field field ) {
245
+ private static void assertNonFinalField (Field field ) {
246
246
if (ModifierSupport .isFinal (field )) {
247
247
throw new ExtensionConfigurationException ("@TempDir field [" + field + "] must not be declared as final." );
248
248
}
249
249
}
250
250
251
- private void assertSupportedType (String target , Class <?> type ) {
251
+ private static void assertSupportedType (String target , Class <?> type ) {
252
252
if (type != Path .class && type != File .class ) {
253
253
throw new ExtensionConfigurationException ("Can only resolve @TempDir " + target + " of type "
254
254
+ Path .class .getName () + " or " + File .class .getName () + " but was: " + type .getName ());
255
255
}
256
256
}
257
257
258
- private Object getPathOrFile (Class <?> elementType , AnnotatedElementContext elementContext , TempDirFactory factory ,
259
- CleanupMode cleanupMode , Scope scope , ExtensionContext extensionContext ) {
258
+ private static Object getPathOrFile (Class <?> elementType , AnnotatedElementContext elementContext ,
259
+ TempDirFactory factory , CleanupMode cleanupMode , Scope scope , ExtensionContext extensionContext ) {
260
+
260
261
Namespace namespace = scope == Scope .PER_DECLARATION //
261
262
? NAMESPACE .append (elementContext ) //
262
263
: NAMESPACE ;
@@ -271,6 +272,7 @@ private Object getPathOrFile(Class<?> elementType, AnnotatedElementContext eleme
271
272
272
273
static CloseablePath createTempDir (TempDirFactory factory , CleanupMode cleanupMode , Class <?> elementType ,
273
274
AnnotatedElementContext elementContext , ExtensionContext extensionContext ) {
275
+
274
276
try {
275
277
return new CloseablePath (factory , cleanupMode , elementType , elementContext , extensionContext );
276
278
}
@@ -302,12 +304,12 @@ private CloseablePath(TempDirFactory factory, CleanupMode cleanupMode, Class<?>
302
304
this .annotatedElement = elementContext .getAnnotatedElement ();
303
305
this .extensionContext = extensionContext ;
304
306
305
- if (dir == null || !Files .isDirectory (dir )) {
307
+ if (this . dir == null || !Files .isDirectory (this . dir )) {
306
308
close ();
307
309
throw new PreconditionViolationException ("temp directory must be a directory" );
308
310
}
309
311
310
- if (elementType == File .class && !dir .getFileSystem ().equals (FileSystems .getDefault ())) {
312
+ if (elementType == File .class && !this . dir .getFileSystem ().equals (FileSystems .getDefault ())) {
311
313
close ();
312
314
throw new PreconditionViolationException (
313
315
"temp directory with non-default file system cannot be injected into " + File .class .getName ()
@@ -316,19 +318,20 @@ private CloseablePath(TempDirFactory factory, CleanupMode cleanupMode, Class<?>
316
318
}
317
319
318
320
Path get () {
319
- return dir ;
321
+ return this . dir ;
320
322
}
321
323
322
324
@ Override
323
325
public void close () throws IOException {
324
326
try {
325
- if (cleanupMode == NEVER || (cleanupMode == ON_SUCCESS && selfOrChildFailed (extensionContext ))) {
327
+ if (this .cleanupMode == NEVER
328
+ || (this .cleanupMode == ON_SUCCESS && selfOrChildFailed (this .extensionContext ))) {
326
329
logger .info (() -> String .format ("Skipping cleanup of temp dir %s for %s due to CleanupMode.%s." ,
327
- dir , descriptionFor (annotatedElement ), cleanupMode .name ()));
330
+ this . dir , descriptionFor (this . annotatedElement ), this . cleanupMode .name ()));
328
331
return ;
329
332
}
330
333
331
- FileOperations fileOperations = extensionContext .getStore (NAMESPACE ) //
334
+ FileOperations fileOperations = this . extensionContext .getStore (NAMESPACE ) //
332
335
.getOrDefault (FILE_OPERATIONS_KEY , FileOperations .class , FileOperations .DEFAULT );
333
336
334
337
SortedMap <Path , IOException > failures = deleteAllFilesAndDirectories (fileOperations );
@@ -337,7 +340,7 @@ public void close() throws IOException {
337
340
}
338
341
}
339
342
finally {
340
- factory .close ();
343
+ this . factory .close ();
341
344
}
342
345
}
343
346
@@ -370,14 +373,15 @@ private static String descriptionFor(Executable executable) {
370
373
371
374
private SortedMap <Path , IOException > deleteAllFilesAndDirectories (FileOperations fileOperations )
372
375
throws IOException {
373
- if (dir == null || Files .notExists (dir )) {
376
+
377
+ if (this .dir == null || Files .notExists (this .dir )) {
374
378
return Collections .emptySortedMap ();
375
379
}
376
380
377
381
SortedMap <Path , IOException > failures = new TreeMap <>();
378
382
Set <Path > retriedPaths = new HashSet <>();
379
- tryToResetPermissions (dir );
380
- Files .walkFileTree (dir , new SimpleFileVisitor <Path >() {
383
+ tryToResetPermissions (this . dir );
384
+ Files .walkFileTree (this . dir , new SimpleFileVisitor <Path >() {
381
385
382
386
@ Override
383
387
public FileVisitResult preVisitDirectory (Path dir , BasicFileAttributes attrs ) {
@@ -482,7 +486,7 @@ private IOException createIOExceptionWithAttachedFailures(SortedMap<Path, IOExce
482
486
.map (this ::relativizeSafely ) //
483
487
.map (path -> emptyPath .equals (path ) ? "<root>" : path .toString ()) //
484
488
.collect (joining (", " ));
485
- IOException exception = new IOException ("Failed to delete temp directory " + dir .toAbsolutePath ()
489
+ IOException exception = new IOException ("Failed to delete temp directory " + this . dir .toAbsolutePath ()
486
490
+ ". The following paths could not be deleted (see suppressed exceptions for details): "
487
491
+ joinedPaths );
488
492
failures .values ().forEach (exception ::addSuppressed );
@@ -500,7 +504,7 @@ private Path tryToDeleteOnExit(Path path) {
500
504
501
505
private Path relativizeSafely (Path path ) {
502
506
try {
503
- return dir .relativize (path );
507
+ return this . dir .relativize (path );
504
508
}
505
509
catch (IllegalArgumentException e ) {
506
510
return path ;
0 commit comments