Unify application folder logic
This commit is contained in:
parent
5f6f45a26b
commit
bed6732d35
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue