001/*
002 * SonarQube
003 * Copyright (C) 2009-2017 SonarSource SA
004 * mailto:info AT sonarsource DOT com
005 *
006 * This program is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Lesser General Public
008 * License as published by the Free Software Foundation; either
009 * version 3 of the License, or (at your option) any later version.
010 *
011 * This program is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014 * Lesser General Public License for more details.
015 *
016 * You should have received a copy of the GNU Lesser General Public License
017 * along with this program; if not, write to the Free Software Foundation,
018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
019 */
020package org.sonar.api.utils.internal;
021
022import java.nio.file.FileVisitResult;
023import java.nio.file.SimpleFileVisitor;
024import java.nio.file.attribute.BasicFileAttributes;
025import org.apache.commons.io.FileUtils;
026import org.sonar.api.utils.TempFolder;
027
028import javax.annotation.Nullable;
029
030import java.io.File;
031import java.io.IOException;
032import java.nio.file.Files;
033import java.nio.file.Path;
034import org.sonar.api.utils.log.Logger;
035import org.sonar.api.utils.log.Loggers;
036
037public class DefaultTempFolder implements TempFolder {
038  private static final Logger LOG = Loggers.get(DefaultTempFolder.class);
039
040  private final File tempDir;
041  private final boolean deleteOnExit;
042
043  public DefaultTempFolder(File tempDir) {
044    this(tempDir, false);
045  }
046
047  public DefaultTempFolder(File tempDir, boolean deleteOnExit) {
048    this.tempDir = tempDir;
049    this.deleteOnExit = deleteOnExit;
050  }
051
052  @Override
053  public File newDir() {
054    return createTempDir(tempDir.toPath()).toFile();
055  }
056
057  private static Path createTempDir(Path baseDir) {
058    try {
059      return Files.createTempDirectory(baseDir, null);
060    } catch (IOException e) {
061      throw new IllegalStateException("Failed to create temp directory", e);
062    }
063  }
064
065  @Override
066  public File newDir(String name) {
067    File dir = new File(tempDir, name);
068    try {
069      FileUtils.forceMkdir(dir);
070    } catch (IOException e) {
071      throw new IllegalStateException("Failed to create temp directory - " + dir, e);
072    }
073    return dir;
074  }
075
076  @Override
077  public File newFile() {
078    return newFile(null, null);
079  }
080
081  @Override
082  public File newFile(@Nullable String prefix, @Nullable String suffix) {
083    return createTempFile(tempDir.toPath(), prefix, suffix).toFile();
084  }
085
086  private static Path createTempFile(Path baseDir, String prefix, String suffix) {
087    try {
088      return Files.createTempFile(baseDir, prefix, suffix);
089    } catch (IOException e) {
090      throw new IllegalStateException("Failed to create temp file", e);
091    }
092  }
093
094  public void clean() {
095    try {
096      Files.walkFileTree(tempDir.toPath(), DeleteRecursivelyFileVisitor.INSTANCE);
097    } catch (IOException e) {
098      LOG.error("Failed to delete temp folder", e);
099    }
100  }
101
102  public void stop() {
103    if (deleteOnExit) {
104      clean();
105    }
106  }
107
108  private static final class DeleteRecursivelyFileVisitor extends SimpleFileVisitor<Path> {
109    public static final DeleteRecursivelyFileVisitor INSTANCE = new DeleteRecursivelyFileVisitor();
110
111    @Override
112    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
113      Files.delete(file);
114      return FileVisitResult.CONTINUE;
115    }
116
117    @Override
118    public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
119      Files.delete(dir);
120      return FileVisitResult.CONTINUE;
121    }
122  }
123
124}