diff --git a/build.gradle b/build.gradle index d7126cc9e4..afe21cc5e8 100644 --- a/build.gradle +++ b/build.gradle @@ -49,6 +49,7 @@ dependencies { compile 'org.jetbrains:annotations:13.0' compile 'eu.hansolo.enzo:Enzo:0.1.5' testCompile 'junit:junit:4.11' + testCompile 'org.springframework:spring-test:4.1.1.RELEASE' } task packageNative(type: Exec, dependsOn: shadowJar) { diff --git a/src/main/java/io/bitsquare/app/BitsquareEnvironment.java b/src/main/java/io/bitsquare/app/BitsquareEnvironment.java index 47e56d0a73..daa5f15680 100644 --- a/src/main/java/io/bitsquare/app/BitsquareEnvironment.java +++ b/src/main/java/io/bitsquare/app/BitsquareEnvironment.java @@ -23,10 +23,6 @@ import io.bitsquare.btc.WalletFacade; import io.bitsquare.gui.ViewCB; import io.bitsquare.persistence.Persistence; -import com.google.common.base.Preconditions; - -import java.io.IOException; - import java.nio.file.Paths; import java.util.Properties; @@ -42,51 +38,59 @@ import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import org.springframework.core.io.support.ResourcePropertySource; -public class BitsquareEnvironment extends StandardEnvironment { +import static com.google.common.base.Preconditions.checkNotNull; - public static final String APP_NAME_KEY = "app.name"; - public static final String DEFAULT_APP_NAME = "Bitsquare"; +public class BitsquareEnvironment extends StandardEnvironment { 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_NAME_KEY = "app.name"; + public static final String DEFAULT_APP_NAME = "Bitsquare"; + 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_FILESYSTEM_PROPERTY_SOURCE_NAME = "bitsquareFilesystemProperties"; - private static final String BITSQUARE_COMMANDLINE_PROPERTY_SOURCE_NAME = "bitsquareCommandLineProperties"; + static final String BITSQUARE_DEFAULT_PROPERTY_SOURCE_NAME = "bitsquareDefaultProperties"; + static final String BITSQUARE_CLASSPATH_PROPERTY_SOURCE_NAME = "bitsquareClasspathProperties"; + static final String BITSQUARE_FILESYSTEM_PROPERTY_SOURCE_NAME = "bitsquareFilesystemProperties"; + static final String BITSQUARE_COMMANDLINE_PROPERTY_SOURCE_NAME = "bitsquareCommandLineProperties"; private final ResourceLoader resourceLoader = new DefaultResourceLoader(); + private final String appName; + private final String appDataDir; + 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) ? - (String) commandLineProperties.getProperty(APP_NAME_KEY) : - DEFAULT_APP_NAME; + this(new JOptCommandLinePropertySource(BITSQUARE_COMMANDLINE_PROPERTY_SOURCE_NAME, checkNotNull(options))); + } + BitsquareEnvironment(PropertySource commandLineProperties) { 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) ? + this.appName = commandLineProperties.containsProperty(APP_NAME_KEY) ? + (String) commandLineProperties.getProperty(APP_NAME_KEY) : + DEFAULT_APP_NAME; + + this.appDataDir = commandLineProperties.containsProperty(APP_DATA_DIR_KEY) ? (String) commandLineProperties.getProperty(APP_DATA_DIR_KEY) : appDataDir(userDataDir, appName); MutablePropertySources propertySources = this.getPropertySources(); - 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, filesystemProperties(appDataDir)); - propertySources.addAfter(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, commandLineProperties); + propertySources.addFirst(commandLineProperties); + try { + propertySources.addLast(filesystemProperties()); + propertySources.addLast(classpathProperties()); + propertySources.addLast(defaultProperties()); + } catch (Exception ex) { + throw new BitsquareException(ex); + } } - private PropertySource defaultProperties(String appDataDir, String appName) { + PropertySource defaultProperties() throws Exception { return new PropertiesPropertySource(BITSQUARE_DEFAULT_PROPERTY_SOURCE_NAME, new Properties() {{ setProperty(APP_DATA_DIR_KEY, appDataDir); setProperty(APP_NAME_KEY, appName); @@ -104,28 +108,19 @@ public class BitsquareEnvironment extends StandardEnvironment { }}); } - 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); - } + PropertySource classpathProperties() throws Exception { + Resource resource = resourceLoader.getResource("classpath:bitsquare.properties"); + return new ResourcePropertySource(BITSQUARE_CLASSPATH_PROPERTY_SOURCE_NAME, resource); } - private PropertySource filesystemProperties(String appDir) { - String location = String.format("file:%s/bitsquare.conf", appDir); + PropertySource filesystemProperties() throws Exception { + String location = String.format("file:%s/bitsquare.conf", appDataDir); Resource resource = resourceLoader.getResource(location); - if (!resource.exists()) { + 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); - } + return new ResourcePropertySource(BITSQUARE_FILESYSTEM_PROPERTY_SOURCE_NAME, resource); } diff --git a/src/main/java/io/bitsquare/app/gui/BitsquareAppMain.java b/src/main/java/io/bitsquare/app/gui/BitsquareAppMain.java index dffb8d87eb..da72226152 100644 --- a/src/main/java/io/bitsquare/app/gui/BitsquareAppMain.java +++ b/src/main/java/io/bitsquare/app/gui/BitsquareAppMain.java @@ -39,8 +39,8 @@ public class BitsquareAppMain extends BitsquareExecutable { @Override protected void customizeOptionParsing(OptionParser parser) { - parser.accepts(APP_NAME_KEY, "Application name").withRequiredArg().defaultsTo(DEFAULT_APP_NAME); parser.accepts(USER_DATA_DIR_KEY, "User data directory").withRequiredArg().defaultsTo(DEFAULT_USER_DATA_DIR); + parser.accepts(APP_NAME_KEY, "Application name").withRequiredArg().defaultsTo(DEFAULT_APP_NAME); 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)); diff --git a/src/test/java/io/bitsquare/app/BitsquareEnvironmentTests.java b/src/test/java/io/bitsquare/app/BitsquareEnvironmentTests.java index fa54068a39..e9c94fbf4c 100644 --- a/src/test/java/io/bitsquare/app/BitsquareEnvironmentTests.java +++ b/src/test/java/io/bitsquare/app/BitsquareEnvironmentTests.java @@ -19,13 +19,43 @@ package io.bitsquare.app; import org.junit.Test; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.MutablePropertySources; +import org.springframework.core.env.PropertySource; +import org.springframework.mock.env.MockPropertySource; + +import static io.bitsquare.app.BitsquareEnvironment.*; import static org.hamcrest.CoreMatchers.equalTo; import static org.junit.Assert.*; +import static org.springframework.core.env.PropertySource.named; +import static org.springframework.core.env.StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME; +import static org.springframework.core.env.StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME; public class BitsquareEnvironmentTests { @Test - public void test() { - assertThat(1, equalTo(1)); + public void testPropertySourcePrecedence() { + PropertySource commandlineProps = new MockPropertySource(BITSQUARE_COMMANDLINE_PROPERTY_SOURCE_NAME) + .withProperty("key.x", "x.commandline"); + + PropertySource filesystemProps = new MockPropertySource(BITSQUARE_FILESYSTEM_PROPERTY_SOURCE_NAME) + .withProperty("key.x", "x.env") + .withProperty("key.y", "y.env"); + + ConfigurableEnvironment env = new BitsquareEnvironment(commandlineProps) { + @Override PropertySource filesystemProperties() { return filesystemProps; } + }; + MutablePropertySources propertySources = env.getPropertySources(); + + assertThat(propertySources.precedenceOf(named(BITSQUARE_COMMANDLINE_PROPERTY_SOURCE_NAME)), equalTo(0)); + assertThat(propertySources.precedenceOf(named(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME)), equalTo(1)); + assertThat(propertySources.precedenceOf(named(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME)), equalTo(2)); + assertThat(propertySources.precedenceOf(named(BITSQUARE_FILESYSTEM_PROPERTY_SOURCE_NAME)), equalTo(3)); + assertThat(propertySources.precedenceOf(named(BITSQUARE_CLASSPATH_PROPERTY_SOURCE_NAME)), equalTo(4)); + assertThat(propertySources.precedenceOf(named(BITSQUARE_DEFAULT_PROPERTY_SOURCE_NAME)), equalTo(5)); + assertThat(propertySources.size(), equalTo(6)); + + assertThat(env.getProperty("key.x"), equalTo("x.commandline")); // commandline value wins due to precedence + assertThat(env.getProperty("key.y"), equalTo("y.env")); // env value wins because it's the only one available } } \ No newline at end of file