private static final Logger LOG = LoggerFactory.getLogger(PluginDownloader.class);
- private TempDirectories tempDirs;
+ private TempDirectories workingDirectories;
private ServerClient server;
- public PluginDownloader(TempDirectories tempDirs, ServerClient server) {
- this.tempDirs = tempDirs;
+ public PluginDownloader(TempDirectories workingDirectories, ServerClient server) {
+ this.workingDirectories = workingDirectories;
this.server = server;
}
public List<File> downloadPlugin(RemotePlugin remote) {
try {
- File targetDir = tempDirs.getDir("plugins/" + remote.getKey());
+ File targetDir = workingDirectories.getDir("plugins/" + remote.getKey());
FileUtils.forceMkdir(targetDir);
LOG.debug("Downloading plugin " + remote.getKey() + " into " + targetDir);
*/
package org.sonar.batch.bootstrap;
+import com.google.common.collect.Maps;
import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.filefilter.AgeFileFilter;
+import org.apache.commons.io.filefilter.AndFileFilter;
+import org.apache.commons.io.filefilter.DirectoryFileFilter;
+import org.apache.commons.io.filefilter.PrefixFileFilter;
import org.apache.commons.lang.StringUtils;
-import org.sonar.api.batch.bootstrap.ProjectReactor;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.utils.SonarException;
+import org.sonar.api.utils.TempFileUtils;
import java.io.File;
+import java.io.FileFilter;
import java.io.IOException;
+import java.util.Arrays;
+import java.util.Map;
public class TempDirectories {
+ public static final String DIR_PREFIX = "sonar-batch";
+
+ // this timeout must be greater than the longest analysis
+ public static final int AGE_BEFORE_DELETION = 24 * 60 * 60 * 1000;
+
private File rootDir;
+ private Map<String, File> directoriesByKey = Maps.newHashMap();
- public TempDirectories(ProjectReactor reactor) throws IOException {
- this.rootDir = new File(reactor.getRoot().getWorkDir(), "_tmp");
- if (rootDir.exists()) {
- FileUtils.deleteDirectory(rootDir);
- }
- FileUtils.forceMkdir(rootDir);
+ public TempDirectories() throws IOException {
+ this.rootDir = TempFileUtils.createTempDirectory(DIR_PREFIX);
+ LoggerFactory.getLogger(getClass()).debug("Temporary directory: " + rootDir.getAbsolutePath());
}
public File getRoot() {
return rootDir;
}
- public void stop() {
- FileUtils.deleteQuietly(rootDir);
- }
-
/**
* Get or create a working directory
*/
- public File getDir(String dirname) {
- if (StringUtils.isBlank(dirname)) {
+ public File getDir(String key) {
+ if (StringUtils.isBlank(key)) {
return rootDir;
}
- File dir = new File(rootDir, dirname);
- try {
- FileUtils.forceMkdir(dir);
- return dir;
- } catch (IOException e) {
- throw new IllegalStateException("Fail to create temp directory: " + dir, e);
+ File dir = directoriesByKey.get(key);
+ if (dir == null) {
+ dir = new File(rootDir, key);
+ try {
+ FileUtils.forceMkdir(dir);
+ directoriesByKey.put(key, dir);
+
+ } catch (IOException e) {
+ throw new SonarException("Can not create the temp directory: " + dir, e);
+ }
}
+ return dir;
}
- public File getFile(String dirname, String filename) {
- File dir = getDir(dirname);
+ public File getFile(String directoryKey, String filename) {
+ File dir = getDir(directoryKey);
return new File(dir, filename);
}
+
+ /**
+ * This method is executed by picocontainer during shutdown.
+ */
+ public void stop() {
+ directoriesByKey.clear();
+
+ // Deleting temp directory does not work on MS Windows and Sun JVM because URLClassLoader locks JARs and resources.
+ // The workaround is that sonar deletes orphans itself.
+
+ // older than AGE_BEFORE_DELETION to be sure that the current dir is deleted on mac and linux.
+ rootDir.setLastModified(System.currentTimeMillis() - AGE_BEFORE_DELETION - 60 * 60 * 1000);
+
+ File[] directoriesToDelete = rootDir.getParentFile().listFiles((FileFilter) new AndFileFilter(Arrays.asList(
+ DirectoryFileFilter.DIRECTORY, new PrefixFileFilter(DIR_PREFIX), new AgeFileFilter(System.currentTimeMillis() - AGE_BEFORE_DELETION))));
+ for (File dir : directoriesToDelete) {
+ LoggerFactory.getLogger(getClass()).debug("Delete temporary directory: " + dir);
+ FileUtils.deleteQuietly(dir);
+ }
+ }
}
*/
package org.sonar.batch.bootstrap;
-import com.google.common.io.Files;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.filefilter.IOFileFilter;
+import org.junit.After;
import org.junit.Before;
-import org.junit.Rule;
import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.sonar.api.batch.bootstrap.ProjectDefinition;
-import org.sonar.api.batch.bootstrap.ProjectReactor;
import java.io.File;
import java.io.IOException;
public class TempDirectoriesTest {
- @Rule
- public TemporaryFolder folder = new TemporaryFolder();
-
- TempDirectories tempDirectories;
- File workDir;
- ProjectReactor reactor;
+ private TempDirectories tempDirectories;
@Before
public void before() throws IOException {
- workDir = folder.newFolder();
- ProjectDefinition project = ProjectDefinition.create().setKey("foo").setWorkDir(workDir);
- reactor = new ProjectReactor(project);
+ tempDirectories = new TempDirectories();
}
- @Test
- public void should_create_root_temp_dir() throws IOException {
- tempDirectories = new TempDirectories(reactor);
- assertThat(tempDirectories.getRoot()).isNotNull();
- assertThat(tempDirectories.getRoot()).exists();
- assertThat(tempDirectories.getRoot()).isDirectory();
- assertThat(tempDirectories.getRoot().getName()).isEqualTo("_tmp");
+ @After
+ public void after() {
+ if (tempDirectories != null) {
+ tempDirectories.stop();
+ }
}
@Test
- public void should_clean_root_temp_dir_at_startup() throws IOException {
- File tempFile = new File(workDir, "_tmp/foo.txt");
- FileUtils.touch(tempFile);
- assertThat(tempFile).exists();
-
- tempDirectories = new TempDirectories(reactor);
- assertThat(tempDirectories.getRoot().getParentFile()).isEqualTo(workDir);
+ public void shouldCreateRoot() {
+ assertThat(tempDirectories.getRoot()).isNotNull();
assertThat(tempDirectories.getRoot()).exists();
- assertThat(tempFile).doesNotExist();
- assertThat(FileUtils.listFiles(tempDirectories.getRoot(), new String[]{"txt"}, true)).isEmpty();
- }
-
- @Test
- public void should_accept_empty_dirname() throws IOException {
- tempDirectories = new TempDirectories(reactor);
+ assertThat(tempDirectories.getRoot()).isDirectory();
assertThat(tempDirectories.getDir("")).isEqualTo(tempDirectories.getRoot());
}
@Test
- public void should_create_sub_directory() throws IOException {
- tempDirectories = new TempDirectories(reactor);
+ public void shouldCreateDirectory() {
File findbugsDir = tempDirectories.getDir("findbugs");
assertThat(findbugsDir).isNotNull();
assertThat(findbugsDir).exists();
}
@Test
- public void should_delete_temp_dir_on_shutdown() throws IOException {
- tempDirectories = new TempDirectories(reactor);
+ public void shouldStopAndDeleteDirectory() {
File root = tempDirectories.getRoot();
File findbugsDir = tempDirectories.getDir("findbugs");
assertThat(findbugsDir).exists();
}
@Test
- public void should_create_parent_directory() throws IOException {
- tempDirectories = new TempDirectories(reactor);
+ public void shouldCreateDirectoryWhenGettingFile() {
File file = tempDirectories.getFile("findbugs", "bcel.jar");
assertThat(file).isNotNull();
assertThat(file.getParentFile().getName()).isEqualTo("findbugs");