Unify application folder logic

This commit is contained in:
Reinhard Pointner 2016-03-11 11:14:50 +00:00
parent 5f6f45a26b
commit bed6732d35
7 changed files with 121 additions and 101 deletions

View File

@ -26,10 +26,12 @@ public class CacheManager {
} }
private final net.sf.ehcache.CacheManager manager; private final net.sf.ehcache.CacheManager manager;
private final File diskStore;
public CacheManager() { public CacheManager() {
try { try {
this.manager = net.sf.ehcache.CacheManager.create(getConfiguration()); this.diskStore = acquireDiskStore();
this.manager = net.sf.ehcache.CacheManager.create(new Configuration().diskStore(new DiskStoreConfiguration().path(diskStore.getPath())));
} catch (IOException e) { } catch (IOException e) {
throw new CacheException(e); throw new CacheException(e);
} }
@ -47,19 +49,13 @@ public class CacheManager {
manager.removeAllCaches(); manager.removeAllCaches();
// clear all caches that have not been added yet // clear all caches that have not been added yet
clearDiskStore(new File(manager.getConfiguration().getDiskStoreConfiguration().getPath())); clearDiskStore(diskStore);
} }
public synchronized void shutdown() { public synchronized void shutdown() {
manager.shutdown(); manager.shutdown();
} }
private Configuration getConfiguration() throws IOException {
Configuration config = new Configuration();
config.addDiskStore(getDiskStoreConfiguration());
return config;
}
private void clearDiskStore(File cache) { private void clearDiskStore(File cache) {
getChildren(cache).stream().filter(f -> f.isFile() && !f.getName().startsWith(".")).forEach(f -> { getChildren(cache).stream().filter(f -> f.isFile() && !f.getName().startsWith(".")).forEach(f -> {
if (!delete(f)) { if (!delete(f)) {
@ -68,9 +64,9 @@ public class CacheManager {
}); });
} }
private DiskStoreConfiguration getDiskStoreConfiguration() throws IOException { private File acquireDiskStore() throws IOException {
// prepare cache folder for this application instance // prepare cache folder for this application instance
File cacheRoot = getApplicationCache().getCanonicalFile(); File cacheRoot = ApplicationFolder.Cache.getCanonicalFile();
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
File cache = new File(cacheRoot, Integer.toString(i)); File cache = new File(cacheRoot, Integer.toString(i));
@ -116,7 +112,7 @@ public class CacheManager {
Runtime.getRuntime().addShutdownHook(new ShutdownHook(this, channel, lock)); Runtime.getRuntime().addShutdownHook(new ShutdownHook(this, channel, lock));
// cache for this application instance is successfully set up and locked // cache for this application instance is successfully set up and locked
return new DiskStoreConfiguration().path(cache.getPath()); return cache;
} }
// try next lock file // try next lock file
@ -130,7 +126,6 @@ public class CacheManager {
private static class ShutdownHook extends Thread { private static class ShutdownHook extends Thread {
private final CacheManager manager; private final CacheManager manager;
private final FileChannel channel; private final FileChannel channel;
private final FileLock lock; private final FileLock lock;

View File

@ -39,7 +39,7 @@ public final class HistorySpooler {
}); });
} }
private File persistentHistoryFile = new File(getApplicationFolder(), "history.xml"); private File persistentHistoryFile = ApplicationFolder.AppData.resolve("history.xml");
private int persistentHistoryTotalSize = -1; private int persistentHistoryTotalSize = -1;
private boolean persistentHistoryEnabled = true; private boolean persistentHistoryEnabled = true;

View File

@ -43,6 +43,7 @@ import javax.swing.UIManager;
import org.kohsuke.args4j.CmdLineException; import org.kohsuke.args4j.CmdLineException;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import net.filebot.Settings.ApplicationFolder;
import net.filebot.cli.ArgumentBean; import net.filebot.cli.ArgumentBean;
import net.filebot.cli.ArgumentProcessor; import net.filebot.cli.ArgumentProcessor;
import net.filebot.format.ExpressionFormat; import net.filebot.format.ExpressionFormat;
@ -85,7 +86,7 @@ public class Main {
// clear preferences and cache // clear preferences and cache
if (args.clearCache()) { if (args.clearCache()) {
System.out.println("Clear cache and temporary files"); System.out.println("Clear cache and temporary files");
for (File folder : getChildren(getApplicationFolder().getCanonicalFile(), FOLDERS)) { for (File folder : getChildren(ApplicationFolder.AppData.getCanonicalFile(), FOLDERS)) {
System.out.println("* Delete " + folder); System.out.println("* Delete " + folder);
delete(folder); delete(folder);
} }
@ -104,7 +105,7 @@ public class Main {
initializeLogging(args); initializeLogging(args);
// make sure java.io.tmpdir exists // make sure java.io.tmpdir exists
createFolders(getApplicationTempFolder()); createFolders(ApplicationFolder.Temp.get());
// initialize this stuff before anything else // initialize this stuff before anything else
CacheManager.getInstance(); CacheManager.getInstance();
@ -410,7 +411,7 @@ public class Main {
System.setProperty("sun.net.client.defaultReadTimeout", "60000"); System.setProperty("sun.net.client.defaultReadTimeout", "60000");
System.setProperty("swing.crossplatformlaf", "javax.swing.plaf.nimbus.NimbusLookAndFeel"); System.setProperty("swing.crossplatformlaf", "javax.swing.plaf.nimbus.NimbusLookAndFeel");
System.setProperty("grape.root", new File(getApplicationFolder(), "grape").getAbsolutePath()); System.setProperty("grape.root", ApplicationFolder.AppData.resolve("grape").getAbsolutePath());
System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.NoOpLog"); System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.NoOpLog");
System.setProperty("unixfs", Boolean.toString(args.unixfs)); System.setProperty("unixfs", Boolean.toString(args.unixfs));
@ -424,7 +425,7 @@ public class Main {
if (args.logFile != null) { if (args.logFile != null) {
File logFile = new File(args.logFile); File logFile = new File(args.logFile);
if (!logFile.isAbsolute()) { if (!logFile.isAbsolute()) {
logFile = new File(new File(getApplicationFolder(), "logs"), logFile.getPath()).getAbsoluteFile(); // by default resolve relative paths against {applicationFolder}/logs/{logFile} logFile = new File(ApplicationFolder.AppData.resolve("logs"), logFile.getPath()).getAbsoluteFile(); // by default resolve relative paths against {applicationFolder}/logs/{logFile}
} }
if (!logFile.exists() && !logFile.getParentFile().mkdirs() && !logFile.createNewFile()) { if (!logFile.exists() && !logFile.getParentFile().mkdirs() && !logFile.createNewFile()) {
throw new IOException("Failed to create log file: " + logFile); throw new IOException("Failed to create log file: " + logFile);
@ -459,7 +460,7 @@ public class Main {
// log errors to file // log errors to file
try { try {
Handler error = createSimpleFileHandler(new File(getApplicationFolder(), "error.log"), Level.WARNING); Handler error = createSimpleFileHandler(ApplicationFolder.AppData.resolve("error.log"), Level.WARNING);
log.addHandler(error); log.addHandler(error);
debug.addHandler(error); debug.addHandler(error);
} catch (Exception e) { } catch (Exception e) {

View File

@ -135,58 +135,6 @@ public final class Settings {
return Runtime.getRuntime().availableProcessors(); return Runtime.getRuntime().availableProcessors();
} }
public static File getApplicationFolder() {
String applicationFolderPath = System.getProperty("application.dir");
File applicationFolder = null;
if (applicationFolderPath != null && !applicationFolderPath.isEmpty()) {
// use given path
applicationFolder = new File(applicationFolderPath);
} else {
// create folder in user home (can't use working directory for web start applications)
applicationFolder = new File(System.getProperty("user.home"), ".filebot");
}
// create folder if necessary
try {
createFolders(applicationFolder);
} catch (Exception e) {
throw new IllegalStateException("application.dir", e);
}
return applicationFolder;
}
public static File getApplicationCache() {
String cacheFolderPath = System.getProperty("application.cache");
File cacheFolder = null;
if (cacheFolderPath != null && !cacheFolderPath.isEmpty()) {
cacheFolder = new File(cacheFolderPath);
} else {
cacheFolder = new File(getApplicationFolder(), "cache");
}
return cacheFolder;
}
public static File getApplicationTempFolder() {
return new File(System.getProperty("java.io.tmpdir"));
}
public static File getRealUserHome() {
if (isMacSandbox()) {
// when running sandboxed applications user.home may point to the application-specific container
String username = System.getProperty("user.name");
if (username != null && username.length() > 0) {
return new File("/Users", username);
}
}
// default home
return new File(System.getProperty("user.home"));
}
public static String getAppStoreName() { public static String getAppStoreName() {
if (isMacApp()) if (isMacApp())
return "Mac App Store"; return "Mac App Store";
@ -235,6 +183,104 @@ public final class Settings {
return links; return links;
} }
public static String getApplicationIdentifier() {
return String.format("%s %s (r%d)", getApplicationName(), getApplicationVersion(), getApplicationRevisionNumber());
}
public static String getJavaRuntimeIdentifier() {
return String.format("%s %s %s", System.getProperty("java.runtime.name"), System.getProperty("java.version"), GraphicsEnvironment.isHeadless() ? "(headless)" : "").trim();
}
private static String[] applicationArgumentArray;
protected static void setApplicationArgumentArray(String[] args) {
applicationArgumentArray = args;
}
public static ArgumentBean getApplicationArguments() {
try {
return ArgumentBean.parse(applicationArgumentArray);
} catch (Exception e) {
throw new IllegalStateException(e);
}
}
public static enum ApplicationFolder {
AppData {
@Override
public File get() {
String appdata = System.getProperty("application.dir");
if (appdata != null) {
// use given $APP_DATA folder
return new File(appdata);
} else {
// use $HOME/.filebot as application data folder
return new File(System.getProperty("user.home"), ".filebot");
}
}
},
UserHome {
@Override
public File get() {
// The user.home of sandboxed applications will point to the application-specific container
if (isMacSandbox()) {
return new File("/Users", System.getProperty("user.name", "anonymous"));
}
// default user home
return new File(System.getProperty("user.home"));
}
},
Temp {
@Override
public File get() {
return new File(System.getProperty("java.io.tmpdir"));
}
},
Cache {
@Override
public File get() {
String cache = System.getProperty("application.cache");
if (cache != null) {
return new File(cache);
}
// default to $APP_DATA/cache
return AppData.resolve("cache");
}
};
public abstract File get();
public File resolve(String name) {
return new File(getCanonicalFile(), name);
}
public File getCanonicalFile() {
File path = get();
try {
if (!path.isDirectory()) {
createFolders(path);
}
return path.getCanonicalFile();
} catch (Exception e) {
debug.log(Level.SEVERE, String.format("Failed to create application folder: %s => %s", this, path), e);
return path;
}
}
}
public static Settings forPackage(Class<?> type) { public static Settings forPackage(Class<?> type) {
return new Settings(Preferences.userNodeForPackage(type)); return new Settings(Preferences.userNodeForPackage(type));
} }
@ -295,26 +341,4 @@ public final class Settings {
} }
} }
public static String getApplicationIdentifier() {
return String.format("%s %s (r%d)", getApplicationName(), getApplicationVersion(), getApplicationRevisionNumber());
}
public static String getJavaRuntimeIdentifier() {
return String.format("%s %s %s", System.getProperty("java.runtime.name"), System.getProperty("java.version"), GraphicsEnvironment.isHeadless() ? "(headless)" : "").trim();
}
private static String[] applicationArgumentArray;
protected static void setApplicationArgumentArray(String[] args) {
applicationArgumentArray = args;
}
public static ArgumentBean getApplicationArguments() {
try {
return ArgumentBean.parse(applicationArgumentArray);
} catch (Exception e) {
throw new IllegalStateException(e);
}
}
} }

View File

@ -33,6 +33,7 @@ import javax.swing.text.JTextComponent;
import net.filebot.ResourceManager; import net.filebot.ResourceManager;
import net.filebot.Settings; import net.filebot.Settings;
import net.filebot.Settings.ApplicationFolder;
import net.filebot.cli.ArgumentProcessor.DefaultScriptProvider; import net.filebot.cli.ArgumentProcessor.DefaultScriptProvider;
import net.filebot.util.TeePrintStream; import net.filebot.util.TeePrintStream;
@ -142,7 +143,7 @@ public class GroovyPad extends JFrame {
} }
protected FileLocation getFileLocation(String name) throws IOException { protected FileLocation getFileLocation(String name) throws IOException {
File pad = new File(Settings.getApplicationFolder(), name); File pad = ApplicationFolder.AppData.resolve(name);
if (!pad.exists()) { if (!pad.exists()) {
// use this default value so people can easily submit bug reports with fn:sysinfo logs // use this default value so people can easily submit bug reports with fn:sysinfo logs
ScriptShellMethods.saveAs("runScript 'fn:sysinfo'", pad); ScriptShellMethods.saveAs("runScript 'fn:sysinfo'", pad);

View File

@ -42,6 +42,7 @@ import net.filebot.Language;
import net.filebot.MediaTypes; import net.filebot.MediaTypes;
import net.filebot.MetaAttributeView; import net.filebot.MetaAttributeView;
import net.filebot.Settings; import net.filebot.Settings;
import net.filebot.Settings.ApplicationFolder;
import net.filebot.WebServices; import net.filebot.WebServices;
import net.filebot.hash.HashType; import net.filebot.hash.HashType;
import net.filebot.media.MetaAttributes; import net.filebot.media.MetaAttributes;
@ -848,8 +849,8 @@ public class MediaBindingBean {
} }
@Define("home") @Define("home")
public File getUserHome() throws IOException { public File getUserHome() {
return Settings.getRealUserHome(); return ApplicationFolder.UserHome.getCanonicalFile();
} }
@Define("now") @Define("now")

View File

@ -20,6 +20,7 @@ import javax.script.ScriptContext;
import javax.script.ScriptEngine; import javax.script.ScriptEngine;
import javax.script.ScriptException; import javax.script.ScriptException;
import net.filebot.Settings.ApplicationFolder;
import net.filebot.util.ExceptionUtilities; import net.filebot.util.ExceptionUtilities;
public class SecureCompiledScript extends CompiledScript { public class SecureCompiledScript extends CompiledScript {
@ -46,12 +47,9 @@ public class SecureCompiledScript extends CompiledScript {
permissions.add(new ReflectPermission("suppressAccessChecks")); permissions.add(new ReflectPermission("suppressAccessChecks"));
permissions.add(new ReflectPermission("newProxyInPackage.*")); permissions.add(new ReflectPermission("newProxyInPackage.*"));
// write permissions for temp and cache folders // write permissions for cache and temp folders
try { for (ApplicationFolder it : ApplicationFolder.values()) {
permissions.add(new FilePermission(new File(System.getProperty("java.io.tmpdir")).getAbsolutePath() + File.separator + "-", "write, delete")); permissions.add(new FilePermission(it.getCanonicalFile() + File.separator + "-", "read, write, delete"));
permissions.add(new FilePermission(new File(System.getProperty("ehcache.disk.store.dir")).getAbsolutePath() + File.separator + "-", "write, delete"));
} catch (Exception e) {
// ignore
} }
return permissions; return permissions;