Add Java version of the examples

This commit is contained in:
Havoc Pennington 2013-09-27 16:15:54 -04:00
parent 15e5ad4e6e
commit 05197ab17e
13 changed files with 200 additions and 6 deletions

View File

View File

@ -0,0 +1,78 @@
import com.typesafe.config.*;
import simplelib.*;
class ComplexApp {
// Simple-lib is a library in this same examples/ directory.
// This method demos usage of that library with the config
// provided.
private static void demoConfigInSimpleLib(Config config) {
SimpleLibContext context = new SimpleLibContext(config);
context.printSetting("simple-lib.foo");
context.printSetting("simple-lib.hello");
context.printSetting("simple-lib.whatever");
}
public static void main(String[] args) {
// This app is "complex" because we load multiple separate app
// configs into a single JVM and we have a separately-configurable
// context for simple lib.
// system property overrides work, but the properties must be set
// before the config lib is used (config lib will not notice changes
// once it loads the properties)
System.setProperty("simple-lib.whatever", "This value comes from a system property");
// /////////
// "config1" is just an example of using a file other than
// application.conf
Config config1 = ConfigFactory.load("complex1");
// use the config ourselves
System.out.println("config1, complex-app.something="
+ config1.getString("complex-app.something"));
// use the config for a library
demoConfigInSimpleLib(config1);
// ////////
// "config2" shows how to configure a library with a custom settings
// subtree
Config config2 = ConfigFactory.load("complex2");
// use the config ourselves
System.out.println("config2, complex-app.something="
+ config2.getString("complex-app.something"));
// pull out complex-app.simple-lib-context and move it to
// the toplevel, creating a new config suitable for our
// SimpleLibContext.
// The defaultOverrides() have to be put back on top of the stack so
// they still override any simple-lib settings.
// We fall back to config2 again to be sure we get simple-lib's
// reference.conf plus any other settings we've set. You could
// also just fall back to ConfigFactory.referenceConfig() if
// you don't want complex2.conf settings outside of
// complex-app.simple-lib-context to be used.
Config simpleLibConfig2 = ConfigFactory.defaultOverrides()
.withFallback(config2.getConfig("complex-app.simple-lib-context"))
.withFallback(config2);
demoConfigInSimpleLib(simpleLibConfig2);
// ////////
// Here's an illustration that simple-lib will get upset if we pass it
// a bad config. In this case, we'll fail to merge the reference
// config in to complex-app.simple-lib-context, so simple-lib will
// point out that some settings are missing.
try {
demoConfigInSimpleLib(config2.getConfig("complex-app.simple-lib-context"));
} catch (ConfigException.ValidationFailed e) {
System.out.println("when we passed a bad config to simple-lib, it said: "
+ e.getMessage());
}
}
}

View File

@ -0,0 +1,8 @@
# these are our own config values defined by the app
complex-app {
something="This value comes from complex-app's complex1.conf"
}
# Here we override some values used by a library
simple-lib.foo="This value comes from complex-app's complex1.conf"
simple-lib.whatever = "This value comes from complex-app's complex1.conf"

View File

@ -0,0 +1,13 @@
complex-app {
something="This value comes from complex-app's complex2.conf"
# here we want a simple-lib-context unique to our app
# which can be custom-configured. In code, we have to
# pull out this subtree and pass it to simple-lib.
simple-lib-context = {
simple-lib {
foo="This value comes from complex-app's complex2.conf in its custom simple-lib-context"
whatever = "This value comes from complex-app's complex2.conf in its custom simple-lib-context"
}
}
}

View File

View File

@ -0,0 +1,27 @@
import com.typesafe.config.*;
import simplelib.*;
class SimpleApp {
public static void main(String[] args) {
// example of how system properties override; note this
// must be set before the config lib is used
System.setProperty("simple-lib.whatever", "This value comes from a system property");
// Load our own config values from the default location,
// application.conf
Config conf = ConfigFactory.load();
System.out.println("The answer is: " + conf.getString("simple-app.answer"));
// In this simple app, we're allowing SimpleLibContext() to
// use the default config in application.conf ; this is exactly
// the same as passing in ConfigFactory.load() here, so we could
// also write "new SimpleLibContext(conf)" and it would be the same.
// (simple-lib is a library in this same examples/ directory).
// The point is that SimpleLibContext defaults to ConfigFactory.load()
// but also allows us to pass in our own Config.
SimpleLibContext context = new SimpleLibContext();
context.printSetting("simple-lib.foo");
context.printSetting("simple-lib.hello");
context.printSetting("simple-lib.whatever");
}
}

View File

@ -0,0 +1,8 @@
# these are our own config values defined by the app
simple-app {
answer=42
}
# Here we override some values used by a library
simple-lib.foo="This value comes from simple-app's application.conf"
simple-lib.whatever = "This value comes from simple-app's application.conf"

