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.
1717package org .springframework .boot .system ;
1818
1919import 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 ;
2028import java .security .MessageDigest ;
29+ import java .util .EnumSet ;
2130
2231import org .springframework .util .Assert ;
2332import 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 ) {
0 commit comments