/*
 * Copyright 2012-2019 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.boot.system;

import java.io.File;
import java.security.MessageDigest;

import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

Provides access to an application specific temporary directory. Generally speaking different Spring Boot applications will get different locations, however, simply restarting an application will give the same location.
Author:Phillip Webb
Since:2.0.0
/** * Provides access to an application specific temporary directory. Generally speaking * different Spring Boot applications will get different locations, however, simply * restarting an application will give the same location. * * @author Phillip Webb * @since 2.0.0 */
public class ApplicationTemp { private static final char[] HEX_CHARS = "0123456789ABCDEF".toCharArray(); private final Class<?> sourceClass; private volatile File dir;
Create a new ApplicationTemp instance.
/** * Create a new {@link ApplicationTemp} instance. */
public ApplicationTemp() { this(null); }
Create a new ApplicationTemp instance for the specified source class.
Params:
  • sourceClass – the source class or null
/** * Create a new {@link ApplicationTemp} instance for the specified source class. * @param sourceClass the source class or {@code null} */
public ApplicationTemp(Class<?> sourceClass) { this.sourceClass = sourceClass; } @Override public String toString() { return getDir().getAbsolutePath(); }
Return a sub-directory of the application temp.
Params:
  • subDir – the sub-directory name
Returns:a sub-directory
/** * Return a sub-directory of the application temp. * @param subDir the sub-directory name * @return a sub-directory */
public File getDir(String subDir) { File dir = new File(getDir(), subDir); dir.mkdirs(); return dir; }
Return the directory to be used for application specific temp files.
Returns:the application temp directory
/** * Return the directory to be used for application specific temp files. * @return the application temp directory */
public File getDir() { if (this.dir == null) { synchronized (this) { byte[] hash = generateHash(this.sourceClass); this.dir = new File(getTempDirectory(), toHexString(hash)); this.dir.mkdirs(); Assert.state(this.dir.exists(), () -> "Unable to create temp directory " + this.dir); } } return this.dir; } private File getTempDirectory() { String property = System.getProperty("java.io.tmpdir"); Assert.state(StringUtils.hasLength(property), "No 'java.io.tmpdir' property set"); File file = new File(property); Assert.state(file.exists(), () -> "Temp directory " + file + " does not exist"); Assert.state(file.isDirectory(), () -> "Temp location " + file + " is not a directory"); return file; } private byte[] generateHash(Class<?> sourceClass) { ApplicationHome home = new ApplicationHome(sourceClass); MessageDigest digest; try { digest = MessageDigest.getInstance("SHA-1"); update(digest, home.getSource()); update(digest, home.getDir()); update(digest, System.getProperty("user.dir")); update(digest, System.getProperty("java.home")); update(digest, System.getProperty("java.class.path")); update(digest, System.getProperty("sun.java.command")); update(digest, System.getProperty("sun.boot.class.path")); return digest.digest(); } catch (Exception ex) { throw new IllegalStateException(ex); } } private void update(MessageDigest digest, Object source) { if (source != null) { digest.update(getUpdateSourceBytes(source)); } } private byte[] getUpdateSourceBytes(Object source) { if (source instanceof File) { return getUpdateSourceBytes(((File) source).getAbsolutePath()); } return source.toString().getBytes(); } private String toHexString(byte[] bytes) { char[] hex = new char[bytes.length * 2]; for (int i = 0; i < bytes.length; i++) { int b = bytes[i] & 0xFF; hex[i * 2] = HEX_CHARS[b >>> 4]; hex[i * 2 + 1] = HEX_CHARS[b & 0x0F]; } return new String(hex); } }