summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJesse Morgan <jesse@jesterpm.net>2013-06-04 21:16:00 -0700
committerJesse Morgan <jesse@jesterpm.net>2013-06-04 21:16:00 -0700
commitf4c2eb2dafbca580319a9f50ef4f5dd68d658702 (patch)
tree6b393681913cd41c21583120f01452d0b5995a51 /src
parent3b6dc4955f0aa67b2610b1bc90f156dd9a9d6cab (diff)
Adding config support.
Diffstat (limited to 'src')
-rw-r--r--src/com/p4square/grow/config/Config.java148
-rw-r--r--src/com/p4square/grow/frontend/GrowFrontend.java42
-rw-r--r--src/com/p4square/grow/frontend/SurveyPageResource.java7
3 files changed, 194 insertions, 3 deletions
diff --git a/src/com/p4square/grow/config/Config.java b/src/com/p4square/grow/config/Config.java
new file mode 100644
index 0000000..f5ebe3c
--- /dev/null
+++ b/src/com/p4square/grow/config/Config.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2013 Jesse Morgan
+ */
+
+package com.p4square.grow.config;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.util.Properties;
+
+import org.apache.log4j.Logger;
+
+/**
+ * Manage configuration for an application.
+ *
+ * Config reads one or more property files as the application config. Duplicate
+ * properties loaded later override properties loaded earlier. Config has the
+ * concept of a domain to distinguish settings for development and production.
+ * The default domain is prod for production. Domain can be any String such as
+ * dev for development or test for testing.
+ *
+ * The property files are processed like java.util.Properties except that the
+ * keys are specified as DOMAIN.KEY. An asterisk (*) can be used in place of a
+ * domain to indicate it should apply to all domains. If a domain specific entry
+ * exists for the current domain, it will override any global config.
+ *
+ * @author Jesse Morgan <jesse@jesterpm.net>
+ */
+public class Config {
+ private static Logger cLog = Logger.getLogger(Config.class);
+
+ private String mDomain;
+ private Properties mProperties;
+
+ /**
+ * Construct a new Config object. Domain defaults to prod.
+ */
+ public Config() {
+ mDomain = "prod";
+ mProperties = new Properties();
+
+ }
+
+ /**
+ * Change the domain from the default string "prod".
+ *
+ * @param domain The new domain.
+ */
+ public void setDomain(String domain) {
+ mDomain = domain;
+ }
+
+ /**
+ * Load properties from a file.
+ * Any exceptions are logged and suppressed.
+ */
+ public void updateConfig(String propertyFilename) {
+ final File propFile = new File(propertyFilename);
+
+ cLog.info("Loading properties from " + propFile);
+
+ try {
+ InputStream in = new FileInputStream(propFile);
+ updateConfig(in);
+
+ } catch (IOException e) {
+ cLog.error("Could not load properties file: " + e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Load properties from an InputStream.
+ * This method closes the InputStream when it completes.
+ *
+ * @param in The InputStream
+ */
+ public void updateConfig(InputStream in) throws IOException {
+ mProperties.load(in);
+ in.close();
+ }
+
+ /**
+ * Get a String from the config.
+ *
+ * @return The config value or null if it is not found.
+ */
+ public String getString(String key) {
+ return getString(key, null);
+ }
+
+ /**
+ * Get a String from the config.
+ *
+ * @return The config value or defaultValue if it can not be found.
+ */
+ public String getString(String key, String defaultValue) {
+ String result;
+
+ final String domainKey = mDomain + "." + key;
+ result = mProperties.getProperty(domainKey, defaultValue);
+ if (result != null) {
+ return result;
+ }
+
+ final String globalKey = "*." + key;
+ result = mProperties.getProperty(globalKey, defaultValue);
+ if (result != null) {
+ return result;
+ }
+
+ return defaultValue;
+ }
+
+ /**
+ * Get an integer from the config.
+ *
+ * @return The config value or Integer.MIN_VALUE if the key is not present or the
+ * config can not be parsed.
+ */
+ public int getInt(String key) {
+ return getInt(key, Integer.MIN_VALUE);
+ }
+
+ /**
+ * Get an integer from the config.
+ *
+ * @return The config value or defaultValue if the key is not present or the
+ * config can not be parsed.
+ */
+ public int getInt(String key, int defaultValue) {
+ final String propertyValue = getString(key);
+
+ if (propertyValue != null) {
+ try {
+ final int result = Integer.valueOf(propertyValue);
+ return result;
+
+ } catch (NumberFormatException e) {
+ cLog.warn("Expected property to be an integer: "
+ + key + " = { " + propertyValue + " }");
+ }
+ }
+
+ return defaultValue;
+ }
+}
diff --git a/src/com/p4square/grow/frontend/GrowFrontend.java b/src/com/p4square/grow/frontend/GrowFrontend.java
index 72e2a8f..e3662d5 100644
--- a/src/com/p4square/grow/frontend/GrowFrontend.java
+++ b/src/com/p4square/grow/frontend/GrowFrontend.java
@@ -13,6 +13,8 @@ import org.apache.log4j.Logger;
import net.jesterpm.fmfacade.FMFacade;
import net.jesterpm.fmfacade.FreeMarkerPageResource;
+import com.p4square.grow.config.Config;
+
/**
* This is the Restlet Application implementing the Grow project front-end.
* It's implemented as an extension of FMFacade that connects interactive pages
@@ -24,6 +26,34 @@ import net.jesterpm.fmfacade.FreeMarkerPageResource;
public class GrowFrontend extends FMFacade {
private static Logger cLog = Logger.getLogger(GrowFrontend.class);
+ private Config mConfig;
+
+ public GrowFrontend() {
+ mConfig = new Config();
+ }
+
+ public Config getConfig() {
+ return mConfig;
+ }
+
+ @Override
+ public void start() throws Exception {
+ super.start();
+
+ final String configDomain =
+ getContext().getParameters().getFirstValue("config-domain");
+ if (configDomain != null) {
+ mConfig.setDomain(configDomain);
+ }
+
+ final String configFilename =
+ getContext().getParameters().getFirstValue("config-file");
+
+ if (configFilename != null) {
+ mConfig.updateConfig(configFilename);
+ }
+ }
+
@Override
protected Router createRouter() {
Router router = new Router(getContext());
@@ -54,7 +84,17 @@ public class GrowFrontend extends FMFacade {
final Component component = new Component();
component.getServers().add(Protocol.HTTP, 8085);
component.getClients().add(Protocol.HTTP);
- component.getDefaultHost().attach(new GrowFrontend());
+
+ // Setup App
+ GrowFrontend app = new GrowFrontend();
+
+ // Load an optional config file from the first argument.
+ app.getConfig().setDomain("dev");
+ if (args.length == 1) {
+ app.getConfig().updateConfig(args[0]);
+ }
+
+ component.getDefaultHost().attach(app);
// Setup shutdown hook
Runtime.getRuntime().addShutdownHook(new Thread() {
diff --git a/src/com/p4square/grow/frontend/SurveyPageResource.java b/src/com/p4square/grow/frontend/SurveyPageResource.java
index 72a2d34..e7fcd07 100644
--- a/src/com/p4square/grow/frontend/SurveyPageResource.java
+++ b/src/com/p4square/grow/frontend/SurveyPageResource.java
@@ -23,6 +23,8 @@ import net.jesterpm.fmfacade.json.JsonResponse;
import net.jesterpm.fmfacade.FreeMarkerPageResource;
+import com.p4square.grow.config.Config;
+
/**
* SurveyPageResource handles rendering the survey and processing user's answers.
*
@@ -36,6 +38,7 @@ import net.jesterpm.fmfacade.FreeMarkerPageResource;
public class SurveyPageResource extends FreeMarkerPageResource {
private static Logger cLog = Logger.getLogger(SurveyPageResource.class);
+ private Config mConfig;
private Template mSurveyTemplate;
private JsonRequestClient mJsonClient;
@@ -48,6 +51,7 @@ public class SurveyPageResource extends FreeMarkerPageResource {
super.doInit();
GrowFrontend growFrontend = (GrowFrontend) getApplication();
+ mConfig = growFrontend.getConfig();
mSurveyTemplate = growFrontend.getTemplate("templates/survey.ftl");
if (mSurveyTemplate == null) {
cLog.fatal("Could not find survey template.");
@@ -172,8 +176,7 @@ public class SurveyPageResource extends FreeMarkerPageResource {
* @return The backend endpoint URI
*/
private String getBackendEndpoint() {
- // TODO: Config
- return "http://localhost:9095";
+ return mConfig.getString("backendUri", "http://localhost:9095");
}
/**