diff --git a/Configuration/lib/isaac-configuration-1.0.10-SNAPSHOT_dependency.jar b/Configuration/lib/isaac-configuration-1.0.10-SNAPSHOT_dependency.jar
deleted file mode 100644
index 1fdbb07..0000000
Binary files a/Configuration/lib/isaac-configuration-1.0.10-SNAPSHOT_dependency.jar and /dev/null differ
diff --git a/Configuration/lib_ori/isaac-configuration-1.0.10-SNAPSHOT.jar b/Configuration/lib_ori/isaac-configuration-1.0.10-SNAPSHOT.jar
deleted file mode 100644
index f207482..0000000
Binary files a/Configuration/lib_ori/isaac-configuration-1.0.10-SNAPSHOT.jar and /dev/null differ
diff --git a/Configuration/src/com/dotmarketing/plugin/business/PluginAPIImpl.java b/Configuration/src/com/dotmarketing/plugin/business/PluginAPIImpl.java
index ee5ad3d..9e25545 100644
--- a/Configuration/src/com/dotmarketing/plugin/business/PluginAPIImpl.java
+++ b/Configuration/src/com/dotmarketing/plugin/business/PluginAPIImpl.java
@@ -13,8 +13,8 @@
import java.util.List;
import java.util.NoSuchElementException;
+import nl.isaac.comp.configuration.CustomConfiguration;
import nl.isaac.dotcms.plugin.configuration.ConfigurationService;
-import nl.isaac.dotcms.plugin.configuration.dependencies.nl.isaac.comp.configuration.CustomConfiguration;
import nl.isaac.dotcms.plugin.configuration.dependencies.org.apache.commons.configuration.ConfigurationException;
import nl.isaac.dotcms.plugin.configuration.exception.ConfigurationNotFoundException;
diff --git a/Configuration/src/nl/isaac/comp/configuration/CombinedConfigurationWrapper.java b/Configuration/src/nl/isaac/comp/configuration/CombinedConfigurationWrapper.java
new file mode 100644
index 0000000..8531fde
--- /dev/null
+++ b/Configuration/src/nl/isaac/comp/configuration/CombinedConfigurationWrapper.java
@@ -0,0 +1,457 @@
+package nl.isaac.comp.configuration;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+
+import nl.isaac.dotcms.plugin.configuration.dependencies.org.apache.commons.configuration.AbstractConfiguration;
+import nl.isaac.dotcms.plugin.configuration.dependencies.org.apache.commons.configuration.CombinedConfiguration;
+import nl.isaac.dotcms.plugin.configuration.dependencies.org.apache.commons.configuration.Configuration;
+import nl.isaac.dotcms.plugin.configuration.dependencies.org.apache.commons.configuration.HierarchicalConfiguration;
+import nl.isaac.dotcms.plugin.configuration.dependencies.org.apache.commons.configuration.HierarchicalConfiguration.Node;
+import nl.isaac.dotcms.plugin.configuration.dependencies.org.apache.commons.configuration.SubnodeConfiguration;
+import nl.isaac.dotcms.plugin.configuration.dependencies.org.apache.commons.configuration.event.ConfigurationErrorListener;
+import nl.isaac.dotcms.plugin.configuration.dependencies.org.apache.commons.configuration.event.ConfigurationEvent;
+import nl.isaac.dotcms.plugin.configuration.dependencies.org.apache.commons.configuration.event.ConfigurationListener;
+import nl.isaac.dotcms.plugin.configuration.dependencies.org.apache.commons.configuration.interpol.ConfigurationInterpolator;
+import nl.isaac.dotcms.plugin.configuration.dependencies.org.apache.commons.configuration.tree.ConfigurationNode;
+import nl.isaac.dotcms.plugin.configuration.dependencies.org.apache.commons.configuration.tree.ExpressionEngine;
+import nl.isaac.dotcms.plugin.configuration.dependencies.org.apache.commons.configuration.tree.NodeCombiner;
+import nl.isaac.dotcms.plugin.configuration.dependencies.org.apache.commons.lang.text.StrSubstitutor;
+import nl.isaac.dotcms.plugin.configuration.dependencies.org.apache.commons.logging.Log;
+
+
+/**
+ * A wrapper class for {@link CombinedConfiguration}
+ * @author jan-willem
+ *
+ */
+public class CombinedConfigurationWrapper implements Configuration {
+
+ private final CombinedConfiguration configuration;
+
+ public CombinedConfigurationWrapper(CombinedConfiguration configuration) {
+ this.configuration = configuration;
+ }
+
+ /**
+ * Returns the delegated instance which was passed to {@link #HierarchicalConfigurationWrapper(HierarchicalConfiguration)}
+ * @return
+ */
+ public CombinedConfiguration getDelegate() {
+ return configuration;
+ }
+
+ public void addConfiguration(AbstractConfiguration config, String name,
+ String at) {
+ configuration.addConfiguration(config, name, at);
+ }
+
+ public void addConfiguration(AbstractConfiguration config, String name) {
+ configuration.addConfiguration(config, name);
+ }
+
+ public void addConfiguration(AbstractConfiguration config) {
+ configuration.addConfiguration(config);
+ }
+
+ public void addConfigurationListener(ConfigurationListener l) {
+ configuration.addConfigurationListener(l);
+ }
+
+ public void addErrorListener(ConfigurationErrorListener l) {
+ configuration.addErrorListener(l);
+ }
+
+ public void addErrorLogListener() {
+ configuration.addErrorLogListener();
+ }
+
+ public void addNodes(String key, Collection nodes) {
+ configuration.addNodes(key, nodes);
+ }
+
+ public void addProperty(String key, Object value) {
+ configuration.addProperty(key, value);
+ }
+
+ public void append(Configuration c) {
+ configuration.append(c);
+ }
+
+ public void clear() {
+ configuration.clear();
+ }
+
+ public void clearConfigurationListeners() {
+ configuration.clearConfigurationListeners();
+ }
+
+ public void clearErrorListeners() {
+ configuration.clearErrorListeners();
+ }
+
+ public void clearProperty(String key) {
+ configuration.clearProperty(key);
+ }
+
+ public void clearTree(String key) {
+ configuration.clearTree(key);
+ }
+
+ public Object clone() {
+ return configuration.clone();
+ }
+
+ public SubnodeConfiguration configurationAt(String key,
+ boolean supportUpdates) {
+ return configuration.configurationAt(key, supportUpdates);
+ }
+
+ public SubnodeConfiguration configurationAt(String key) {
+ return configuration.configurationAt(key);
+ }
+
+ public void configurationChanged(ConfigurationEvent event) {
+ configuration.configurationChanged(event);
+ }
+
+ public List configurationsAt(String key) {
+ return configuration.configurationsAt(key);
+ }
+
+ public boolean containsKey(String key) {
+ return configuration.containsKey(key);
+ }
+
+ public void copy(Configuration c) {
+ configuration.copy(c);
+ }
+
+ public boolean equals(Object obj) {
+ return configuration.equals(obj);
+ }
+
+ public BigDecimal getBigDecimal(String key, BigDecimal defaultValue) {
+ return configuration.getBigDecimal(key, defaultValue);
+ }
+
+ public BigDecimal getBigDecimal(String key) {
+ return configuration.getBigDecimal(key);
+ }
+
+ public BigInteger getBigInteger(String key, BigInteger defaultValue) {
+ return configuration.getBigInteger(key, defaultValue);
+ }
+
+ public BigInteger getBigInteger(String key) {
+ return configuration.getBigInteger(key);
+ }
+
+ public boolean getBoolean(String key, boolean defaultValue) {
+ return configuration.getBoolean(key, defaultValue);
+ }
+
+ public Boolean getBoolean(String key, Boolean defaultValue) {
+ return configuration.getBoolean(key, defaultValue);
+ }
+
+ public boolean getBoolean(String key) {
+ return configuration.getBoolean(key);
+ }
+
+ public byte getByte(String key, byte defaultValue) {
+ return configuration.getByte(key, defaultValue);
+ }
+
+ public Byte getByte(String key, Byte defaultValue) {
+ return configuration.getByte(key, defaultValue);
+ }
+
+ public byte getByte(String key) {
+ return configuration.getByte(key);
+ }
+
+ public Configuration getConfiguration(int index) {
+ return configuration.getConfiguration(index);
+ }
+
+ public Configuration getConfiguration(String name) {
+ return configuration.getConfiguration(name);
+ }
+
+ public Collection getConfigurationListeners() {
+ return configuration.getConfigurationListeners();
+ }
+
+ public Set getConfigurationNames() {
+ return configuration.getConfigurationNames();
+ }
+
+ public ExpressionEngine getConversionExpressionEngine() {
+ return configuration.getConversionExpressionEngine();
+ }
+
+ public double getDouble(String key, double defaultValue) {
+ return configuration.getDouble(key, defaultValue);
+ }
+
+ public Double getDouble(String key, Double defaultValue) {
+ return configuration.getDouble(key, defaultValue);
+ }
+
+ public double getDouble(String key) {
+ return configuration.getDouble(key);
+ }
+
+ public Collection getErrorListeners() {
+ return configuration.getErrorListeners();
+ }
+
+ public ExpressionEngine getExpressionEngine() {
+ return configuration.getExpressionEngine();
+ }
+
+ public float getFloat(String key, float defaultValue) {
+ return configuration.getFloat(key, defaultValue);
+ }
+
+ public Float getFloat(String key, Float defaultValue) {
+ return configuration.getFloat(key, defaultValue);
+ }
+
+ public float getFloat(String key) {
+ return configuration.getFloat(key);
+ }
+
+ public int getInt(String key, int defaultValue) {
+ return configuration.getInt(key, defaultValue);
+ }
+
+ public int getInt(String key) {
+ return configuration.getInt(key);
+ }
+
+ public Integer getInteger(String key, Integer defaultValue) {
+ return configuration.getInteger(key, defaultValue);
+ }
+
+ public ConfigurationInterpolator getInterpolator() {
+ return configuration.getInterpolator();
+ }
+
+ public Iterator getKeys() {
+ return configuration.getKeys();
+ }
+
+ public Iterator getKeys(String prefix) {
+ return configuration.getKeys(prefix);
+ }
+
+ public List getList(String key, List defaultValue) {
+ return configuration.getList(key, defaultValue);
+ }
+
+ public List getList(String key) {
+ return configuration.getList(key);
+ }
+
+ public char getListDelimiter() {
+ return configuration.getListDelimiter();
+ }
+
+ public Log getLogger() {
+ return configuration.getLogger();
+ }
+
+ public long getLong(String key, long defaultValue) {
+ return configuration.getLong(key, defaultValue);
+ }
+
+ public Long getLong(String key, Long defaultValue) {
+ return configuration.getLong(key, defaultValue);
+ }
+
+ public long getLong(String key) {
+ return configuration.getLong(key);
+ }
+
+ public int getMaxIndex(String key) {
+ return configuration.getMaxIndex(key);
+ }
+
+ public NodeCombiner getNodeCombiner() {
+ return configuration.getNodeCombiner();
+ }
+
+ public int getNumberOfConfigurations() {
+ return configuration.getNumberOfConfigurations();
+ }
+
+ public Properties getProperties(String key, Properties defaults) {
+ return configuration.getProperties(key, defaults);
+ }
+
+ public Properties getProperties(String key) {
+ return configuration.getProperties(key);
+ }
+
+ public Object getProperty(String key) {
+ return configuration.getProperty(key);
+ }
+
+ public Node getRoot() {
+ return configuration.getRoot();
+ }
+
+ public ConfigurationNode getRootNode() {
+ return configuration.getRootNode();
+ }
+
+ public short getShort(String key, short defaultValue) {
+ return configuration.getShort(key, defaultValue);
+ }
+
+ public Short getShort(String key, Short defaultValue) {
+ return configuration.getShort(key, defaultValue);
+ }
+
+ public short getShort(String key) {
+ return configuration.getShort(key);
+ }
+
+ public Configuration getSource(String key) {
+ return configuration.getSource(key);
+ }
+
+ public String getString(String key, String defaultValue) {
+ return configuration.getString(key, defaultValue);
+ }
+
+ public String getString(String key) {
+ return configuration.getString(key);
+ }
+
+ public String[] getStringArray(String key) {
+ return configuration.getStringArray(key);
+ }
+
+ public StrSubstitutor getSubstitutor() {
+ return configuration.getSubstitutor();
+ }
+
+ public int hashCode() {
+ return configuration.hashCode();
+ }
+
+ public Configuration interpolatedConfiguration() {
+ return configuration.interpolatedConfiguration();
+ }
+
+ public void invalidate() {
+ configuration.invalidate();
+ }
+
+ public boolean isDelimiterParsingDisabled() {
+ return configuration.isDelimiterParsingDisabled();
+ }
+
+ public boolean isDetailEvents() {
+ return configuration.isDetailEvents();
+ }
+
+ public boolean isEmpty() {
+ return configuration.isEmpty();
+ }
+
+ public boolean isForceReloadCheck() {
+ return configuration.isForceReloadCheck();
+ }
+
+ public boolean isThrowExceptionOnMissing() {
+ return configuration.isThrowExceptionOnMissing();
+ }
+
+ public boolean removeConfiguration(Configuration config) {
+ return configuration.removeConfiguration(config);
+ }
+
+ public Configuration removeConfiguration(String name) {
+ return configuration.removeConfiguration(name);
+ }
+
+ public Configuration removeConfigurationAt(int index) {
+ return configuration.removeConfigurationAt(index);
+ }
+
+ public boolean removeConfigurationListener(ConfigurationListener l) {
+ return configuration.removeConfigurationListener(l);
+ }
+
+ public boolean removeErrorListener(ConfigurationErrorListener l) {
+ return configuration.removeErrorListener(l);
+ }
+
+ public void setConversionExpressionEngine(
+ ExpressionEngine conversionExpressionEngine) {
+ configuration.setConversionExpressionEngine(conversionExpressionEngine);
+ }
+
+ public void setDelimiterParsingDisabled(boolean delimiterParsingDisabled) {
+ configuration.setDelimiterParsingDisabled(delimiterParsingDisabled);
+ }
+
+ public void setDetailEvents(boolean enable) {
+ configuration.setDetailEvents(enable);
+ }
+
+ public void setExpressionEngine(ExpressionEngine expressionEngine) {
+ configuration.setExpressionEngine(expressionEngine);
+ }
+
+ public void setForceReloadCheck(boolean forceReloadCheck) {
+ configuration.setForceReloadCheck(forceReloadCheck);
+ }
+
+ public void setListDelimiter(char listDelimiter) {
+ configuration.setListDelimiter(listDelimiter);
+ }
+
+ public void setLogger(Log log) {
+ configuration.setLogger(log);
+ }
+
+ public void setNodeCombiner(NodeCombiner nodeCombiner) {
+ configuration.setNodeCombiner(nodeCombiner);
+ }
+
+ public void setProperty(String key, Object value) {
+ configuration.setProperty(key, value);
+ }
+
+ public void setRoot(Node node) {
+ configuration.setRoot(node);
+ }
+
+ public void setRootNode(ConfigurationNode rootNode) {
+ configuration.setRootNode(rootNode);
+ }
+
+ public void setThrowExceptionOnMissing(boolean throwExceptionOnMissing) {
+ configuration.setThrowExceptionOnMissing(throwExceptionOnMissing);
+ }
+
+ public Configuration subset(String prefix) {
+ return configuration.subset(prefix);
+ }
+
+ public String toString() {
+ return configuration.toString();
+ }
+
+
+}
diff --git a/Configuration/src/nl/isaac/comp/configuration/ConfigurationFactory.java b/Configuration/src/nl/isaac/comp/configuration/ConfigurationFactory.java
new file mode 100644
index 0000000..7a25146
--- /dev/null
+++ b/Configuration/src/nl/isaac/comp/configuration/ConfigurationFactory.java
@@ -0,0 +1,117 @@
+package nl.isaac.comp.configuration;
+
+import nl.isaac.dotcms.plugin.configuration.dependencies.org.apache.commons.configuration.AbstractConfiguration;
+import nl.isaac.dotcms.plugin.configuration.dependencies.org.apache.commons.configuration.CombinedConfiguration;
+import nl.isaac.dotcms.plugin.configuration.dependencies.org.apache.commons.configuration.ConfigurationException;
+import nl.isaac.dotcms.plugin.configuration.dependencies.org.apache.commons.configuration.FileConfiguration;
+import nl.isaac.dotcms.plugin.configuration.dependencies.org.apache.commons.lang.exception.ExceptionUtils;
+
+import org.xml.sax.SAXParseException;
+
+import com.dotmarketing.util.Logger;
+
+/**
+ * A factory class with useful methods to load configurations
+ * @author jan-willem
+ *
+ */
+public class ConfigurationFactory {
+
+ private ConfigurationFactory() {
+ }
+
+ /**
+ * Convenient method for initializing a {@link CustomConfiguration} Object.
+ * Usage example:
+ *
+ * CustomConfiguration config = ConfigurationFactory.newConfiguration(MyConfigService.class.getClassLoader(), "META-INF/config.xml"); + * return new MyConfigPojo(config); + *+ * In addition, each additional xml configuration location is parsed and added to the resulting configuration as well. + * @param cl, the classLoader where config.xml is found + * @param configXmlLocation + * @param additionalXmlLocations + * @return + * @throws ConfigurationException + */ + public static CustomConfiguration newConfiguration(ClassLoader cl, String configXmlLocation, String... additionalXmlLocations) throws ConfigurationException { + + try { + + CustomConfigurationBuilder configurationBuilder = new CustomConfigurationBuilder(cl, configXmlLocation); + CombinedConfiguration config = configurationBuilder.getConfiguration(true); + + if (additionalXmlLocations != null && additionalXmlLocations.length > 0) { + + // this is a reference to the latest configuration loaded + // by adding the loaded configuration to the new configuration, previous loaded variables + // can be used in the new configuration and in config.xml's + AbstractConfiguration parentConfig = (AbstractConfiguration) config.clone(); + + for (String additionalXmlLocation : additionalXmlLocations) { + + CustomConfigurationBuilder additionalConfigurationBuilder = new CustomConfigurationBuilder(cl, additionalXmlLocation); + + CombinedConfiguration additionalConfig = additionalConfigurationBuilder.getConfiguration(true, parentConfig); + + config.addConfiguration(additionalConfig); + + parentConfig = (AbstractConfiguration) additionalConfig.clone(); + } + } + + // wrap it with a helper that contains convenient methods + return new CustomConfiguration(config); + + } catch (ConfigurationException e) { + + Throwable rootCause = ExceptionUtils.getRootCause(e); + + if (rootCause instanceof SAXParseException) { + + /* + * When an SAXParseException is thrown, create a new Exception that gives all known problems in one message + * instead of several exceptions + */ + Throwable cause2 = null; + + int indexOfCause1 = ExceptionUtils.indexOfThrowable(e, SAXParseException.class); + if (indexOfCause1 > 0) { + int indexOfCause2 = ExceptionUtils.indexOfThrowable(e, ConfigurationException.class, indexOfCause1 - 1); + if (indexOfCause2 >= 0) { + cause2 = ExceptionUtils.getThrowables(e)[indexOfCause2]; + } + } + + SAXParseException spe = (SAXParseException) rootCause; + String message = "Error parsing configuration, line=" + spe.getLineNumber() + ", column=" + spe.getColumnNumber(); + if (cause2 != null) { + message = cause2.getMessage() + ". " + message; + } + throw new ConfigurationException(message + ". " + rootCause.getMessage(), e.getCause()); + } + throw e; + } + } + + public static CustomConfiguration newConfiguration(ClassLoader cl, boolean logConfigurationDetails, String configXmlLocation, String... additionalXmlLocations) throws ConfigurationException { + + CustomConfiguration result = newConfiguration(cl, configXmlLocation, additionalXmlLocations); + logConfigurationDetails(result); + + return result; + } + + protected static void logConfigurationDetails(CustomConfiguration configuration) { + + StringBuffer configFiles = new StringBuffer(); + for (FileConfiguration cf : configuration.getLoadedFileConfigurations()) { + if (cf.getFile() != null) { + configFiles.append("\n\t").append(cf.getFile()); + } + } + + Logger.debug(ConfigurationFactory.class, "Used configuration files:" + configFiles.toString()); + Logger.debug(ConfigurationFactory.class, "Configuration result:\n" + configuration.toStringTree(true)); + } +} diff --git a/Configuration/src/nl/isaac/comp/configuration/CustomConfiguration.java b/Configuration/src/nl/isaac/comp/configuration/CustomConfiguration.java new file mode 100644 index 0000000..464b665 --- /dev/null +++ b/Configuration/src/nl/isaac/comp/configuration/CustomConfiguration.java @@ -0,0 +1,244 @@ +package nl.isaac.comp.configuration; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import nl.isaac.comp.configuration.visitor.ToStringMultiLineVisitor; +import nl.isaac.comp.configuration.visitor.ToStringSingleLineVisitor; +import nl.isaac.comp.configuration.visitor.ToStringTreeVisitor; +import nl.isaac.dotcms.plugin.configuration.dependencies.org.apache.commons.configuration.CombinedConfiguration; +import nl.isaac.dotcms.plugin.configuration.dependencies.org.apache.commons.configuration.Configuration; +import nl.isaac.dotcms.plugin.configuration.dependencies.org.apache.commons.configuration.FileConfiguration; +import nl.isaac.dotcms.plugin.configuration.dependencies.org.apache.commons.configuration.HierarchicalConfiguration; +import nl.isaac.dotcms.plugin.configuration.dependencies.org.apache.commons.configuration.tree.ConfigurationNodeVisitor; + + + +/** + * A ISAAC configuration class with additional helper methods compared to {@link CombinedConfiguration}
getConfiguration()
. It checks whether the
+ * header
section of the configuration definition file
+ * contains a result
element. If this is the case, it will be
+ * used to initialize the properties of the newly created configuration
+ * object.
+ *
+ * @return the resulting configuration object
+ * @throws ConfigurationException if an error occurs
+ */
+ @Override
+ protected CombinedConfiguration createResultConfiguration() throws ConfigurationException {
+
+ CombinedConfiguration result = super.createResultConfiguration();
+
+ if (parentConfigurationWhileParsing != null) {
+ result.addConfiguration(parentConfigurationWhileParsing);
+ }
+
+ return result;
+ }
+
+ @Override
+ public CombinedConfiguration getConfiguration(boolean load) throws ConfigurationException {
+
+ return getConfiguration(load, null);
+ }
+
+ /**
+ * @see #getConfiguration(boolean)
+ * @param load
+ * @param parentConfigurationWhileParsing the configuration to use while processing config.xml. The configuration is not part of the actual configuration when loaded
+ * @return
+ * @throws ConfigurationException
+ */
+ public CombinedConfiguration getConfiguration(boolean load, AbstractConfiguration parentConfigurationWhileParsing) throws ConfigurationException {
+
+ if (load && loadedOnInstantiation) {
+ load = false;
+ }
+
+ if (parentConfigurationWhileParsing != null) {
+
+ // this is used in createResultConfiguration();
+ this.parentConfigurationWhileParsing = parentConfigurationWhileParsing;
+ }
+
+ CombinedConfiguration combinedConfiguration = super.getConfiguration(load);
+
+ if (parentConfigurationWhileParsing != null) {
+
+ // and remove the configuration again since we only used it for parsing
+ combinedConfiguration.removeConfiguration(parentConfigurationWhileParsing);
+ }
+
+ return combinedConfiguration;
+ }
+
+ /**
+ * @see #getConfiguration(boolean, AbstractConfiguration)
+ * @param parentConfigurationWhileParsing the configuration to use while processing config.xml. The configuration is not part of the actual configuration when loaded
+ * @return
+ * @throws ConfigurationException
+ */
+ public Configuration getConfiguration(AbstractConfiguration parentConfigurationWhileParsing) throws ConfigurationException {
+ return getConfiguration(true, parentConfigurationWhileParsing);
+ }
+}
diff --git a/Configuration/src/nl/isaac/comp/configuration/InlinePropertiesConfigurationProvider.java b/Configuration/src/nl/isaac/comp/configuration/InlinePropertiesConfigurationProvider.java
new file mode 100644
index 0000000..c46f736
--- /dev/null
+++ b/Configuration/src/nl/isaac/comp/configuration/InlinePropertiesConfigurationProvider.java
@@ -0,0 +1,61 @@
+package nl.isaac.comp.configuration;
+
+import java.util.List;
+
+import nl.isaac.dotcms.plugin.configuration.dependencies.org.apache.commons.configuration.AbstractConfiguration;
+import nl.isaac.dotcms.plugin.configuration.dependencies.org.apache.commons.configuration.DefaultConfigurationBuilder.ConfigurationDeclaration;
+import nl.isaac.dotcms.plugin.configuration.dependencies.org.apache.commons.configuration.DefaultConfigurationBuilder.ConfigurationProvider;
+import nl.isaac.dotcms.plugin.configuration.dependencies.org.apache.commons.configuration.PropertiesConfiguration;
+import nl.isaac.dotcms.plugin.configuration.dependencies.org.apache.commons.configuration.tree.ConfigurationNode;
+
+
+
+/**
+ * A specialized provider implementation that deals with inline property
+ * configurations.
+ */
+public class InlinePropertiesConfigurationProvider extends ConfigurationProvider {
+
+ /**
+ * Creates a new instance of InlineConfigurationProvider
.
+ */
+ public InlinePropertiesConfigurationProvider() {
+ super(PropertiesConfiguration.class);
+ }
+
+ /**
+ * Creates the configuration. After that load()
will be
+ * called. If this configuration is marked as optional, exceptions will
+ * be ignored.
+ *
+ * @param decl the declaration
+ * @return the new configuration
+ * @throws Exception if an error occurs
+ */
+ public AbstractConfiguration getConfiguration(ConfigurationDeclaration decl) throws Exception {
+
+ PropertiesConfiguration config = new PropertiesConfiguration();
+
+ for (Object o : decl.getNode().getChildren()) {
+
+ ConfigurationNode node = (ConfigurationNode) o;
+
+ if (node.getName().equals("property")) {
+
+ List> keys = node.getAttributes("key");
+
+ if (keys.size() != 1) throw new RuntimeException(InlinePropertiesConfigurationProvider.class.getSimpleName() + ": missing 'key' attribute");
+ String key = (String) ((ConfigurationNode) keys.get(0)).getValue();
+ Object value = node.getValue();
+
+ if (value != null) {
+ config.addProperty(key, value);
+ }
+ }
+ }
+
+ return config;
+ }
+
+}
+
diff --git a/Configuration/src/nl/isaac/comp/configuration/interpolator/EnvironmentLookup.java b/Configuration/src/nl/isaac/comp/configuration/interpolator/EnvironmentLookup.java
new file mode 100644
index 0000000..593bab2
--- /dev/null
+++ b/Configuration/src/nl/isaac/comp/configuration/interpolator/EnvironmentLookup.java
@@ -0,0 +1,17 @@
+package nl.isaac.comp.configuration.interpolator;
+
+import nl.isaac.dotcms.plugin.configuration.dependencies.org.apache.commons.lang.text.StrLookup;
+
+/**
+ * Lookup implementation for environment settings using the "env:" prefix
+ * @author jan-willem
+ *
+ */
+public class EnvironmentLookup extends StrLookup {
+
+ @Override
+ public String lookup(String key) {
+ return System.getenv(key);
+ }
+
+}
diff --git a/Configuration/src/nl/isaac/comp/configuration/types/EnvironmentType.java b/Configuration/src/nl/isaac/comp/configuration/types/EnvironmentType.java
new file mode 100644
index 0000000..7f92169
--- /dev/null
+++ b/Configuration/src/nl/isaac/comp/configuration/types/EnvironmentType.java
@@ -0,0 +1,43 @@
+package nl.isaac.comp.configuration.types;
+
+/**
+ * This enum specifies the environment the application is running in. It should be used in all applications
+ * @author jan-willem
+ *
+ */
+public enum EnvironmentType {
+
+ /**
+ * Local development workstation (e.g. Eclipse)
+ */
+ LOCAL(true),
+
+ /**
+ * Development environment (non development machine)
+ */
+ DEV(true),
+
+ /**
+ * UAT environment
+ */
+ UAT(true),
+
+ /**
+ * Production environment
+ */
+ PROD(false);
+
+ private final boolean isTestEnvironment;
+
+ private EnvironmentType(boolean isTestEnvironment) {
+ this.isTestEnvironment = isTestEnvironment;
+ }
+
+ /**
+ * Returns true if this is not a production environment
+ * @return
+ */
+ public boolean isTestEnvironment() {
+ return isTestEnvironment;
+ }
+}
diff --git a/Configuration/src/nl/isaac/comp/configuration/visitor/ToStringMultiLineVisitor.java b/Configuration/src/nl/isaac/comp/configuration/visitor/ToStringMultiLineVisitor.java
new file mode 100644
index 0000000..050734d
--- /dev/null
+++ b/Configuration/src/nl/isaac/comp/configuration/visitor/ToStringMultiLineVisitor.java
@@ -0,0 +1,55 @@
+package nl.isaac.comp.configuration.visitor;
+
+import java.util.Stack;
+
+import nl.isaac.dotcms.plugin.configuration.dependencies.org.apache.commons.configuration.tree.ConfigurationNode;
+import nl.isaac.dotcms.plugin.configuration.dependencies.org.apache.commons.configuration.tree.ConfigurationNodeVisitor;
+
+
+
+public class ToStringMultiLineVisitor implements ConfigurationNodeVisitor {
+
+ private Stack