Skip to content

Commit 44eb8c3

Browse files
committed
Align ApplicationTemp with Files.createTempDirectory
Update `ApplicationTemp` to align the way that it creates temp folders with the way that `Files.createTempDirectory` works. Closes gh-27857
1 parent 7cec0b3 commit 44eb8c3

File tree

2 files changed

+91
-22
lines changed

2 files changed

+91
-22
lines changed

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/system/ApplicationTemp.java

Lines changed: 55 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2019 the original author or authors.
2+
* Copyright 2012-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,7 +17,16 @@
1717
package org.springframework.boot.system;
1818

1919
import java.io.File;
20+
import java.io.IOException;
21+
import java.nio.file.FileSystem;
22+
import java.nio.file.Files;
23+
import java.nio.file.Path;
24+
import java.nio.file.Paths;
25+
import java.nio.file.attribute.FileAttribute;
26+
import java.nio.file.attribute.PosixFilePermission;
27+
import java.nio.file.attribute.PosixFilePermissions;
2028
import java.security.MessageDigest;
29+
import java.util.EnumSet;
2130

2231
import org.springframework.util.Assert;
2332
import org.springframework.util.StringUtils;
@@ -34,9 +43,14 @@ public class ApplicationTemp {
3443

3544
private static final char[] HEX_CHARS = "0123456789ABCDEF".toCharArray();
3645

46+
private static final FileAttribute<?>[] NO_FILE_ATTRIBUTES = {};
47+
48+
private static final EnumSet<PosixFilePermission> DIRECTORY_PERMISSIONS = EnumSet.of(PosixFilePermission.OWNER_READ,
49+
PosixFilePermission.OWNER_WRITE, PosixFilePermission.OWNER_EXECUTE);
50+
3751
private final Class<?> sourceClass;
3852

39-
private volatile File dir;
53+
private volatile Path path;
4054

4155
/**
4256
* Create a new {@link ApplicationTemp} instance.
@@ -58,40 +72,60 @@ public String toString() {
5872
return getDir().getAbsolutePath();
5973
}
6074

75+
/**
76+
* Return the directory to be used for application specific temp files.
77+
* @return the application temp directory
78+
*/
79+
public File getDir() {
80+
return getPath().toFile();
81+
}
82+
6183
/**
6284
* Return a sub-directory of the application temp.
6385
* @param subDir the sub-directory name
6486
* @return a sub-directory
6587
*/
6688
public File getDir(String subDir) {
67-
File dir = new File(getDir(), subDir);
68-
dir.mkdirs();
69-
return dir;
89+
return createDirectory(getPath().resolve(subDir)).toFile();
7090
}
7191

72-
/**
73-
* Return the directory to be used for application specific temp files.
74-
* @return the application temp directory
75-
*/
76-
public File getDir() {
77-
if (this.dir == null) {
92+
private Path getPath() {
93+
if (this.path == null) {
7894
synchronized (this) {
79-
byte[] hash = generateHash(this.sourceClass);
80-
this.dir = new File(getTempDirectory(), toHexString(hash));
81-
this.dir.mkdirs();
82-
Assert.state(this.dir.exists(), () -> "Unable to create temp directory " + this.dir);
95+
String hash = toHexString(generateHash(this.sourceClass));
96+
this.path = createDirectory(getTempDirectory().resolve(hash));
8397
}
8498
}
85-
return this.dir;
99+
return this.path;
100+
}
101+
102+
private Path createDirectory(Path path) {
103+
try {
104+
if (!Files.exists(path)) {
105+
Files.createDirectory(path, getFileAttributes(path.getFileSystem(), DIRECTORY_PERMISSIONS));
106+
}
107+
return path;
108+
}
109+
catch (IOException ex) {
110+
throw new IllegalStateException("Unable to create application temp directory " + path, ex);
111+
}
112+
}
113+
114+
private FileAttribute<?>[] getFileAttributes(FileSystem fileSystem, EnumSet<PosixFilePermission> ownerReadWrite) {
115+
if (!fileSystem.supportedFileAttributeViews().contains("posix")) {
116+
return NO_FILE_ATTRIBUTES;
117+
}
118+
return new FileAttribute<?>[] { PosixFilePermissions.asFileAttribute(ownerReadWrite) };
86119
}
87120

88-
private File getTempDirectory() {
121+
private Path getTempDirectory() {
89122
String property = System.getProperty("java.io.tmpdir");
90123
Assert.state(StringUtils.hasLength(property), "No 'java.io.tmpdir' property set");
91-
File file = new File(property);
92-
Assert.state(file.exists(), () -> "Temp directory " + file + " does not exist");
93-
Assert.state(file.isDirectory(), () -> "Temp location " + file + " is not a directory");
94-
return file;
124+
Path tempDirectory = Paths.get(property);
125+
Assert.state(Files.exists(tempDirectory), () -> "Temp directory '" + tempDirectory + "' does not exist");
126+
Assert.state(Files.isDirectory(tempDirectory),
127+
() -> "Temp location '" + tempDirectory + "' is not a directory");
128+
return tempDirectory;
95129
}
96130

97131
private byte[] generateHash(Class<?> sourceClass) {

spring-boot-project/spring-boot/src/test/java/org/springframework/boot/system/ApplicationTempTests.java

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2019 the original author or authors.
2+
* Copyright 2012-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,9 +17,20 @@
1717
package org.springframework.boot.system;
1818

1919
import java.io.File;
20+
import java.io.IOException;
21+
import java.nio.file.FileSystem;
22+
import java.nio.file.Files;
23+
import java.nio.file.Path;
24+
import java.nio.file.attribute.PosixFileAttributeView;
25+
import java.nio.file.attribute.PosixFilePermission;
26+
import java.util.Set;
2027

28+
import org.junit.jupiter.api.AfterEach;
29+
import org.junit.jupiter.api.BeforeEach;
2130
import org.junit.jupiter.api.Test;
2231

32+
import org.springframework.util.FileSystemUtils;
33+
2334
import static org.assertj.core.api.Assertions.assertThat;
2435

2536
/**
@@ -29,6 +40,12 @@
2940
*/
3041
class ApplicationTempTests {
3142

43+
@BeforeEach
44+
@AfterEach
45+
void cleanup() {
46+
FileSystemUtils.deleteRecursively(new ApplicationTemp().getDir());
47+
}
48+
3249
@Test
3350
void generatesConsistentTemp() {
3451
ApplicationTemp t1 = new ApplicationTemp();
@@ -57,4 +74,22 @@ void getSubDir() {
5774
assertThat(temp.getDir("abc")).isEqualTo(new File(temp.getDir(), "abc"));
5875
}
5976

77+
@Test
78+
void posixPermissions() throws IOException {
79+
ApplicationTemp temp = new ApplicationTemp();
80+
Path path = temp.getDir().toPath();
81+
FileSystem fileSystem = path.getFileSystem();
82+
if (fileSystem.supportedFileAttributeViews().contains("posix")) {
83+
assertDirectoryPermissions(path);
84+
assertDirectoryPermissions(temp.getDir("sub").toPath());
85+
}
86+
}
87+
88+
private void assertDirectoryPermissions(Path path) throws IOException {
89+
Set<PosixFilePermission> permissions = Files.getFileAttributeView(path, PosixFileAttributeView.class)
90+
.readAttributes().permissions();
91+
assertThat(permissions).containsExactlyInAnyOrder(PosixFilePermission.OWNER_READ,
92+
PosixFilePermission.OWNER_WRITE, PosixFilePermission.OWNER_EXECUTE);
93+
}
94+
6095
}

0 commit comments

Comments
 (0)