Eliminate remaining uses of @Named("appName")

Changes include:

 - Remove lighthouse.files.AppDirectory. Several methods from this class
   have, as of this commit, been rewritten and moved into the
   BitsquareEnvironment and BitsquareApp classes as appropriate.

 - Rename "appName" property => "app.name" for consistency with other
   configurable properties.

 - Allow configuration of both user and application data directories on
   the command line. See --help menu for details.
This commit is contained in:
Chris Beams 2014-11-11 14:21:01 +01:00
parent 454ee1fbe0
commit 1c0a6ee432
No known key found for this signature in database
GPG key ID: 3D214F8F5BC5ED73
7 changed files with 76 additions and 114 deletions

View file

@ -27,10 +27,11 @@ import com.google.common.base.Preconditions;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Paths;
import java.util.Properties; import java.util.Properties;
import joptsimple.OptionSet; import joptsimple.OptionSet;
import lighthouse.files.AppDirectory;
import org.springframework.core.env.JOptCommandLinePropertySource; import org.springframework.core.env.JOptCommandLinePropertySource;
import org.springframework.core.env.MutablePropertySources; import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertiesPropertySource; import org.springframework.core.env.PropertiesPropertySource;
@ -43,9 +44,15 @@ import org.springframework.core.io.support.ResourcePropertySource;
public class BitsquareEnvironment extends StandardEnvironment { public class BitsquareEnvironment extends StandardEnvironment {
public static final String APP_NAME_KEY = "appName"; public static final String APP_NAME_KEY = "app.name";
public static final String DEFAULT_APP_NAME = "Bitsquare"; public static final String DEFAULT_APP_NAME = "Bitsquare";
public static final String USER_DATA_DIR_KEY = "user.data.dir";
public static final String DEFAULT_USER_DATA_DIR = defaultUserDataDir();
public static final String APP_DATA_DIR_KEY = "app.data.dir";
public static final String DEFAULT_APP_DATA_DIR = appDataDir(DEFAULT_USER_DATA_DIR, DEFAULT_APP_NAME);
private static final String BITSQUARE_DEFAULT_PROPERTY_SOURCE_NAME = "bitsquareDefaultProperties"; private static final String BITSQUARE_DEFAULT_PROPERTY_SOURCE_NAME = "bitsquareDefaultProperties";
private static final String BITSQUARE_CLASSPATH_PROPERTY_SOURCE_NAME = "bitsquareClasspathProperties"; private static final String BITSQUARE_CLASSPATH_PROPERTY_SOURCE_NAME = "bitsquareClasspathProperties";
private static final String BITSQUARE_FILESYSTEM_PROPERTY_SOURCE_NAME = "bitsquareFilesystemProperties"; private static final String BITSQUARE_FILESYSTEM_PROPERTY_SOURCE_NAME = "bitsquareFilesystemProperties";
@ -60,27 +67,37 @@ public class BitsquareEnvironment extends StandardEnvironment {
new JOptCommandLinePropertySource(BITSQUARE_COMMANDLINE_PROPERTY_SOURCE_NAME, options); new JOptCommandLinePropertySource(BITSQUARE_COMMANDLINE_PROPERTY_SOURCE_NAME, options);
String appName = commandLineProperties.containsProperty(APP_NAME_KEY) ? String appName = commandLineProperties.containsProperty(APP_NAME_KEY) ?
DEFAULT_APP_NAME + "-" + commandLineProperties.getProperty(APP_NAME_KEY) : (String) commandLineProperties.getProperty(APP_NAME_KEY) :
DEFAULT_APP_NAME; DEFAULT_APP_NAME;
String userDataDir = commandLineProperties.containsProperty(USER_DATA_DIR_KEY) ?
(String) commandLineProperties.getProperty(USER_DATA_DIR_KEY) :
DEFAULT_USER_DATA_DIR;
String appDataDir = commandLineProperties.containsProperty(APP_DATA_DIR_KEY) ?
(String) commandLineProperties.getProperty(APP_DATA_DIR_KEY) :
appDataDir(userDataDir, appName);
MutablePropertySources propertySources = this.getPropertySources(); MutablePropertySources propertySources = this.getPropertySources();
propertySources.addBefore(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, defaultProperties(appName)); propertySources.addBefore(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, defaultProperties(appDataDir, appName));
propertySources.addBefore(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, classpathProperties()); propertySources.addBefore(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, classpathProperties());
propertySources.addBefore(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, filesystemProperties(appName)); propertySources.addBefore(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, filesystemProperties(appDataDir));
propertySources.addAfter(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, commandLineProperties); propertySources.addAfter(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, commandLineProperties);
} }
private PropertySource<?> defaultProperties(String appName) {
private PropertySource<?> defaultProperties(String appDataDir, String appName) {
return new PropertiesPropertySource(BITSQUARE_DEFAULT_PROPERTY_SOURCE_NAME, new Properties() {{ return new PropertiesPropertySource(BITSQUARE_DEFAULT_PROPERTY_SOURCE_NAME, new Properties() {{
setProperty(APP_DATA_DIR_KEY, appDataDir);
setProperty(APP_NAME_KEY, appName); setProperty(APP_NAME_KEY, appName);
setProperty(UserAgent.NAME_KEY, appName); setProperty(UserAgent.NAME_KEY, appName);
setProperty(UserAgent.VERSION_KEY, "0.1"); setProperty(UserAgent.VERSION_KEY, "0.1");
setProperty(WalletFacade.DIR_KEY, AppDirectory.dir(appName).toString()); setProperty(WalletFacade.DIR_KEY, appDataDir);
setProperty(WalletFacade.PREFIX_KEY, appName); setProperty(WalletFacade.PREFIX_KEY, appName);
setProperty(Persistence.DIR_KEY, AppDirectory.dir(appName).toString()); setProperty(Persistence.DIR_KEY, appDataDir);
setProperty(Persistence.PREFIX_KEY, appName + "_pref"); setProperty(Persistence.PREFIX_KEY, appName + "_pref");
setProperty(ViewCB.TITLE_KEY, appName); setProperty(ViewCB.TITLE_KEY, appName);
@ -96,8 +113,8 @@ public class BitsquareEnvironment extends StandardEnvironment {
} }
} }
private PropertySource<?> filesystemProperties(String appName) { private PropertySource<?> filesystemProperties(String appDir) {
String location = String.format("file:%s/bitsquare.conf", AppDirectory.dir(appName)); String location = String.format("file:%s/bitsquare.conf", appDir);
Resource resource = resourceLoader.getResource(location); Resource resource = resourceLoader.getResource(location);
if (!resource.exists()) { if (!resource.exists()) {
@ -110,4 +127,22 @@ public class BitsquareEnvironment extends StandardEnvironment {
throw new BitsquareException(ex); throw new BitsquareException(ex);
} }
} }
private static String defaultUserDataDir() {
String os = System.getProperty("os.name").toLowerCase();
if (os.contains("win"))
return System.getenv("APPDATA");
if (os.contains("mac"))
return Paths.get(System.getProperty("user.home"), "Library", "Application Support").toString();
// *nix
return Paths.get(System.getProperty("user.home"), ".local", "share").toString();
}
private static String appDataDir(String userDataDir, String appName) {
return Paths.get(userDataDir, appName).toString();
}
} }

View file

@ -17,7 +17,7 @@
package io.bitsquare.app.gui; package io.bitsquare.app.gui;
import io.bitsquare.app.BitsquareEnvironment; import io.bitsquare.BitsquareException;
import io.bitsquare.gui.Navigation; import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.SystemTray; import io.bitsquare.gui.SystemTray;
import io.bitsquare.gui.ViewLoader; import io.bitsquare.gui.ViewLoader;
@ -35,21 +35,21 @@ import com.google.inject.Injector;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import javafx.application.Application; import javafx.application.Application;
import javafx.scene.*; import javafx.scene.*;
import javafx.scene.image.*; import javafx.scene.image.*;
import javafx.scene.input.*; import javafx.scene.input.*;
import javafx.stage.Stage; import javafx.stage.Stage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import lighthouse.files.AppDirectory;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
public class BitsquareApp extends Application { import static io.bitsquare.app.BitsquareEnvironment.*;
private static final Logger log = LoggerFactory.getLogger(BitsquareApp.class);
public class BitsquareApp extends Application {
private static Environment env; private static Environment env;
private BitsquareAppModule bitsquareAppModule; private BitsquareAppModule bitsquareAppModule;
@ -63,8 +63,6 @@ public class BitsquareApp extends Application {
public void start(Stage primaryStage) throws IOException { public void start(Stage primaryStage) throws IOException {
Preconditions.checkArgument(env != null, "Environment must not be null"); Preconditions.checkArgument(env != null, "Environment must not be null");
String appName = env.getRequiredProperty(BitsquareEnvironment.APP_NAME_KEY);
bitsquareAppModule = new BitsquareAppModule(env, primaryStage); bitsquareAppModule = new BitsquareAppModule(env, primaryStage);
injector = Guice.createInjector(bitsquareAppModule); injector = Guice.createInjector(bitsquareAppModule);
@ -75,13 +73,9 @@ public class BitsquareApp extends Application {
Popups.handleUncaughtExceptions(Throwables.getRootCause(throwable))); Popups.handleUncaughtExceptions(Throwables.getRootCause(throwable)));
// configure the Bitsquare application data directory // initialize the application data directory (if necessary)
try { initAppDir(env.getRequiredProperty(APP_DATA_DIR_KEY));
AppDirectory.initAppDir(appName);
} catch (IOException e) {
log.error(e.getMessage());
}
// load and apply any stored settings // load and apply any stored settings
@ -125,7 +119,7 @@ public class BitsquareApp extends Application {
// configure the primary stage // configure the primary stage
primaryStage.setTitle(appName); primaryStage.setTitle(env.getRequiredProperty(APP_NAME_KEY));
primaryStage.setScene(scene); primaryStage.setScene(scene);
primaryStage.setMinWidth(75); primaryStage.setMinWidth(75);
primaryStage.setMinHeight(50); primaryStage.setMinHeight(50);
@ -143,4 +137,20 @@ public class BitsquareApp extends Application {
bitsquareAppModule.close(injector); bitsquareAppModule.close(injector);
System.exit(0); System.exit(0);
} }
private void initAppDir(String appDir) {
Path dir = Paths.get(appDir);
if (Files.exists(dir)) {
if (!Files.isWritable(dir)) {
throw new BitsquareException("Application data directory '%s' is not writeable", dir);
}
return;
}
try {
Files.createDirectory(dir);
} catch (IOException ex) {
throw new BitsquareException(ex, "Application data directory '%s' could not be created", dir);
}
}
} }

View file

@ -26,7 +26,7 @@ import io.bitsquare.network.Node;
import joptsimple.OptionParser; import joptsimple.OptionParser;
import joptsimple.OptionSet; import joptsimple.OptionSet;
import static io.bitsquare.app.BitsquareEnvironment.APP_NAME_KEY; import static io.bitsquare.app.BitsquareEnvironment.*;
import static io.bitsquare.btc.BitcoinModule.BITCOIN_NETWORK_KEY; import static io.bitsquare.btc.BitcoinModule.BITCOIN_NETWORK_KEY;
import static io.bitsquare.msg.tomp2p.TomP2PMessageModule.*; import static io.bitsquare.msg.tomp2p.TomP2PMessageModule.*;
import static io.bitsquare.network.Node.*; import static io.bitsquare.network.Node.*;
@ -39,8 +39,10 @@ public class BitsquareAppMain extends BitsquareExecutable {
@Override @Override
protected void customizeOptionParsing(OptionParser parser) { protected void customizeOptionParsing(OptionParser parser) {
parser.accepts(APP_NAME_KEY, "Qualified application name").withRequiredArg(); parser.accepts(APP_NAME_KEY, "Application name").withRequiredArg().defaultsTo(DEFAULT_APP_NAME);
parser.accepts(NAME_KEY, "Name of this node").withRequiredArg(); parser.accepts(USER_DATA_DIR_KEY, "User data directory").withRequiredArg().defaultsTo(DEFAULT_USER_DATA_DIR);
parser.accepts(APP_DATA_DIR_KEY, "Application data directory").withRequiredArg().defaultsTo(DEFAULT_APP_DATA_DIR);
parser.accepts(NAME_KEY, "Network name").withRequiredArg();
parser.accepts(PORT_KEY, "Port to listen on").withRequiredArg().defaultsTo(String.valueOf(Node.DEFAULT_PORT)); parser.accepts(PORT_KEY, "Port to listen on").withRequiredArg().defaultsTo(String.valueOf(Node.DEFAULT_PORT));
parser.accepts(BITCOIN_NETWORK_KEY).withRequiredArg().defaultsTo(BitcoinModule.DEFAULT_BITCOIN_NETWORK); parser.accepts(BITCOIN_NETWORK_KEY).withRequiredArg().defaultsTo(BitcoinModule.DEFAULT_BITCOIN_NETWORK);
parser.accepts(BOOTSTRAP_NODE_NAME_KEY).withRequiredArg().defaultsTo(BootstrapNodes.DEFAULT.getName()); parser.accepts(BOOTSTRAP_NODE_NAME_KEY).withRequiredArg().defaultsTo(BootstrapNodes.DEFAULT.getName());

View file

@ -18,7 +18,6 @@
package io.bitsquare.app.gui; package io.bitsquare.app.gui;
import io.bitsquare.BitsquareModule; import io.bitsquare.BitsquareModule;
import io.bitsquare.app.BitsquareEnvironment;
import io.bitsquare.btc.BitcoinModule; import io.bitsquare.btc.BitcoinModule;
import io.bitsquare.crypto.CryptoModule; import io.bitsquare.crypto.CryptoModule;
import io.bitsquare.gui.GuiModule; import io.bitsquare.gui.GuiModule;
@ -66,10 +65,6 @@ class BitsquareAppModule extends BitsquareModule {
install(tradeModule()); install(tradeModule());
install(offerModule()); install(offerModule());
install(guiModule()); install(guiModule());
String appName = env.getRequiredProperty(BitsquareEnvironment.APP_NAME_KEY);
bindConstant().annotatedWith(named("appName")).to(appName);
} }
protected MessageModule messageModule() { protected MessageModule messageModule() {

View file

@ -31,7 +31,6 @@ import org.slf4j.LoggerFactory;
public class Navigation { public class Navigation {
private static final Logger log = LoggerFactory.getLogger(Navigation.class); private static final Logger log = LoggerFactory.getLogger(Navigation.class);
// New listeners can be added during iteration so we use CopyOnWriteArrayList to prevent invalid array // New listeners can be added during iteration so we use CopyOnWriteArrayList to prevent invalid array
// modification // modification
private final List<Listener> listeners = new CopyOnWriteArrayList<>(); private final List<Listener> listeners = new CopyOnWriteArrayList<>();

View file

@ -1,73 +0,0 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package lighthouse.files;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import static com.google.common.base.Preconditions.checkNotNull;
// TODO update to open source file when its released, check licence issues
/**
* Manages the directory where the app stores all its files.
*/
public class AppDirectory {
public static Path getUserDataDir() {
String os = System.getProperty("os.name").toLowerCase();
if (os.contains("win")) {
return Paths.get(System.getenv("APPDATA"));
}
else if (os.contains("mac")) {
return Paths.get(System.getProperty("user.home"), "Library", "Application Support");
}
else {
// Linux and other similar systems, we hope (not Android).
return Paths.get(System.getProperty("user.home"), ".local", "share");
}
}
public static Path getUserDataDir(String appName) {
return getUserDataDir().resolve(appName);
}
public static Path initAppDir(String appName) throws IOException {
Path dir = dir(appName);
if (!Files.exists(dir))
Files.createDirectory(dir);
else if (!Files.isWritable(dir))
throw new IOException("App directory is not writeable");
return dir;
}
private static Path dir;
public static Path dir(String appName) {
if (dir == null)
return getUserDataDir(appName);
else
return dir;
}
public static void overrideAppDir(Path newDir) {
dir = checkNotNull(newDir);
}
}

View file

@ -25,8 +25,6 @@ import io.bitsquare.gui.ViewLoader;
import com.google.inject.Guice; import com.google.inject.Guice;
import com.google.inject.Injector; import com.google.inject.Injector;
import java.util.Properties;
import javafx.application.Application; import javafx.application.Application;
import javafx.stage.Stage; import javafx.stage.Stage;
@ -36,7 +34,6 @@ import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import joptsimple.OptionParser; import joptsimple.OptionParser;
import org.springframework.core.env.PropertiesPropertySource;
public class ViewLoaderTests { public class ViewLoaderTests {
@ -65,11 +62,8 @@ public class ViewLoaderTests {
@Before @Before
public void setUp() { public void setUp() {
Properties properties = new Properties();
properties.setProperty(BitsquareEnvironment.APP_NAME_KEY, "testApp");
OptionParser parser = new OptionParser(); OptionParser parser = new OptionParser();
BitsquareEnvironment env = new BitsquareEnvironment(parser.parse(new String[] {})); BitsquareEnvironment env = new BitsquareEnvironment(parser.parse(new String[] {}));
env.getPropertySources().addLast(new PropertiesPropertySource("testProperties", properties));
Injector injector = Guice.createInjector(new BitsquareAppModule(env, TestApp.primaryStage)); Injector injector = Guice.createInjector(new BitsquareAppModule(env, TestApp.primaryStage));
ViewLoader.setInjector(injector); ViewLoader.setInjector(injector);
} }