mirror of
https://github.com/bisq-network/bisq.git
synced 2024-11-19 18:03:12 +01:00
Merge branch 'wip-cbeams'
These changes eliminate the use of "appName" throughout the codebase in favor of explicitly named, and therefore individually configurable alternatives specific to each component. For example, instead of passing the application name through the WalletFacade boundary and then using a utility like AppDirectory to put construct the wallet directory on the fly, the path to wallet directory is now passed explicitly as a @Named(WALLET_DIR) parameter to the WalletFacade constructor. The result is not only better configurability (e.g. the WALLET_DIR property can be overridden without affecting any other parts of the system), but also better understandability. See BitsquareEnvironment#defaultProperties to see how it all comes together. Note how the value of appName is mapped to each of these new properties, all in one place where it's easy to get an overview etc. Also, as of this commit, there is only one place in the codebase where the word "Bitsquare" is hard-coded (in `i.b.app.BitsquareEnvironment`): $ git grep -h '"Bitsquare"' src public static final String DEFAULT_APP_NAME = "Bitsquare"; To keep things clean, further hard-coding should be avoided from this point forward. See extended comments for each commit for details. * wip-cbeams: Eliminate remaining uses of @Named("appName") Introduce explicit title param in ViewCB Introduce io.bitsquare.btc.UserAgent Introduce explicit dir and prefix params in Persistence Introduce explicit wallet and useragent params in WalletFacade Rename environment "app properties"=>"default properties"
This commit is contained in:
commit
d3f1ec252e
@ -18,15 +18,20 @@
|
|||||||
package io.bitsquare.app;
|
package io.bitsquare.app;
|
||||||
|
|
||||||
import io.bitsquare.BitsquareException;
|
import io.bitsquare.BitsquareException;
|
||||||
|
import io.bitsquare.btc.UserAgent;
|
||||||
|
import io.bitsquare.btc.WalletFacade;
|
||||||
|
import io.bitsquare.gui.ViewCB;
|
||||||
|
import io.bitsquare.persistence.Persistence;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
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;
|
||||||
@ -39,10 +44,16 @@ 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";
|
||||||
|
|
||||||
private static final String BITSQUARE_APP_PROPERTY_SOURCE_NAME = "bitsquareAppProperties";
|
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_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";
|
||||||
private static final String BITSQUARE_COMMANDLINE_PROPERTY_SOURCE_NAME = "bitsquareCommandLineProperties";
|
private static final String BITSQUARE_COMMANDLINE_PROPERTY_SOURCE_NAME = "bitsquareCommandLineProperties";
|
||||||
@ -56,19 +67,40 @@ 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, appProperties(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<?> appProperties(String appName) {
|
|
||||||
return new PropertiesPropertySource(BITSQUARE_APP_PROPERTY_SOURCE_NAME, new Properties() {{
|
private PropertySource<?> defaultProperties(String appDataDir, String appName) {
|
||||||
|
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.VERSION_KEY, "0.1");
|
||||||
|
|
||||||
|
setProperty(WalletFacade.DIR_KEY, appDataDir);
|
||||||
|
setProperty(WalletFacade.PREFIX_KEY, appName);
|
||||||
|
|
||||||
|
setProperty(Persistence.DIR_KEY, appDataDir);
|
||||||
|
setProperty(Persistence.PREFIX_KEY, appName + "_pref");
|
||||||
|
|
||||||
|
setProperty(ViewCB.TITLE_KEY, appName);
|
||||||
}});
|
}});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,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()) {
|
||||||
@ -95,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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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());
|
||||||
|
@ -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;
|
||||||
@ -32,12 +31,15 @@ import io.bitsquare.trade.TradeModule;
|
|||||||
import io.bitsquare.user.User;
|
import io.bitsquare.user.User;
|
||||||
|
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
import com.google.inject.name.Names;
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
import org.springframework.core.env.Environment;
|
import org.springframework.core.env.Environment;
|
||||||
|
|
||||||
|
import static com.google.inject.name.Names.named;
|
||||||
|
|
||||||
class BitsquareAppModule extends BitsquareModule {
|
class BitsquareAppModule extends BitsquareModule {
|
||||||
|
|
||||||
private final Stage primaryStage;
|
private final Stage primaryStage;
|
||||||
@ -50,19 +52,19 @@ class BitsquareAppModule extends BitsquareModule {
|
|||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
bind(User.class).asEagerSingleton();
|
bind(User.class).asEagerSingleton();
|
||||||
bind(Persistence.class).asEagerSingleton();
|
|
||||||
bind(Settings.class).asEagerSingleton();
|
bind(Settings.class).asEagerSingleton();
|
||||||
|
|
||||||
|
File persistenceDir = new File(env.getRequiredProperty(Persistence.DIR_KEY));
|
||||||
|
bind(File.class).annotatedWith(named(Persistence.DIR_KEY)).toInstance(persistenceDir);
|
||||||
|
bindConstant().annotatedWith(named(Persistence.PREFIX_KEY)).to(env.getRequiredProperty(Persistence.PREFIX_KEY));
|
||||||
|
bind(Persistence.class).asEagerSingleton();
|
||||||
|
|
||||||
install(messageModule());
|
install(messageModule());
|
||||||
install(bitcoinModule());
|
install(bitcoinModule());
|
||||||
install(cryptoModule());
|
install(cryptoModule());
|
||||||
install(tradeModule());
|
install(tradeModule());
|
||||||
install(offerModule());
|
install(offerModule());
|
||||||
install(guiModule());
|
install(guiModule());
|
||||||
|
|
||||||
String appName = env.getRequiredProperty(BitsquareEnvironment.APP_NAME_KEY);
|
|
||||||
|
|
||||||
bindConstant().annotatedWith(Names.named("appName")).to(appName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected MessageModule messageModule() {
|
protected MessageModule messageModule() {
|
||||||
|
@ -26,8 +26,12 @@ import org.bitcoinj.params.TestNet3Params;
|
|||||||
|
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
import org.springframework.core.env.Environment;
|
import org.springframework.core.env.Environment;
|
||||||
|
|
||||||
|
import static com.google.inject.name.Names.named;
|
||||||
|
|
||||||
public class BitcoinModule extends BitsquareModule {
|
public class BitcoinModule extends BitsquareModule {
|
||||||
|
|
||||||
public static final String BITCOIN_NETWORK_KEY = "bitcoin.network";
|
public static final String BITCOIN_NETWORK_KEY = "bitcoin.network";
|
||||||
@ -39,10 +43,19 @@ public class BitcoinModule extends BitsquareModule {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
bind(WalletFacade.class).asEagerSingleton();
|
|
||||||
bind(FeePolicy.class).asEagerSingleton();
|
|
||||||
bind(BlockChainFacade.class).asEagerSingleton();
|
|
||||||
bind(NetworkParameters.class).toInstance(network());
|
bind(NetworkParameters.class).toInstance(network());
|
||||||
|
bind(FeePolicy.class).asEagerSingleton();
|
||||||
|
|
||||||
|
bindConstant().annotatedWith(named(UserAgent.NAME_KEY)).to(env.getRequiredProperty(UserAgent.NAME_KEY));
|
||||||
|
bindConstant().annotatedWith(named(UserAgent.VERSION_KEY)).to(env.getRequiredProperty(UserAgent.VERSION_KEY));
|
||||||
|
bind(UserAgent.class).asEagerSingleton();
|
||||||
|
|
||||||
|
File walletDir = new File(env.getRequiredProperty(WalletFacade.DIR_KEY));
|
||||||
|
bind(File.class).annotatedWith(named(WalletFacade.DIR_KEY)).toInstance(walletDir);
|
||||||
|
bindConstant().annotatedWith(named(WalletFacade.PREFIX_KEY)).to(env.getRequiredProperty(WalletFacade.PREFIX_KEY));
|
||||||
|
bind(WalletFacade.class).asEagerSingleton();
|
||||||
|
|
||||||
|
bind(BlockChainFacade.class).asEagerSingleton();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
44
src/main/java/io/bitsquare/btc/UserAgent.java
Normal file
44
src/main/java/io/bitsquare/btc/UserAgent.java
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* 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 io.bitsquare.btc;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
|
||||||
|
public class UserAgent {
|
||||||
|
public static final String NAME_KEY = "useragent.name";
|
||||||
|
public static final String VERSION_KEY = "useragent.version";
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
private final String version;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public UserAgent(@Named(NAME_KEY) String name, @Named(VERSION_KEY) String version) {
|
||||||
|
this.name = name;
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -57,6 +57,7 @@ import com.google.common.util.concurrent.Futures;
|
|||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import com.google.common.util.concurrent.Service;
|
import com.google.common.util.concurrent.Service;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
@ -84,8 +85,6 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import lighthouse.files.AppDirectory;
|
|
||||||
|
|
||||||
import static org.bitcoinj.script.ScriptOpCodes.OP_RETURN;
|
import static org.bitcoinj.script.ScriptOpCodes.OP_RETURN;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -94,24 +93,30 @@ import static org.bitcoinj.script.ScriptOpCodes.OP_RETURN;
|
|||||||
*/
|
*/
|
||||||
public class WalletFacade {
|
public class WalletFacade {
|
||||||
private static final Logger log = LoggerFactory.getLogger(WalletFacade.class);
|
private static final Logger log = LoggerFactory.getLogger(WalletFacade.class);
|
||||||
|
private static final String LOCK_NAME = "lock";
|
||||||
|
|
||||||
|
public static final String DIR_KEY = "wallet.dir";
|
||||||
|
public static final String PREFIX_KEY = "wallet.prefix";
|
||||||
|
|
||||||
private final ReentrantLock lock = Threading.lock("lock");
|
|
||||||
private final NetworkParameters params;
|
|
||||||
private WalletAppKit walletAppKit;
|
|
||||||
private final FeePolicy feePolicy;
|
|
||||||
private final CryptoFacade cryptoFacade;
|
|
||||||
private final Persistence persistence;
|
|
||||||
private final String appName;
|
|
||||||
private final List<AddressConfidenceListener> addressConfidenceListeners = new CopyOnWriteArrayList<>();
|
private final List<AddressConfidenceListener> addressConfidenceListeners = new CopyOnWriteArrayList<>();
|
||||||
private final List<TxConfidenceListener> txConfidenceListeners = new CopyOnWriteArrayList<>();
|
private final List<TxConfidenceListener> txConfidenceListeners = new CopyOnWriteArrayList<>();
|
||||||
private final List<BalanceListener> balanceListeners = new CopyOnWriteArrayList<>();
|
private final List<BalanceListener> balanceListeners = new CopyOnWriteArrayList<>();
|
||||||
|
private final ReentrantLock lock = Threading.lock(LOCK_NAME);
|
||||||
|
|
||||||
|
private final NetworkParameters params;
|
||||||
|
private final FeePolicy feePolicy;
|
||||||
|
private final CryptoFacade cryptoFacade;
|
||||||
|
private final Persistence persistence;
|
||||||
|
private final File walletDir;
|
||||||
|
private final String walletPrefix;
|
||||||
|
private final UserAgent userAgent;
|
||||||
|
|
||||||
|
private WalletAppKit walletAppKit;
|
||||||
private Wallet wallet;
|
private Wallet wallet;
|
||||||
private WalletEventListener walletEventListener;
|
private WalletEventListener walletEventListener;
|
||||||
private AddressEntry registrationAddressEntry;
|
private AddressEntry registrationAddressEntry;
|
||||||
private AddressEntry arbitratorDepositAddressEntry;
|
private AddressEntry arbitratorDepositAddressEntry;
|
||||||
|
private @GuardedBy(LOCK_NAME) List<AddressEntry> addressEntryList = new ArrayList<>();
|
||||||
@GuardedBy("lock")
|
|
||||||
private List<AddressEntry> addressEntryList = new ArrayList<>();
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Constructor
|
// Constructor
|
||||||
@ -119,12 +124,15 @@ public class WalletFacade {
|
|||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public WalletFacade(NetworkParameters params, FeePolicy feePolicy, CryptoFacade cryptoFacade,
|
public WalletFacade(NetworkParameters params, FeePolicy feePolicy, CryptoFacade cryptoFacade,
|
||||||
Persistence persistence, @Named("appName") String appName) {
|
Persistence persistence, UserAgent userAgent,
|
||||||
|
@Named(DIR_KEY) File walletDir, @Named(PREFIX_KEY) String walletPrefix) {
|
||||||
this.params = params;
|
this.params = params;
|
||||||
this.feePolicy = feePolicy;
|
this.feePolicy = feePolicy;
|
||||||
this.cryptoFacade = cryptoFacade;
|
this.cryptoFacade = cryptoFacade;
|
||||||
this.persistence = persistence;
|
this.persistence = persistence;
|
||||||
this.appName = appName;
|
this.walletDir = walletDir;
|
||||||
|
this.walletPrefix = walletPrefix;
|
||||||
|
this.userAgent = userAgent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -141,7 +149,7 @@ public class WalletFacade {
|
|||||||
Threading.USER_THREAD = executor;
|
Threading.USER_THREAD = executor;
|
||||||
|
|
||||||
// If seed is non-null it means we are restoring from backup.
|
// If seed is non-null it means we are restoring from backup.
|
||||||
walletAppKit = new WalletAppKit(params, AppDirectory.dir(appName).toFile(), appName) {
|
walletAppKit = new WalletAppKit(params, walletDir, walletPrefix) {
|
||||||
@Override
|
@Override
|
||||||
protected void onSetupCompleted() {
|
protected void onSetupCompleted() {
|
||||||
// Don't make the user wait for confirmations for now, as the intention is they're sending it
|
// Don't make the user wait for confirmations for now, as the intention is they're sending it
|
||||||
@ -195,7 +203,7 @@ public class WalletFacade {
|
|||||||
|
|
||||||
walletAppKit.setDownloadListener(downloadListener)
|
walletAppKit.setDownloadListener(downloadListener)
|
||||||
.setBlockingStartup(false)
|
.setBlockingStartup(false)
|
||||||
.setUserAgent(appName, "0.1");
|
.setUserAgent(userAgent.getName(), userAgent.getVersion());
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// TODO restore from DeterministicSeed
|
// TODO restore from DeterministicSeed
|
||||||
|
@ -28,6 +28,8 @@ import io.bitsquare.gui.util.validation.FiatValidator;
|
|||||||
import io.bitsquare.gui.util.validation.InputValidator;
|
import io.bitsquare.gui.util.validation.InputValidator;
|
||||||
import io.bitsquare.gui.util.validation.PasswordValidator;
|
import io.bitsquare.gui.util.validation.PasswordValidator;
|
||||||
|
|
||||||
|
import com.google.inject.name.Names;
|
||||||
|
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
import org.springframework.core.env.Environment;
|
import org.springframework.core.env.Environment;
|
||||||
@ -57,5 +59,7 @@ public class GuiModule extends BitsquareModule {
|
|||||||
bind(Stage.class).toInstance(primaryStage);
|
bind(Stage.class).toInstance(primaryStage);
|
||||||
Popups.primaryStage = primaryStage;
|
Popups.primaryStage = primaryStage;
|
||||||
Help.primaryStage = primaryStage;
|
Help.primaryStage = primaryStage;
|
||||||
|
|
||||||
|
bindConstant().annotatedWith(Names.named(ViewCB.TITLE_KEY)).to(env.getRequiredProperty(ViewCB.TITLE_KEY));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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<>();
|
||||||
|
@ -36,6 +36,8 @@ import org.slf4j.LoggerFactory;
|
|||||||
public class ViewCB<T extends PresentationModel> implements Initializable {
|
public class ViewCB<T extends PresentationModel> implements Initializable {
|
||||||
private static final Logger log = LoggerFactory.getLogger(ViewCB.class);
|
private static final Logger log = LoggerFactory.getLogger(ViewCB.class);
|
||||||
|
|
||||||
|
public static final String TITLE_KEY = "view.title";
|
||||||
|
|
||||||
protected T presentationModel;
|
protected T presentationModel;
|
||||||
//TODO Initializable has to be changed to CodeBehind<? extends PresentationModel> when all UIs are updated
|
//TODO Initializable has to be changed to CodeBehind<? extends PresentationModel> when all UIs are updated
|
||||||
protected Initializable childController;
|
protected Initializable childController;
|
||||||
|
@ -31,11 +31,11 @@ public class SystemNotification {
|
|||||||
private static final Logger log = LoggerFactory.getLogger(SystemNotification.class);
|
private static final Logger log = LoggerFactory.getLogger(SystemNotification.class);
|
||||||
private static final Notification.Notifier notifier = NotifierBuilder.create().build();
|
private static final Notification.Notifier notifier = NotifierBuilder.create().build();
|
||||||
|
|
||||||
public static void openInfoNotification(String headline, String message) {
|
public static void openInfoNotification(String title, String message) {
|
||||||
// On windows it causes problems with the hidden stage used in the hansolo Notification implementation
|
// On windows it causes problems with the hidden stage used in the hansolo Notification implementation
|
||||||
// Lets deactivate it for the moment and fix that with a more native-like or real native solution later.
|
// Lets deactivate it for the moment and fix that with a more native-like or real native solution later.
|
||||||
String os = System.getProperty("os.name").toLowerCase();
|
String os = System.getProperty("os.name").toLowerCase();
|
||||||
if (!os.contains("win"))
|
if (!os.contains("win"))
|
||||||
notifier.notify(NotificationBuilder.create().title(headline).message(message).build());
|
notifier.notify(NotificationBuilder.create().title(title).message(message).build());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ public class MainViewCB extends ViewCB<MainPM> {
|
|||||||
private final OverlayManager overlayManager;
|
private final OverlayManager overlayManager;
|
||||||
private final ToggleGroup navButtonsGroup = new ToggleGroup();
|
private final ToggleGroup navButtonsGroup = new ToggleGroup();
|
||||||
private final Settings settings;
|
private final Settings settings;
|
||||||
private final String appName;
|
private final String title;
|
||||||
|
|
||||||
private BorderPane baseApplicationContainer;
|
private BorderPane baseApplicationContainer;
|
||||||
private VBox splashScreen;
|
private VBox splashScreen;
|
||||||
@ -77,13 +77,13 @@ public class MainViewCB extends ViewCB<MainPM> {
|
|||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private MainViewCB(MainPM presentationModel, Navigation navigation, OverlayManager overlayManager,
|
private MainViewCB(MainPM presentationModel, Navigation navigation, OverlayManager overlayManager,
|
||||||
TradeManager tradeManager, Settings settings, @Named("appName") String appName) {
|
TradeManager tradeManager, Settings settings, @Named(TITLE_KEY) String title) {
|
||||||
super(presentationModel);
|
super(presentationModel);
|
||||||
|
|
||||||
this.navigation = navigation;
|
this.navigation = navigation;
|
||||||
this.overlayManager = overlayManager;
|
this.overlayManager = overlayManager;
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
this.appName = appName;
|
this.title = title;
|
||||||
|
|
||||||
tradeManager.featureNotImplementedWarningProperty().addListener((ov, oldValue, newValue) -> {
|
tradeManager.featureNotImplementedWarningProperty().addListener((ov, oldValue, newValue) -> {
|
||||||
if (oldValue == null && newValue != null) {
|
if (oldValue == null && newValue != null) {
|
||||||
@ -207,8 +207,8 @@ public class MainViewCB extends ViewCB<MainPM> {
|
|||||||
numPendingTradesLabel.setText(String.valueOf(numPendingTrades));
|
numPendingTradesLabel.setText(String.valueOf(numPendingTrades));
|
||||||
}
|
}
|
||||||
|
|
||||||
log.trace("openInfoNotification " + appName);
|
log.trace("openInfoNotification " + title);
|
||||||
SystemNotification.openInfoNotification(appName, "You got a new trade message.");
|
SystemNotification.openInfoNotification(title, "You got a new trade message.");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (portfolioButtonButtonPane.getChildren().size() > 1)
|
if (portfolioButtonButtonPane.getChildren().size() > 1)
|
||||||
|
@ -17,8 +17,7 @@
|
|||||||
|
|
||||||
package io.bitsquare.persistence;
|
package io.bitsquare.persistence;
|
||||||
|
|
||||||
import io.bitsquare.util.FileUtil;
|
import org.bitcoinj.core.Utils;
|
||||||
|
|
||||||
import org.bitcoinj.utils.Threading;
|
import org.bitcoinj.utils.Threading;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@ -52,22 +51,27 @@ public class Persistence {
|
|||||||
private static final Logger log = LoggerFactory.getLogger(Persistence.class);
|
private static final Logger log = LoggerFactory.getLogger(Persistence.class);
|
||||||
private static final ReentrantLock lock = Threading.lock("Storage");
|
private static final ReentrantLock lock = Threading.lock("Storage");
|
||||||
|
|
||||||
|
public static final String DIR_KEY = "persistence.dir";
|
||||||
|
public static final String PREFIX_KEY = "persistence.prefix";
|
||||||
|
|
||||||
@GuardedBy("lock")
|
@GuardedBy("lock")
|
||||||
private Map<String, Serializable> rootMap = new HashMap<>();
|
private Map<String, Serializable> rootMap = new HashMap<>();
|
||||||
|
|
||||||
|
private final File dir;
|
||||||
private final String prefix;
|
private final String prefix;
|
||||||
private final File storageFile;
|
private final File storageFile;
|
||||||
private String appName;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Constructor
|
// Constructor
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public Persistence(@Named("appName") String appName) {
|
public Persistence(
|
||||||
this.appName = appName;
|
@Named(DIR_KEY) File dir,
|
||||||
this.prefix = appName + "_pref";
|
@Named(PREFIX_KEY) String prefix) {
|
||||||
this.storageFile = FileUtil.getFile(appName, prefix, "ser");
|
this.dir = dir;
|
||||||
|
this.prefix = prefix;
|
||||||
|
this.storageFile = new File(dir, prefix + ".ser");
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -220,7 +224,7 @@ public class Persistence {
|
|||||||
FileOutputStream fileOutputStream = null;
|
FileOutputStream fileOutputStream = null;
|
||||||
ObjectOutputStream objectOutputStream = null;
|
ObjectOutputStream objectOutputStream = null;
|
||||||
try {
|
try {
|
||||||
tempFile = FileUtil.getTempFile(appName, prefix);
|
tempFile = File.createTempFile("temp_" + prefix, null, dir);
|
||||||
|
|
||||||
// Don't use auto closeable resources in try() as we would need too many try/catch clauses (for tempFile)
|
// Don't use auto closeable resources in try() as we would need too many try/catch clauses (for tempFile)
|
||||||
// and we need to close it
|
// and we need to close it
|
||||||
@ -240,7 +244,7 @@ public class Persistence {
|
|||||||
fileOutputStream.close();
|
fileOutputStream.close();
|
||||||
objectOutputStream.close();
|
objectOutputStream.close();
|
||||||
|
|
||||||
FileUtil.writeTempFileToFile(tempFile, storageFile);
|
writeTempFileToFile(tempFile, storageFile);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
log.error("save object to file failed." + e);
|
log.error("save object to file failed." + e);
|
||||||
@ -269,4 +273,20 @@ public class Persistence {
|
|||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void writeTempFileToFile(File tempFile, File file) throws IOException {
|
||||||
|
if (Utils.isWindows()) {
|
||||||
|
// Work around an issue on Windows whereby you can't rename over existing files.
|
||||||
|
final File canonical = file.getCanonicalFile();
|
||||||
|
if (canonical.exists() && !canonical.delete()) {
|
||||||
|
throw new IOException("Failed to delete canonical file for replacement with save");
|
||||||
|
}
|
||||||
|
if (!tempFile.renameTo(canonical)) {
|
||||||
|
throw new IOException("Failed to rename " + tempFile + " to " + canonical);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!tempFile.renameTo(file)) {
|
||||||
|
throw new IOException("Failed to rename " + tempFile + " to " + file);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,57 +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 io.bitsquare.util;
|
|
||||||
|
|
||||||
import org.bitcoinj.core.Utils;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import lighthouse.files.AppDirectory;
|
|
||||||
|
|
||||||
public class FileUtil {
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(FileUtil.class);
|
|
||||||
|
|
||||||
public static File getFile(String appName, String name, String suffix) {
|
|
||||||
return new File(AppDirectory.dir(appName).toFile(), name + "." + suffix);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static File getTempFile(String appName, String prefix) throws IOException {
|
|
||||||
return File.createTempFile("temp_" + prefix, null, AppDirectory.dir(appName).toFile());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void writeTempFileToFile(File tempFile, File file) throws IOException {
|
|
||||||
if (Utils.isWindows()) {
|
|
||||||
// Work around an issue on Windows whereby you can't rename over existing files.
|
|
||||||
final File canonical = file.getCanonicalFile();
|
|
||||||
if (canonical.exists() && !canonical.delete()) {
|
|
||||||
throw new IOException("Failed to delete canonical file for replacement with save");
|
|
||||||
}
|
|
||||||
if (!tempFile.renameTo(canonical)) {
|
|
||||||
throw new IOException("Failed to rename " + tempFile + " to " + canonical);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!tempFile.renameTo(file)) {
|
|
||||||
throw new IOException("Failed to rename " + tempFile + " to " + 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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user