View File

View File

@ -0,0 +1,34 @@
package simplelib;
import com.typesafe.config.*;
// Whenever you write a library, allow people to supply a Config but
// also default to ConfigFactory.load if they don't supply one.
// Libraries generally have some kind of Context or other object
// where it's convenient to place the configuration.
public class SimpleLibContext {
private Config config;
// we have a constructor allowing the app to provide a custom Config
public SimpleLibContext(Config config) {
this.config = config;
// This verifies that the Config is sane and has our
// reference config. Importantly, we specify the "simple-lib"
// path so we only validate settings that belong to this
// library. Otherwise, we might throw mistaken errors about
// settings we know nothing about.
config.checkValid(ConfigFactory.defaultReference(), "simple-lib");
}
// This uses the standard default Config, if none is provided,
// which simplifies apps willing to use the defaults
public SimpleLibContext() {
this(ConfigFactory.load());
}
// this is the amazing functionality provided by simple-lib
public void printSetting(String path) {
System.out.println("The setting '" + path + "' is: " + config.getString(path));
}
}

View File

@ -0,0 +1,5 @@
simple-lib {
foo = "This value comes from simple-lib's reference.conf"
hello = "This value comes from simple-lib's reference.conf"
whatever = "This value comes from simple-lib's reference.conf"
}

View File

@ -14,7 +14,9 @@ object SimpleApp extends App {
// use the default config in application.conf ; this is exactly
// the same as passing in ConfigFactory.load() here, so we could
// also write "new SimpleLibContext(conf)" and it would be the same.
// (simple-lib is a library in this same examples/ directory)
// (simple-lib is a library in this same examples/ directory).
// The point is that SimpleLibContext defaults to ConfigFactory.load()
// but also allows us to pass in our own Config.
val context = new SimpleLibContext()
context.printSetting("simple-lib.foo")
context.printSetting("simple-lib.hello")

View File

@ -2,6 +2,11 @@ package simplelib
import com.typesafe.config._
// Whenever you write a library, allow people to supply a Config but
// also default to ConfigFactory.load if they don't supply one.
// Libraries generally have some kind of Context or other object
// where it's convenient to place the configuration.
// we have a constructor allowing the app to provide a custom Config
class SimpleLibContext(config: Config) {

View File

@ -26,7 +26,9 @@ object ConfigBuild extends Build {
lazy val root = Project(id = "root",
base = file("."),
settings = Project.defaultSettings ++ unpublished) aggregate(testLib, configLib, simpleLibScala, simpleAppScala, complexAppScala)
settings = Project.defaultSettings ++ unpublished) aggregate(testLib, configLib,
simpleLibScala, simpleAppScala, complexAppScala,
simpleLibJava, simpleAppJava, complexAppJava)
lazy val configLib = Project(id = "config",
base = file("config"),
@ -40,21 +42,33 @@ object ConfigBuild extends Build {
artifact in (Compile, packageBin) ~= { _.copy(`type` = "bundle") }
)) dependsOn(testLib % "test->test")
lazy val testLib = Project(id = "test-lib",
lazy val testLib = Project(id = "config-test-lib",
base = file("test-lib"),
settings = Project.defaultSettings ++ unpublished)
lazy val simpleLibScala = Project(id = "simple-lib",
lazy val simpleLibScala = Project(id = "config-simple-lib-scala",
base = file("examples/scala/simple-lib"),
settings = Project.defaultSettings ++ unpublished) dependsOn(configLib)
lazy val simpleAppScala = Project(id = "simple-app",
lazy val simpleAppScala = Project(id = "config-simple-app-scala",
base = file("examples/scala/simple-app"),
settings = Project.defaultSettings ++ unpublished) dependsOn(simpleLibScala)
lazy val complexAppScala = Project(id = "complex-app",
lazy val complexAppScala = Project(id = "config-complex-app-scala",
base = file("examples/scala/complex-app"),
settings = Project.defaultSettings ++ unpublished) dependsOn(simpleLibScala)
lazy val simpleLibJava = Project(id = "config-simple-lib-java",
base = file("examples/java/simple-lib"),
settings = Project.defaultSettings ++ unpublished) dependsOn(configLib)
lazy val simpleAppJava = Project(id = "config-simple-app-java",
base = file("examples/java/simple-app"),
settings = Project.defaultSettings ++ unpublished) dependsOn(simpleLibJava)
lazy val complexAppJava = Project(id = "config-complex-app-java",
base = file("examples/java/complex-app"),
settings = Project.defaultSettings ++ unpublished) dependsOn(simpleLibJava)
}
// from https://raw.github.com/paulp/scala-improving/master/project/PublishToSonatype.scala