diff --git a/build.gradle b/build.gradle
index 9a17f7db1a..d7126cc9e4 100644
--- a/build.gradle
+++ b/build.gradle
@@ -17,7 +17,7 @@ sourceCompatibility = 1.8
sourceSets.main.resources.srcDirs += 'src/main/java'
-mainClassName = "io.bitsquare.app.gui.Main"
+mainClassName = "io.bitsquare.app.gui.BitsquareAppMain"
run {
if (project.hasProperty('args')) {
@@ -33,6 +33,8 @@ repositories {
dependencies {
compile 'org.bitcoinj:bitcoinj-core:0.12'
compile 'net.tomp2p:tomp2p-all:5.0-Alpha.aa0c736-SNAPSHOT'
+ compile 'org.springframework:spring-core:4.1.1.RELEASE'
+ compile 'net.sf.jopt-simple:jopt-simple:4.8'
compile 'org.slf4j:slf4j-api:1.7.7'
compile 'ch.qos.logback:logback-core:1.1.2'
compile 'ch.qos.logback:logback-classic:1.1.2'
@@ -45,7 +47,6 @@ dependencies {
compile 'com.google.code.findbugs:jsr305:2.0.3'
compile 'net.jcip:jcip-annotations:1.0'
compile 'org.jetbrains:annotations:13.0'
- compile 'net.sourceforge.argparse4j:argparse4j:0.4.4'
compile 'eu.hansolo.enzo:Enzo:0.1.5'
testCompile 'junit:junit:4.11'
}
diff --git a/src/main/java/io/bitsquare/gui/FatalException.java b/src/main/java/io/bitsquare/BitsquareException.java
similarity index 73%
rename from src/main/java/io/bitsquare/gui/FatalException.java
rename to src/main/java/io/bitsquare/BitsquareException.java
index 1ceb228864..ced9490e4f 100644
--- a/src/main/java/io/bitsquare/gui/FatalException.java
+++ b/src/main/java/io/bitsquare/BitsquareException.java
@@ -15,16 +15,20 @@
* along with Bitsquare. If not, see .
*/
-package io.bitsquare.gui;
+package io.bitsquare;
@SuppressWarnings("serializable")
-public class FatalException extends RuntimeException {
+public class BitsquareException extends RuntimeException {
- public FatalException(String format, Object... args) {
+ public BitsquareException(Throwable cause) {
+ super(cause);
+ }
+
+ public BitsquareException(String format, Object... args) {
super(String.format(format, args));
}
- public FatalException(Throwable cause, String format, Object... args) {
+ public BitsquareException(Throwable cause, String format, Object... args) {
super(String.format(format, args), cause);
}
}
diff --git a/src/main/java/io/bitsquare/BitsquareModule.java b/src/main/java/io/bitsquare/BitsquareModule.java
index 9293650999..1e244cc936 100644
--- a/src/main/java/io/bitsquare/BitsquareModule.java
+++ b/src/main/java/io/bitsquare/BitsquareModule.java
@@ -22,17 +22,18 @@ import com.google.common.collect.Sets;
import com.google.inject.AbstractModule;
import com.google.inject.Injector;
-import java.util.Properties;
import java.util.Set;
+import org.springframework.core.env.Environment;
+
public abstract class BitsquareModule extends AbstractModule {
- protected final Properties properties;
+ protected final Environment env;
private final Set modules = Sets.newHashSet();
- protected BitsquareModule(Properties properties) {
- this.properties = properties;
+ protected BitsquareModule(Environment env) {
+ this.env = env;
}
protected void install(BitsquareModule module) {
diff --git a/src/main/java/io/bitsquare/app/ArgumentParser.java b/src/main/java/io/bitsquare/app/ArgumentParser.java
deleted file mode 100644
index e3a847d77e..0000000000
--- a/src/main/java/io/bitsquare/app/ArgumentParser.java
+++ /dev/null
@@ -1,75 +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 .
- */
-
-package io.bitsquare.app;
-
-import io.bitsquare.btc.BitcoinModule;
-import io.bitsquare.network.Node;
-
-import net.sourceforge.argparse4j.ArgumentParsers;
-import net.sourceforge.argparse4j.inf.ArgumentParserException;
-import net.sourceforge.argparse4j.inf.Namespace;
-
-import static io.bitsquare.app.AppModule.APP_NAME_KEY;
-import static io.bitsquare.msg.tomp2p.TomP2PMessageModule.*;
-
-public class ArgumentParser {
-
- private final net.sourceforge.argparse4j.inf.ArgumentParser parser;
-
- public ArgumentParser() {
- parser = ArgumentParsers.newArgumentParser("Bitsquare")
- .defaultHelp(true)
- .description("Bitsquare - The decentralized bitcoin exchange");
-
- // Args for local node config
- parser.addArgument("--" + Node.NAME_KEY)
- .help("Local node name");
- parser.addArgument("--" + Node.PORT_KEY)
- .help("Local node port");
-
- // Args for bootstrap node config
- parser.addArgument("--" + BOOTSTRAP_NODE_NAME_KEY)
- .help("Bootstrap node name");
- parser.addArgument("--" + BOOTSTRAP_NODE_IP_KEY)
- .help("Bootstrap node IP address");
- parser.addArgument("--" + BOOTSTRAP_NODE_PORT_KEY)
- .help("Bootstrap node port");
-
- // A custom network interface (needed at the moment for windows, but might be useful also later)
- parser.addArgument("--" + NETWORK_INTERFACE_KEY)
- .help("Network interface");
-
- parser.addArgument("--" + BitcoinModule.BITCOIN_NETWORK_KEY)
- .setDefault(BitcoinModule.DEFAULT_BITCOIN_NETWORK.toString())
- .help("Bitcoin network to use");
-
- // Args for app config
- parser.addArgument("-n", "--" + APP_NAME_KEY)
- .help("Name to append to default application name");
- }
-
- public Namespace parseArgs(String... args) {
- try {
- return parser.parseArgs(args);
- } catch (ArgumentParserException e) {
- parser.handleError(e);
- System.exit(1);
- return null;
- }
- }
-}
diff --git a/src/main/java/io/bitsquare/app/BitsquareEnvironment.java b/src/main/java/io/bitsquare/app/BitsquareEnvironment.java
new file mode 100644
index 0000000000..2155ba3bf8
--- /dev/null
+++ b/src/main/java/io/bitsquare/app/BitsquareEnvironment.java
@@ -0,0 +1,98 @@
+/*
+ * 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 .
+ */
+
+package io.bitsquare.app;
+
+import io.bitsquare.BitsquareException;
+
+import com.google.common.base.Preconditions;
+
+import java.io.IOException;
+
+import java.util.Properties;
+
+import joptsimple.OptionSet;
+import lighthouse.files.AppDirectory;
+import org.springframework.core.env.JOptCommandLinePropertySource;
+import org.springframework.core.env.MutablePropertySources;
+import org.springframework.core.env.PropertiesPropertySource;
+import org.springframework.core.env.PropertySource;
+import org.springframework.core.env.StandardEnvironment;
+import org.springframework.core.io.DefaultResourceLoader;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.core.io.support.ResourcePropertySource;
+
+public class BitsquareEnvironment extends StandardEnvironment {
+
+ public static final String APP_NAME_KEY = "appName";
+ public static final String DEFAULT_APP_NAME = "Bitsquare";
+
+ private static final String BITSQUARE_APP_PROPERTY_SOURCE_NAME = "bitsquareAppProperties";
+ 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_COMMANDLINE_PROPERTY_SOURCE_NAME = "bitsquareCommandLineProperties";
+
+ private final ResourceLoader resourceLoader = new DefaultResourceLoader();
+
+ public BitsquareEnvironment(OptionSet options) {
+ Preconditions.checkArgument(options != null, "Options must not be null");
+
+ PropertySource commandLineProperties =
+ new JOptCommandLinePropertySource(BITSQUARE_COMMANDLINE_PROPERTY_SOURCE_NAME, options);
+
+ String appName = commandLineProperties.containsProperty(APP_NAME_KEY) ?
+ DEFAULT_APP_NAME + "-" + commandLineProperties.getProperty(APP_NAME_KEY) :
+ DEFAULT_APP_NAME;
+
+ MutablePropertySources propertySources = this.getPropertySources();
+ propertySources.addBefore(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, appProperties(appName));
+ propertySources.addBefore(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, classpathProperties());
+ propertySources.addBefore(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, filesystemProperties(appName));
+ propertySources.addAfter(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, commandLineProperties);
+ }
+
+ private PropertySource> appProperties(String appName) {
+ return new PropertiesPropertySource(BITSQUARE_APP_PROPERTY_SOURCE_NAME, new Properties() {{
+ setProperty(APP_NAME_KEY, appName);
+ }});
+ }
+
+ private PropertySource> classpathProperties() {
+ try {
+ Resource resource = resourceLoader.getResource("classpath:bitsquare.properties");
+ return new ResourcePropertySource(BITSQUARE_CLASSPATH_PROPERTY_SOURCE_NAME, resource);
+ } catch (IOException ex) {
+ throw new BitsquareException(ex);
+ }
+ }
+
+ private PropertySource> filesystemProperties(String appName) {
+ String location = String.format("file:%s/bitsquare.conf", AppDirectory.dir(appName));
+ Resource resource = resourceLoader.getResource(location);
+
+ if (!resource.exists()) {
+ return new PropertySource.StubPropertySource(BITSQUARE_FILESYSTEM_PROPERTY_SOURCE_NAME);
+ }
+
+ try {
+ return new ResourcePropertySource(BITSQUARE_FILESYSTEM_PROPERTY_SOURCE_NAME, resource);
+ } catch (IOException ex) {
+ throw new BitsquareException(ex);
+ }
+ }
+}
diff --git a/src/main/java/io/bitsquare/app/BitsquareExecutable.java b/src/main/java/io/bitsquare/app/BitsquareExecutable.java
new file mode 100644
index 0000000000..fd5b3f35f4
--- /dev/null
+++ b/src/main/java/io/bitsquare/app/BitsquareExecutable.java
@@ -0,0 +1,57 @@
+/*
+ * 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 .
+ */
+
+package io.bitsquare.app;
+
+import joptsimple.OptionException;
+import joptsimple.OptionParser;
+import joptsimple.OptionSet;
+
+public abstract class BitsquareExecutable {
+ public static final int EXIT_SUCCESS = 0;
+ public static final int EXIT_FAILURE = 1;
+ public static final String HELP_KEY = "help";
+
+ public void execute(String[] args) throws Exception {
+ OptionParser parser = new OptionParser();
+ parser.accepts(HELP_KEY, "This help text").forHelp();
+
+ this.customizeOptionParsing(parser);
+
+ OptionSet options;
+ try {
+ options = parser.parse(args);
+ if (options.has(HELP_KEY)) {
+ parser.printHelpOn(System.out);
+ System.exit(EXIT_SUCCESS);
+ return;
+ }
+ } catch (OptionException ex) {
+ System.out.println("error: " + ex.getMessage());
+ System.out.println();
+ parser.printHelpOn(System.out);
+ System.exit(EXIT_FAILURE);
+ return;
+ }
+
+ this.doExecute(options);
+ }
+
+ protected abstract void customizeOptionParsing(OptionParser parser);
+
+ protected abstract void doExecute(OptionSet options);
+}
diff --git a/src/main/java/io/bitsquare/app/cli/BootstrapNode.java b/src/main/java/io/bitsquare/app/cli/BootstrapNode.java
index b5d076a4a6..296d7e55b0 100644
--- a/src/main/java/io/bitsquare/app/cli/BootstrapNode.java
+++ b/src/main/java/io/bitsquare/app/cli/BootstrapNode.java
@@ -17,7 +17,6 @@
package io.bitsquare.app.cli;
-import io.bitsquare.app.ArgumentParser;
import io.bitsquare.network.Node;
import net.tomp2p.dht.PeerBuilderDHT;
@@ -33,7 +32,7 @@ import net.tomp2p.rpc.ObjectDataReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import net.sourceforge.argparse4j.inf.Namespace;
+import org.springframework.core.env.Environment;
public class BootstrapNode {
private static final Logger log = LoggerFactory.getLogger(BootstrapNode.class);
@@ -41,16 +40,15 @@ public class BootstrapNode {
private static Peer peer = null;
private static boolean running = true;
- public static void main(String[] args) throws Exception {
- ArgumentParser parser = new ArgumentParser();
- Namespace namespace = parser.parseArgs(args);
+ private final Environment env;
- String name = namespace.getString(Node.NAME_KEY);
- if (name == null)
- throw new IllegalArgumentException(String.format("--%s option is required", Node.NAME_KEY));
+ public BootstrapNode(Environment env) {
+ this.env = env;
+ }
- String portValue = namespace.getString(Node.PORT_KEY);
- int port = portValue != null ? Integer.valueOf(portValue) : Node.DEFAULT_PORT;
+ public void start() {
+ String name = env.getRequiredProperty(Node.NAME_KEY);
+ int port = env.getProperty(Node.PORT_KEY, Integer.class, Node.DEFAULT_PORT);
try {
Number160 peerId = Number160.createHash(name);
@@ -90,12 +88,4 @@ public class BootstrapNode {
peer.shutdown().awaitUninterruptibly();
}
}
-
- public static void stop() {
- running = false;
- if (peer != null) {
- peer.shutdown().awaitUninterruptibly();
- }
- peer = null;
- }
}
diff --git a/src/main/java/io/bitsquare/app/cli/BootstrapNodeMain.java b/src/main/java/io/bitsquare/app/cli/BootstrapNodeMain.java
new file mode 100644
index 0000000000..b45849e4f6
--- /dev/null
+++ b/src/main/java/io/bitsquare/app/cli/BootstrapNodeMain.java
@@ -0,0 +1,42 @@
+/*
+ * 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 .
+ */
+
+package io.bitsquare.app.cli;
+
+import io.bitsquare.app.BitsquareEnvironment;
+import io.bitsquare.app.BitsquareExecutable;
+import io.bitsquare.network.Node;
+
+import joptsimple.OptionParser;
+import joptsimple.OptionSet;
+
+public class BootstrapNodeMain extends BitsquareExecutable {
+
+ public static void main(String[] args) throws Exception {
+ new BootstrapNodeMain().execute(args);
+ }
+
+ protected void customizeOptionParsing(OptionParser parser) {
+ parser.accepts(Node.NAME_KEY, "Name of this node").withRequiredArg().isRequired();
+ parser.accepts(Node.PORT_KEY, "Port to listen on").withRequiredArg()
+ .defaultsTo(String.valueOf(Node.DEFAULT_PORT));
+ }
+
+ protected void doExecute(OptionSet options) {
+ new BootstrapNode(new BitsquareEnvironment(options)).start();
+ }
+}
diff --git a/src/main/java/io/bitsquare/app/gui/Main.java b/src/main/java/io/bitsquare/app/gui/BitsquareApp.java
similarity index 61%
rename from src/main/java/io/bitsquare/app/gui/Main.java
rename to src/main/java/io/bitsquare/app/gui/BitsquareApp.java
index 899d7aba7c..2fe756c9de 100644
--- a/src/main/java/io/bitsquare/app/gui/Main.java
+++ b/src/main/java/io/bitsquare/app/gui/BitsquareApp.java
@@ -17,7 +17,7 @@
package io.bitsquare.app.gui;
-import io.bitsquare.app.ArgumentParser;
+import io.bitsquare.app.BitsquareEnvironment;
import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.SystemTray;
import io.bitsquare.gui.ViewLoader;
@@ -26,8 +26,8 @@ import io.bitsquare.gui.util.ImageUtil;
import io.bitsquare.persistence.Persistence;
import io.bitsquare.settings.Settings;
import io.bitsquare.user.User;
-import io.bitsquare.util.ConfigLoader;
+import com.google.common.base.Preconditions;
import com.google.common.base.Throwables;
import com.google.inject.Guice;
@@ -35,8 +35,6 @@ import com.google.inject.Injector;
import java.io.IOException;
-import java.util.Properties;
-
import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.image.*;
@@ -47,59 +45,28 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import lighthouse.files.AppDirectory;
-import net.sourceforge.argparse4j.inf.Namespace;
+import org.springframework.core.env.Environment;
-import static io.bitsquare.app.AppModule.APP_NAME_KEY;
-import static io.bitsquare.btc.BitcoinModule.BITCOIN_NETWORK_KEY;
-import static io.bitsquare.msg.tomp2p.TomP2PMessageModule.*;
-import static io.bitsquare.network.Node.*;
+public class BitsquareApp extends Application {
+ private static final Logger log = LoggerFactory.getLogger(BitsquareApp.class);
-public class Main extends Application {
- private static final Logger log = LoggerFactory.getLogger(Main.class);
- private static String appName = "Bitsquare";
- private static Properties properties;
+ private static Environment env;
- private MainModule mainModule;
+ private BitsquareAppModule bitsquareAppModule;
private Injector injector;
- public static void main(String[] args) {
- Namespace argumentsNamespace = new ArgumentParser().parseArgs(args);
-
- if (argumentsNamespace.getString(APP_NAME_KEY) != null)
- appName = appName + "-" + argumentsNamespace.getString(APP_NAME_KEY);
-
- properties = ConfigLoader.loadConfig(appName);
-
- properties.setProperty(APP_NAME_KEY, appName);
-
- if (argumentsNamespace.getString(NAME_KEY) != null)
- properties.setProperty(NAME_KEY, argumentsNamespace.getString(NAME_KEY));
-
- if (argumentsNamespace.getString(PORT_KEY) != null)
- properties.setProperty(PORT_KEY, argumentsNamespace.getString(PORT_KEY));
-
- if (argumentsNamespace.getString(BOOTSTRAP_NODE_NAME_KEY) != null)
- properties.setProperty(BOOTSTRAP_NODE_NAME_KEY, argumentsNamespace.getString(BOOTSTRAP_NODE_NAME_KEY));
-
- if (argumentsNamespace.getString(BOOTSTRAP_NODE_IP_KEY) != null)
- properties.setProperty(BOOTSTRAP_NODE_IP_KEY, argumentsNamespace.getString(BOOTSTRAP_NODE_IP_KEY));
-
- if (argumentsNamespace.getString(BOOTSTRAP_NODE_PORT_KEY) != null)
- properties.setProperty(BOOTSTRAP_NODE_PORT_KEY, argumentsNamespace.getString(BOOTSTRAP_NODE_PORT_KEY));
-
- if (argumentsNamespace.getString(NETWORK_INTERFACE_KEY) != null)
- properties.setProperty(NETWORK_INTERFACE_KEY, argumentsNamespace.getString(NETWORK_INTERFACE_KEY));
-
- if (argumentsNamespace.getString(BITCOIN_NETWORK_KEY) != null)
- properties.setProperty(BITCOIN_NETWORK_KEY, argumentsNamespace.getString(BITCOIN_NETWORK_KEY));
-
- Application.launch(Main.class, args);
+ public static void setEnvironment(Environment env) {
+ BitsquareApp.env = env;
}
@Override
- public void start(Stage primaryStage) {
- mainModule = new MainModule(properties, primaryStage);
- injector = Guice.createInjector(mainModule);
+ public void start(Stage primaryStage) throws IOException {
+ Preconditions.checkArgument(env != null, "Environment must not be null");
+
+ String appName = env.getRequiredProperty(BitsquareEnvironment.APP_NAME_KEY);
+
+ bitsquareAppModule = new BitsquareAppModule(env, primaryStage);
+ injector = Guice.createInjector(bitsquareAppModule);
// route uncaught exceptions to a user-facing dialog
@@ -173,7 +140,7 @@ public class Main extends Application {
@Override
public void stop() {
- mainModule.close(injector);
+ bitsquareAppModule.close(injector);
System.exit(0);
}
}
diff --git a/src/main/java/io/bitsquare/app/gui/BitsquareAppMain.java b/src/main/java/io/bitsquare/app/gui/BitsquareAppMain.java
new file mode 100644
index 0000000000..1bc8fbe0b5
--- /dev/null
+++ b/src/main/java/io/bitsquare/app/gui/BitsquareAppMain.java
@@ -0,0 +1,57 @@
+/*
+ * 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 .
+ */
+
+package io.bitsquare.app.gui;
+
+import io.bitsquare.app.BitsquareEnvironment;
+import io.bitsquare.app.BitsquareExecutable;
+import io.bitsquare.btc.BitcoinModule;
+import io.bitsquare.network.BootstrapNodes;
+import io.bitsquare.network.Node;
+
+import joptsimple.OptionParser;
+import joptsimple.OptionSet;
+
+import static io.bitsquare.app.BitsquareEnvironment.APP_NAME_KEY;
+import static io.bitsquare.btc.BitcoinModule.BITCOIN_NETWORK_KEY;
+import static io.bitsquare.msg.tomp2p.TomP2PMessageModule.*;
+import static io.bitsquare.network.Node.*;
+
+public class BitsquareAppMain extends BitsquareExecutable {
+
+ public static void main(String[] args) throws Exception {
+ new BitsquareAppMain().execute(args);
+ }
+
+ @Override
+ protected void customizeOptionParsing(OptionParser parser) {
+ parser.accepts(APP_NAME_KEY, "Qualified application name").withRequiredArg();
+ parser.accepts(NAME_KEY, "Name of this node").withRequiredArg();
+ 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(BOOTSTRAP_NODE_NAME_KEY).withRequiredArg().defaultsTo(BootstrapNodes.DEFAULT.getName());
+ parser.accepts(BOOTSTRAP_NODE_IP_KEY).withRequiredArg().defaultsTo(BootstrapNodes.DEFAULT.getIp());
+ parser.accepts(BOOTSTRAP_NODE_PORT_KEY).withRequiredArg().defaultsTo(BootstrapNodes.DEFAULT.getPortAsString());
+ parser.accepts(NETWORK_INTERFACE_KEY, "Network interface").withRequiredArg();
+ }
+
+ @Override
+ protected void doExecute(OptionSet options) {
+ BitsquareApp.setEnvironment(new BitsquareEnvironment(options));
+ javafx.application.Application.launch(BitsquareApp.class);
+ }
+}
diff --git a/src/main/java/io/bitsquare/app/AppModule.java b/src/main/java/io/bitsquare/app/gui/BitsquareAppModule.java
similarity index 71%
rename from src/main/java/io/bitsquare/app/AppModule.java
rename to src/main/java/io/bitsquare/app/gui/BitsquareAppModule.java
index 8b7a134a0e..8e2343f059 100644
--- a/src/main/java/io/bitsquare/app/AppModule.java
+++ b/src/main/java/io/bitsquare/app/gui/BitsquareAppModule.java
@@ -15,11 +15,13 @@
* along with Bitsquare. If not, see .
*/
-package io.bitsquare.app;
+package io.bitsquare.app.gui;
import io.bitsquare.BitsquareModule;
+import io.bitsquare.app.BitsquareEnvironment;
import io.bitsquare.btc.BitcoinModule;
import io.bitsquare.crypto.CryptoModule;
+import io.bitsquare.gui.GuiModule;
import io.bitsquare.msg.MessageModule;
import io.bitsquare.msg.tomp2p.TomP2PMessageModule;
import io.bitsquare.offer.OfferModule;
@@ -29,21 +31,20 @@ import io.bitsquare.settings.Settings;
import io.bitsquare.trade.TradeModule;
import io.bitsquare.user.User;
-import com.google.common.base.Preconditions;
-
import com.google.inject.Injector;
import com.google.inject.name.Names;
-import java.util.Properties;
+import javafx.stage.Stage;
-/**
- * Configures all non-UI modules necessary to run a Bitsquare application.
- */
-public class AppModule extends BitsquareModule {
- public static final String APP_NAME_KEY = "appName";
+import org.springframework.core.env.Environment;
- public AppModule(Properties properties) {
- super(properties);
+class BitsquareAppModule extends BitsquareModule {
+
+ private final Stage primaryStage;
+
+ public BitsquareAppModule(Environment env, Stage primaryStage) {
+ super(env);
+ this.primaryStage = primaryStage;
}
@Override
@@ -57,35 +58,38 @@ public class AppModule extends BitsquareModule {
install(cryptoModule());
install(tradeModule());
install(offerModule());
+ install(guiModule());
- String appName = properties.getProperty(APP_NAME_KEY);
- Preconditions.checkArgument(appName != null, "App name must be non-null");
+ String appName = env.getRequiredProperty(BitsquareEnvironment.APP_NAME_KEY);
bindConstant().annotatedWith(Names.named("appName")).to(appName);
}
protected MessageModule messageModule() {
- return new TomP2PMessageModule(properties);
+ return new TomP2PMessageModule(env);
}
protected BitcoinModule bitcoinModule() {
- return new BitcoinModule(properties);
+ return new BitcoinModule(env);
}
protected CryptoModule cryptoModule() {
- return new CryptoModule(properties);
+ return new CryptoModule(env);
}
protected TradeModule tradeModule() {
- return new TradeModule(properties);
+ return new TradeModule(env);
}
protected OfferModule offerModule() {
- return new TomP2POfferModule(properties);
+ return new TomP2POfferModule(env);
+ }
+
+ protected GuiModule guiModule() {
+ return new GuiModule(env, primaryStage);
}
@Override
protected void doClose(Injector injector) {
}
}
-
diff --git a/src/main/java/io/bitsquare/btc/BitcoinModule.java b/src/main/java/io/bitsquare/btc/BitcoinModule.java
index c43edba080..1d77a557ff 100644
--- a/src/main/java/io/bitsquare/btc/BitcoinModule.java
+++ b/src/main/java/io/bitsquare/btc/BitcoinModule.java
@@ -26,15 +26,15 @@ import org.bitcoinj.params.TestNet3Params;
import com.google.inject.Injector;
-import java.util.Properties;
+import org.springframework.core.env.Environment;
public class BitcoinModule extends BitsquareModule {
public static final String BITCOIN_NETWORK_KEY = "bitcoin.network";
public static final String DEFAULT_BITCOIN_NETWORK = BitcoinNetwork.TESTNET.toString();
- public BitcoinModule(Properties properties) {
- super(properties);
+ public BitcoinModule(Environment env) {
+ super(env);
}
@Override
@@ -52,7 +52,7 @@ public class BitcoinModule extends BitsquareModule {
private NetworkParameters network() {
BitcoinNetwork network = BitcoinNetwork.valueOf(
- properties.getProperty(BITCOIN_NETWORK_KEY, DEFAULT_BITCOIN_NETWORK).toUpperCase());
+ env.getProperty(BITCOIN_NETWORK_KEY, DEFAULT_BITCOIN_NETWORK).toUpperCase());
switch (network) {
case MAINNET:
diff --git a/src/main/java/io/bitsquare/crypto/CryptoModule.java b/src/main/java/io/bitsquare/crypto/CryptoModule.java
index fc3472c98b..77189b2d3f 100644
--- a/src/main/java/io/bitsquare/crypto/CryptoModule.java
+++ b/src/main/java/io/bitsquare/crypto/CryptoModule.java
@@ -19,12 +19,12 @@ package io.bitsquare.crypto;
import io.bitsquare.BitsquareModule;
-import java.util.Properties;
+import org.springframework.core.env.Environment;
public class CryptoModule extends BitsquareModule {
- public CryptoModule(Properties properties) {
- super(properties);
+ public CryptoModule(Environment env) {
+ super(env);
}
@Override
diff --git a/src/main/java/io/bitsquare/gui/GuiModule.java b/src/main/java/io/bitsquare/gui/GuiModule.java
index 8491ce60bb..48f06c1975 100644
--- a/src/main/java/io/bitsquare/gui/GuiModule.java
+++ b/src/main/java/io/bitsquare/gui/GuiModule.java
@@ -28,16 +28,16 @@ import io.bitsquare.gui.util.validation.FiatValidator;
import io.bitsquare.gui.util.validation.InputValidator;
import io.bitsquare.gui.util.validation.PasswordValidator;
-import java.util.Properties;
-
import javafx.stage.Stage;
+import org.springframework.core.env.Environment;
+
public class GuiModule extends BitsquareModule {
private final Stage primaryStage;
- public GuiModule(Properties properties, Stage primaryStage) {
- super(properties);
+ public GuiModule(Environment env, Stage primaryStage) {
+ super(env);
this.primaryStage = primaryStage;
}
diff --git a/src/main/java/io/bitsquare/gui/ViewLoader.java b/src/main/java/io/bitsquare/gui/ViewLoader.java
index 1de55a7a2e..fc3d7b3b9c 100644
--- a/src/main/java/io/bitsquare/gui/ViewLoader.java
+++ b/src/main/java/io/bitsquare/gui/ViewLoader.java
@@ -17,6 +17,7 @@
package io.bitsquare.gui;
+import io.bitsquare.BitsquareException;
import io.bitsquare.locale.BSResources;
import com.google.inject.Injector;
@@ -56,7 +57,7 @@ public class ViewLoader {
public ViewLoader(Navigation.FxmlResource navItem, boolean useCaching) {
this.url = ViewLoader.class.getResource(navItem.getFxmlUrl());
if (this.url == null) {
- throw new FatalException("'%s' could not be loaded as a resource", navItem.getFxmlUrl());
+ throw new BitsquareException("'%s' could not be loaded as a resource", navItem.getFxmlUrl());
}
isCached = useCaching && cachedGUIItems.containsKey(url);
@@ -87,7 +88,7 @@ public class ViewLoader {
cachedGUIItems.put(url, item);
return result;
} catch (IOException e) {
- throw new FatalException(e, "Failed to load view at %s", url);
+ throw new BitsquareException(e, "Failed to load view at %s", url);
}
}
diff --git a/src/main/java/io/bitsquare/msg/MessageModule.java b/src/main/java/io/bitsquare/msg/MessageModule.java
index e7092fa4da..14c358adbe 100644
--- a/src/main/java/io/bitsquare/msg/MessageModule.java
+++ b/src/main/java/io/bitsquare/msg/MessageModule.java
@@ -21,12 +21,12 @@ import io.bitsquare.BitsquareModule;
import com.google.inject.Injector;
-import java.util.Properties;
+import org.springframework.core.env.Environment;
public abstract class MessageModule extends BitsquareModule {
- protected MessageModule(Properties properties) {
- super(properties);
+ protected MessageModule(Environment env) {
+ super(env);
}
@Override
diff --git a/src/main/java/io/bitsquare/msg/tomp2p/TomP2PMessageModule.java b/src/main/java/io/bitsquare/msg/tomp2p/TomP2PMessageModule.java
index d1c1e7ca45..e4d49908c6 100644
--- a/src/main/java/io/bitsquare/msg/tomp2p/TomP2PMessageModule.java
+++ b/src/main/java/io/bitsquare/msg/tomp2p/TomP2PMessageModule.java
@@ -24,7 +24,7 @@ import io.bitsquare.network.Node;
import com.google.inject.name.Names;
-import java.util.Properties;
+import org.springframework.core.env.Environment;
import static io.bitsquare.msg.tomp2p.BootstrappedPeerFactory.*;
@@ -35,25 +35,25 @@ public class TomP2PMessageModule extends MessageModule {
public static final String BOOTSTRAP_NODE_PORT_KEY = "bootstrap.node.port";
public static final String NETWORK_INTERFACE_KEY = BootstrappedPeerFactory.NETWORK_INTERFACE_KEY;
- public TomP2PMessageModule(Properties properties) {
- super(properties);
+ public TomP2PMessageModule(Environment env) {
+ super(env);
}
@Override
protected void doConfigure() {
bind(int.class).annotatedWith(Names.named(Node.PORT_KEY)).toInstance(
- Integer.valueOf(properties.getProperty(Node.PORT_KEY, String.valueOf(Node.DEFAULT_PORT))));
+ env.getProperty(Node.PORT_KEY, Integer.class, Node.DEFAULT_PORT));
bind(TomP2PNode.class).asEagerSingleton();
bind(Node.class).annotatedWith(Names.named(BOOTSTRAP_NODE_KEY)).toInstance(
Node.at(
- properties.getProperty(BOOTSTRAP_NODE_NAME_KEY, BootstrapNodes.DEFAULT.getName()),
- properties.getProperty(BOOTSTRAP_NODE_IP_KEY, BootstrapNodes.DEFAULT.getIp()),
- properties.getProperty(BOOTSTRAP_NODE_PORT_KEY, BootstrapNodes.DEFAULT.getPortAsString())
+ env.getProperty(BOOTSTRAP_NODE_NAME_KEY, BootstrapNodes.DEFAULT.getName()),
+ env.getProperty(BOOTSTRAP_NODE_IP_KEY, BootstrapNodes.DEFAULT.getIp()),
+ env.getProperty(BOOTSTRAP_NODE_PORT_KEY, BootstrapNodes.DEFAULT.getPortAsString())
)
);
bindConstant().annotatedWith(Names.named(NETWORK_INTERFACE_KEY)).to(
- properties.getProperty(NETWORK_INTERFACE_KEY, NETWORK_INTERFACE_UNSPECIFIED));
+ env.getProperty(NETWORK_INTERFACE_KEY, NETWORK_INTERFACE_UNSPECIFIED));
bind(BootstrappedPeerFactory.class).asEagerSingleton();
}
diff --git a/src/main/java/io/bitsquare/offer/OfferModule.java b/src/main/java/io/bitsquare/offer/OfferModule.java
index a83627f92e..227c30656b 100644
--- a/src/main/java/io/bitsquare/offer/OfferModule.java
+++ b/src/main/java/io/bitsquare/offer/OfferModule.java
@@ -19,12 +19,12 @@ package io.bitsquare.offer;
import io.bitsquare.BitsquareModule;
-import java.util.Properties;
+import org.springframework.core.env.Environment;
public abstract class OfferModule extends BitsquareModule {
- protected OfferModule(Properties properties) {
- super(properties);
+ protected OfferModule(Environment env) {
+ super(env);
}
@Override
diff --git a/src/main/java/io/bitsquare/offer/tomp2p/TomP2POfferModule.java b/src/main/java/io/bitsquare/offer/tomp2p/TomP2POfferModule.java
index fb7e3729ad..af2262573d 100644
--- a/src/main/java/io/bitsquare/offer/tomp2p/TomP2POfferModule.java
+++ b/src/main/java/io/bitsquare/offer/tomp2p/TomP2POfferModule.java
@@ -20,12 +20,12 @@ package io.bitsquare.offer.tomp2p;
import io.bitsquare.offer.OfferModule;
import io.bitsquare.offer.OfferRepository;
-import java.util.Properties;
+import org.springframework.core.env.Environment;
public class TomP2POfferModule extends OfferModule {
- public TomP2POfferModule(Properties properties) {
- super(properties);
+ public TomP2POfferModule(Environment env) {
+ super(env);
}
@Override
diff --git a/src/main/java/io/bitsquare/trade/TradeModule.java b/src/main/java/io/bitsquare/trade/TradeModule.java
index 626e01e6ce..30242578f7 100644
--- a/src/main/java/io/bitsquare/trade/TradeModule.java
+++ b/src/main/java/io/bitsquare/trade/TradeModule.java
@@ -19,12 +19,12 @@ package io.bitsquare.trade;
import io.bitsquare.BitsquareModule;
-import java.util.Properties;
+import org.springframework.core.env.Environment;
public class TradeModule extends BitsquareModule {
- public TradeModule(Properties properties) {
- super(properties);
+ public TradeModule(Environment env) {
+ super(env);
}
@Override
diff --git a/src/main/java/io/bitsquare/util/ConfigLoader.java b/src/main/java/io/bitsquare/util/ConfigLoader.java
deleted file mode 100644
index 484cd7823c..0000000000
--- a/src/main/java/io/bitsquare/util/ConfigLoader.java
+++ /dev/null
@@ -1,77 +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 .
- */
-
-package io.bitsquare.util;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-import java.util.Properties;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import lighthouse.files.AppDirectory;
-
-public class ConfigLoader {
- private static final Logger log = LoggerFactory.getLogger(ConfigLoader.class);
- private static String configFilePath;
-
- public static Properties loadConfig(String appName) {
- configFilePath = AppDirectory.dir(appName) + "/bitsquare.conf";
- InputStream inputStream = null;
-
- // load default properties from class path
- Properties defaultProperties = new Properties();
- try {
- InputStream is = ConfigLoader.class.getResourceAsStream("/bitsquare.properties");
- defaultProperties.load(is);
- } catch (IOException ioe) {
- ioe.printStackTrace();
- } finally {
- if (inputStream != null) {
- try {
- inputStream.close();
- } catch (IOException ioe) {
- ioe.printStackTrace();
- }
- }
- }
-
- // load properties file from config file path
- Properties properties = new Properties(defaultProperties);
- if (new File(configFilePath).exists()) {
- try {
- inputStream = new FileInputStream(configFilePath);
- properties.load(inputStream);
- } catch (IOException ioe) {
- ioe.printStackTrace();
- } finally {
- if (inputStream != null) {
- try {
- inputStream.close();
- } catch (IOException ioe) {
- ioe.printStackTrace();
- }
- }
- }
- }
- return properties;
- }
-}
diff --git a/src/main/java/io/bitsquare/app/gui/MainModule.java b/src/test/java/io/bitsquare/BitsquareEnvironmentTests.java
similarity index 50%
rename from src/main/java/io/bitsquare/app/gui/MainModule.java
rename to src/test/java/io/bitsquare/BitsquareEnvironmentTests.java
index 7fd38c8c52..c962effb94 100644
--- a/src/main/java/io/bitsquare/app/gui/MainModule.java
+++ b/src/test/java/io/bitsquare/BitsquareEnvironmentTests.java
@@ -15,27 +15,27 @@
* along with Bitsquare. If not, see .
*/
-package io.bitsquare.app.gui;
+package io.bitsquare;
-import io.bitsquare.BitsquareModule;
-import io.bitsquare.app.AppModule;
-import io.bitsquare.gui.GuiModule;
+import io.bitsquare.app.BitsquareEnvironment;
-import java.util.Properties;
+import org.junit.Test;
-import javafx.stage.Stage;
+import joptsimple.OptionParser;
-class MainModule extends BitsquareModule {
- private final Stage primaryStage;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.junit.Assert.*;
- public MainModule(Properties properties, Stage primaryStage) {
- super(properties);
- this.primaryStage = primaryStage;
+public class BitsquareEnvironmentTests {
+
+ @Test
+ public void test() {
+ String[] args = new String[]{ "--arg1=val1", "--arg2=val2" };
+ OptionParser parser = new OptionParser();
+ parser.accepts("arg1").withRequiredArg();
+ parser.accepts("arg2").withRequiredArg();
+ BitsquareEnvironment env = new BitsquareEnvironment(parser.parse(args));
+ assertThat(env.getProperty("arg1"), equalTo("val1"));
+ assertThat(env.getProperty("arg2"), equalTo("val2"));
}
-
- @Override
- protected void configure() {
- install(new AppModule(properties));
- install(new GuiModule(properties, primaryStage));
- }
-}
+}
\ No newline at end of file
diff --git a/src/test/java/io/bitsquare/app/gui/ViewLoaderTests.java b/src/test/java/io/bitsquare/app/gui/ViewLoaderTests.java
index b766d5aab0..d0d79f7aea 100644
--- a/src/test/java/io/bitsquare/app/gui/ViewLoaderTests.java
+++ b/src/test/java/io/bitsquare/app/gui/ViewLoaderTests.java
@@ -17,7 +17,8 @@
package io.bitsquare.app.gui;
-import io.bitsquare.gui.FatalException;
+import io.bitsquare.BitsquareException;
+import io.bitsquare.app.BitsquareEnvironment;
import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.ViewLoader;
@@ -34,7 +35,8 @@ import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
-import static io.bitsquare.app.AppModule.APP_NAME_KEY;
+import joptsimple.OptionParser;
+import org.springframework.core.env.PropertiesPropertySource;
public class ViewLoaderTests {
@@ -64,8 +66,11 @@ public class ViewLoaderTests {
@Before
public void setUp() {
Properties properties = new Properties();
- properties.setProperty(APP_NAME_KEY, "testApp");
- Injector injector = Guice.createInjector(new MainModule(properties, TestApp.primaryStage));
+ properties.setProperty(BitsquareEnvironment.APP_NAME_KEY, "testApp");
+ OptionParser parser = new OptionParser();
+ BitsquareEnvironment env = new BitsquareEnvironment(parser.parse(new String[] {}));
+ env.getPropertySources().addLast(new PropertiesPropertySource("testProperties", properties));
+ Injector injector = Guice.createInjector(new BitsquareAppModule(env, TestApp.primaryStage));
ViewLoader.setInjector(injector);
}
@@ -74,7 +79,7 @@ public class ViewLoaderTests {
ViewLoader.setInjector(null);
}
- @Test(expected = FatalException.class)
+ @Test(expected = BitsquareException.class)
public void loadingBogusFxmlResourceShouldThrow() {
new ViewLoader(() -> "a bogus fxml resource", false).load();
}