This is an automated email from the ASF dual-hosted git repository.

jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git


The following commit(s) were added to refs/heads/master by this push:
     new d75a5d3  Clean up builders.
d75a5d3 is described below

commit d75a5d34d25d79af92ad11ca951c0918dc10c0d0
Author: JamesBognar <[email protected]>
AuthorDate: Sat Aug 7 17:42:18 2021 -0400

    Clean up builders.
---
 .../juneau/config/store/ConfigClasspathStore.java  |  13 +-
 .../config/store/ConfigClasspathStoreBuilder.java  |   2 +-
 .../juneau/config/store/ConfigFileStore.java       | 197 +++------------------
 .../config/store/ConfigFileStoreBuilder.java       | 173 +++++++++---------
 .../juneau/config/store/ConfigMemoryStore.java     |  13 +-
 .../config/store/ConfigMemoryStoreBuilder.java     |   2 +-
 .../apache/juneau/config/store/ConfigStore.java    |  12 +-
 .../src/main/java/org/apache/juneau/Context.java   |  13 +-
 .../java/org/apache/juneau/ContextBuilder.java     |  52 ++++++
 .../juneau/config/ConfigMapListenerTest.java       |   4 +-
 .../juneau/config/store/ConfigFileStoreTest.java   |   4 +-
 11 files changed, 189 insertions(+), 296 deletions(-)

diff --git 
a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigClasspathStore.java
 
b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigClasspathStore.java
index e7a7af9..a3c61a9 100644
--- 
a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigClasspathStore.java
+++ 
b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigClasspathStore.java
@@ -17,7 +17,6 @@ import static org.apache.juneau.internal.StringUtils.*;
 import java.io.*;
 import java.util.concurrent.*;
 
-import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.collections.*;
 import org.apache.juneau.internal.*;
@@ -35,12 +34,6 @@ import org.apache.juneau.internal.*;
 public class ConfigClasspathStore extends ConfigStore {
 
        
//-------------------------------------------------------------------------------------------------------------------
-       // Configurable properties
-       
//-------------------------------------------------------------------------------------------------------------------
-
-       static final String PREFIX = "ConfigClasspathStore";
-
-       
//-------------------------------------------------------------------------------------------------------------------
        // Predefined instances
        
//-------------------------------------------------------------------------------------------------------------------
 
@@ -71,10 +64,10 @@ public class ConfigClasspathStore extends ConfigStore {
        /**
         * Constructor.
         *
-        * @param cp The settings for this content store.
+        * @param builder The builder for this object.
         */
-       protected ConfigClasspathStore(ContextProperties cp) {
-               super(cp);
+       protected ConfigClasspathStore(ConfigClasspathStoreBuilder builder) {
+               super(builder);
        }
 
        @Override /* ConfigStore */
diff --git 
a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigClasspathStoreBuilder.java
 
b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigClasspathStoreBuilder.java
index fa47c37..a9d6382 100644
--- 
a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigClasspathStoreBuilder.java
+++ 
b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigClasspathStoreBuilder.java
@@ -44,7 +44,7 @@ public class ConfigClasspathStoreBuilder extends 
ConfigStoreBuilder {
 
        @Override /* ContextBuilder */
        public ConfigClasspathStore build() {
-               return new ConfigClasspathStore(getContextProperties());
+               return new ConfigClasspathStore(this);
        }
 
        
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigFileStore.java
 
b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigFileStore.java
index 84803e4..6f7d626 100644
--- 
a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigFileStore.java
+++ 
b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigFileStore.java
@@ -24,7 +24,6 @@ import java.nio.charset.*;
 import java.nio.file.*;
 import java.util.concurrent.*;
 
-import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.collections.*;
 import org.apache.juneau.internal.*;
@@ -39,165 +38,6 @@ import org.apache.juneau.internal.*;
 public class ConfigFileStore extends ConfigStore {
 
        
//-------------------------------------------------------------------------------------------------------------------
-       // Configurable properties
-       
//-------------------------------------------------------------------------------------------------------------------
-
-       static final String PREFIX = "ConfigFileStore";
-
-       /**
-        * Configuration property:  Local file system directory.
-        *
-        * <h5 class='section'>Property:</h5>
-        * <ul class='spaced-list'>
-        *      <li><b>ID:</b>  {@link 
org.apache.juneau.config.store.ConfigFileStore#FILESTORE_directory 
FILESTORE_directory}
-        *      <li><b>Name:</b>  <js>"ConfigFileStore.directory.s"</js>
-        *      <li><b>Data type:</b>  <c>String</c>
-        *      <li><b>System property:</b>  <c>ConfigFileStore.directory</c>
-        *      <li><b>Environment variable:</b>  
<c>CONFIGFILESTORE_DIRECTORY</c>
-        *      <li><b>Default:</b>  <js>"."</js>
-        *      <li><b>Methods:</b>
-        *              <ul>
-        *                      <li class='jm'>{@link 
org.apache.juneau.config.store.ConfigFileStoreBuilder#directory(String)}
-        *                      <li class='jm'>{@link 
org.apache.juneau.config.store.ConfigFileStoreBuilder#directory(File)}
-        *              </ul>
-        * </ul>
-        *
-        * <h5 class='section'>Description:</h5>
-        * <p>
-        * Identifies the path of the directory containing the configuration 
files.
-        */
-       public static final String FILESTORE_directory = PREFIX + 
".directory.s";
-
-       /**
-        * Configuration property:  Charset.
-        *
-        * <h5 class='section'>Property:</h5>
-        * <ul class='spaced-list'>
-        *      <li><b>ID:</b>  {@link 
org.apache.juneau.config.store.ConfigFileStore#FILESTORE_charset 
FILESTORE_charset}
-        *      <li><b>Name:</b>  <js>"ConfigFileStore.charset.s"</js>
-        *      <li><b>Data type:</b>  {@link java.nio.charset.Charset}
-        *      <li><b>System property:</b>  <c>ConfigFileStore.charset</c>
-        *      <li><b>Environment variable:</b>  <c>CONFIGFILESTORE_CHARSET</c>
-        *      <li><b>Default:</b>  {@link 
java.nio.charset.Charset#defaultCharset()}
-        *      <li><b>Methods:</b>
-        *              <ul>
-        *                      <li class='jm'>{@link 
org.apache.juneau.config.store.ConfigFileStoreBuilder#charset(String)}
-        *                      <li class='jm'>{@link 
org.apache.juneau.config.store.ConfigFileStoreBuilder#charset(Charset)}
-        *              </ul>
-        * </ul>
-        *
-        * <h5 class='section'>Description:</h5>
-        * <p>
-        * Identifies the charset of external files.
-        */
-       public static final String FILESTORE_charset = PREFIX + ".charset.s";
-
-       /**
-        * Configuration property:  Use watcher.
-        *
-        * <h5 class='section'>Property:</h5>
-        * <ul class='spaced-list'>
-        *      <li><b>ID:</b>  {@link 
org.apache.juneau.config.store.ConfigFileStore#FILESTORE_enableWatcher 
FILESTORE_enableWatcher}
-        *      <li><b>Name:</b>  <js>"ConfigFileStore.enableWatcher.b"</js>
-        *      <li><b>Data type:</b>  <jk>boolean</jk>
-        *      <li><b>System property:</b>  
<c>ConfigFileStore.enableWatcher</c>
-        *      <li><b>Environment variable:</b>  
<c>CONFIGFILESTORE_ENABLEWATCHER</c>
-        *      <li><b>Default:</b>  <jk>false</jk>
-        *      <li><b>Methods:</b>
-        *              <ul>
-        *                      <li class='jm'>{@link 
org.apache.juneau.config.store.ConfigFileStoreBuilder#enableWatcher()}
-        *              </ul>
-        * </ul>
-        *
-        * <h5 class='section'>Description:</h5>
-        * <p>
-        * Use a file system watcher for file system changes.
-        *
-        * <ul class='notes'>
-        *      <li>Calling {@link #close()} on this object closes the watcher.
-        * </ul>
-        */
-       public static final String FILESTORE_enableWatcher = PREFIX + 
".enableWatcher.b";
-
-       /**
-        * Configuration property:  Watcher sensitivity.
-        *
-        * <h5 class='section'>Property:</h5>
-        * <ul class='spaced-list'>
-        *      <li><b>ID:</b>  {@link 
org.apache.juneau.config.store.ConfigFileStore#FILESTORE_watcherSensitivity 
FILESTORE_watcherSensitivity}
-        *      <li><b>Name:</b>  
<js>"ConfigFileStore.watcherSensitivity.s"</js>
-        *      <li><b>Data type:</b>  {@link 
org.apache.juneau.config.store.WatcherSensitivity}
-        *      <li><b>System property:</b>  
<c>ConfigFileStore.watcherSensitivity</c>
-        *      <li><b>Environment variable:</b>  
<c>CONFIGFILESTORE_WATCHERSENSITIVITY</c>
-        *      <li><b>Default:</b>  {@link 
org.apache.juneau.config.store.WatcherSensitivity#MEDIUM}
-        *      <li><b>Methods:</b>
-        *              <ul>
-        *                      <li class='jm'>{@link 
org.apache.juneau.config.store.ConfigFileStoreBuilder#watcherSensitivity(WatcherSensitivity)}
-        *                      <li class='jm'>{@link 
org.apache.juneau.config.store.ConfigFileStoreBuilder#watcherSensitivity(String)}
-        *              </ul>
-        * </ul>
-        *
-        * <h5 class='section'>Description:</h5>
-        * <p>
-        * Determines how frequently the file system is polled for updates.
-        *
-        * <ul class='notes'>
-        *      <li>This relies on internal Sun packages and may not work on 
all JVMs.
-        * </ul>
-        */
-       public static final String FILESTORE_watcherSensitivity = PREFIX + 
".watcherSensitivity.s";
-
-       /**
-        * Configuration property:  Update-on-write.
-        *
-        * <h5 class='section'>Property:</h5>
-        * <ul class='spaced-list'>
-        *      <li><b>ID:</b>  {@link 
org.apache.juneau.config.store.ConfigFileStore#FILESTORE_enableUpdateOnWrite 
FILESTORE_enableUpdateOnWrite}
-        *      <li><b>Name:</b>  
<js>"ConfigFileStore.enableUpdateOnWrite.b"</js>
-        *      <li><b>Data type:</b>  <jk>boolean</jk>
-        *      <li><b>System property:</b>  
<c>ConfigFileStore.enableUpdateOnWrite</c>
-        *      <li><b>Environment variable:</b>  
<c>CONFIGFILESTORE_ENABLEUPDATEONWRITE</c>
-        *      <li><b>Default:</b>  <jk>false</jk>
-        *      <li><b>Methods:</b>
-        *              <ul>
-        *                      <li class='jm'>{@link 
org.apache.juneau.config.store.ConfigFileStoreBuilder#enableUpdateOnWrite()}
-        *              </ul>
-        * </ul>
-        *
-        * <h5 class='section'>Description:</h5>
-        * <p>
-        * When enabled, the {@link #update(String, String)} method will be 
called immediately following
-        * calls to {@link #write(String, String, String)} when the contents 
are changing.
-        * <br>This allows for more immediate responses to configuration 
changes on file systems that use
-        * polling watchers.
-        * <br>This may cause double-triggering of {@link ConfigStoreListener 
ConfigStoreListeners}.
-        */
-       public static final String FILESTORE_enableUpdateOnWrite = PREFIX + 
".enableUpdateOnWrite.b";
-
-       /**
-        * Configuration property:  File extensions.
-        *
-        * <h5 class='section'>Property:</h5>
-        * <ul class='spaced-list'>
-        *      <li><b>ID:</b>  {@link 
org.apache.juneau.config.store.ConfigFileStore#FILESTORE_extensions 
FILESTORE_extensions}
-        *      <li><b>Name:</b>  <js>"ConfigFileStore.extensions.s"</js>
-        *      <li><b>Data type:</b>  <c>String</c> (comma-delimited)
-        *      <li><b>System property:</b>  <c>ConfigFileStore.extensions</c>
-        *      <li><b>Environment variable:</b>  
<c>CONFIGFILESTORE_EXTENSIONS</c>
-        *      <li><b>Default:</b>  <js>"cfg"</js>
-        *      <li><b>Methods:</b>
-        *              <ul>
-        *                      <li class='jm'>{@link 
org.apache.juneau.config.store.ConfigFileStoreBuilder#extensions(String)}
-        *              </ul>
-        * </ul>
-        *
-        * <h5 class='section'>Description:</h5>
-        * <p>
-        * Defines what file extensions to search for when the config name does 
not have an extension.
-        */
-       public static final String FILESTORE_extensions = PREFIX + 
".extensions.s";
-
-       
//-------------------------------------------------------------------------------------------------------------------
        // Predefined instances
        
//-------------------------------------------------------------------------------------------------------------------
 
@@ -223,32 +63,37 @@ public class ConfigFileStore extends ConfigStore {
                return new ConfigFileStoreBuilder(this);
        }
 
+       final String directory, extensions;
+       final Charset charset;
+       final boolean enableWatcher, updateOnWrite;
+       final WatcherSensitivity watcherSensitivity;
+
        private final File dir;
-       private final Charset charset;
        private final WatcherThread watcher;
-       private final boolean updateOnWrite;
        private final ConcurrentHashMap<String,String> cache = new 
ConcurrentHashMap<>();
        private final ConcurrentHashMap<String,String> nameCache = new 
ConcurrentHashMap<>();
-       private final String[] extensions;
+       private final String[] exts;
 
        /**
         * Constructor.
         *
-        * @param cp The settings for this content store.
+        * @param builder The builder for this object.
         */
-       protected ConfigFileStore(ContextProperties cp) {
-               super(cp);
+       protected ConfigFileStore(ConfigFileStoreBuilder builder) {
+               super(builder);
+               directory = builder.directory;
+               extensions = builder.extensions;
+               charset = builder.charset;
+               enableWatcher = builder.enableWatcher;
+               updateOnWrite = builder.updateOnWrite;
+               watcherSensitivity = builder.watcherSensitivity;
                try {
-                       dir = new 
File(cp.getString(FILESTORE_directory).orElse(".")).getCanonicalFile();
+                       dir = new File(directory).getCanonicalFile();
                        dir.mkdirs();
-                       charset = cp.get(FILESTORE_charset, 
Charset.class).orElse(Charset.defaultCharset());
-                       updateOnWrite = 
cp.getBoolean(FILESTORE_enableUpdateOnWrite).orElse(false);
-                       extensions = cp.getCdl(FILESTORE_extensions).orElse(new 
String[]{"cfg"});
-                       WatcherSensitivity ws = 
cp.get(FILESTORE_watcherSensitivity, 
WatcherSensitivity.class).orElse(WatcherSensitivity.MEDIUM);
-                       watcher = 
cp.getBoolean(FILESTORE_enableWatcher).orElse(false) ? new WatcherThread(dir, 
ws) : null;
+                       exts = StringUtils.split(extensions);
+                       watcher = enableWatcher ? new WatcherThread(dir, 
watcherSensitivity) : null;
                        if (watcher != null)
                                watcher.start();
-
                } catch (Exception e) {
                        throw runtimeException(e);
                }
@@ -367,7 +212,7 @@ public class ConfigFileStore extends ConfigStore {
 
                        // Does name already have an extension?
                        if (n == null) {
-                               for (String ext : extensions) {
+                               for (String ext : exts) {
                                        if (FileUtils.hasExtension(name, ext)) {
                                                n = name;
                                                break;
@@ -377,7 +222,7 @@ public class ConfigFileStore extends ConfigStore {
 
                        // Find file with the correct extension.
                        if (n == null) {
-                               for (String ext : extensions) {
+                               for (String ext : exts) {
                                        if (FileUtils.exists(dir, name + '.' + 
ext)) {
                                                n = name + '.' + ext;
                                                break;
@@ -387,7 +232,7 @@ public class ConfigFileStore extends ConfigStore {
 
                        // If file not found, use the default which is the name 
with the first extension.
                        if (n == null)
-                               n = extensions.length == 0 ? name : (name + "." 
+ extensions[0]);
+                               n = exts.length == 0 ? name : (name + "." + 
exts[0]);
 
                        nameCache.put(name, n);
                }
diff --git 
a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigFileStoreBuilder.java
 
b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigFileStoreBuilder.java
index 476b47f..23aa4b3 100644
--- 
a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigFileStoreBuilder.java
+++ 
b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigFileStoreBuilder.java
@@ -12,8 +12,6 @@
 // 
***************************************************************************************************************************
 package org.apache.juneau.config.store;
 
-import static org.apache.juneau.config.store.ConfigFileStore.*;
-
 import java.io.*;
 import java.lang.reflect.*;
 import java.nio.charset.*;
@@ -30,11 +28,22 @@ import org.apache.juneau.svl.*;
 @FluentSetters
 public class ConfigFileStoreBuilder extends ConfigStoreBuilder {
 
+       String directory, extensions;
+       Charset charset;
+       boolean enableWatcher, updateOnWrite;
+       WatcherSensitivity watcherSensitivity;
+
        /**
         * Constructor, default settings.
         */
        public ConfigFileStoreBuilder() {
                super();
+               directory = env(String.class, "ConfigFileStore.directory", ".");
+               charset = env(Charset.class, "ConfigFileStore.charset", 
Charset.defaultCharset());
+               enableWatcher = env(Boolean.class, 
"ConfigFileStore.enableWatcher", false);
+               watcherSensitivity = env(WatcherSensitivity.class, 
"ConfigFileStore.watcherSensitivity", WatcherSensitivity.MEDIUM);
+               updateOnWrite = env(Boolean.class, 
"ConfigFileStore.updateOnWrite", false);
+               extensions = env(String.class, "ConfigFileStore.extensions", 
"cfg");
        }
 
        /**
@@ -44,11 +53,18 @@ public class ConfigFileStoreBuilder extends 
ConfigStoreBuilder {
         */
        public ConfigFileStoreBuilder(ConfigFileStore copyFrom) {
                super(copyFrom);
+               directory = copyFrom.directory;
+               charset = copyFrom.charset;
+               enableWatcher = copyFrom.enableWatcher;
+               watcherSensitivity = copyFrom.watcherSensitivity;
+               updateOnWrite = copyFrom.updateOnWrite;
+               extensions = copyFrom.extensions;
+
        }
 
        @Override /* ContextBuilder */
        public ConfigFileStore build() {
-               return new ConfigFileStore(getContextProperties());
+               return new ConfigFileStore(this);
        }
 
        
//-----------------------------------------------------------------------------------------------------------------
@@ -56,172 +72,161 @@ public class ConfigFileStoreBuilder extends 
ConfigStoreBuilder {
        
//-----------------------------------------------------------------------------------------------------------------
 
        /**
-        * Configuration property:  Local file system directory.
+        * Local file system directory.
         *
         * <p>
         * Identifies the path of the directory containing the configuration 
files.
         *
-        * <ul class='seealso'>
-        *      <li class='jf'>{@link ConfigFileStore#FILESTORE_directory}
-        * </ul>
-        *
         * @param value
         *      The new value for this property.
-        *      <br>The default is <js>"."</js>.
+        *      <br>The default is the first value found:
+        *      <ul>
+        *              <li>System property <js>"ConfigFileStore.directory"
+        *              <li>Environment variable <js>"CONFIGFILESTORE_DIRECTORY"
+        *              <li><js>"."</js>
+        *      </ul>
         * @return This object (for method chaining).
         */
        public ConfigFileStoreBuilder directory(String value) {
-               super.set(FILESTORE_directory, value);
+               directory = value;
                return this;
        }
 
        /**
-        * Configuration property:  Local file system directory.
+        * Local file system directory.
         *
         * <p>
         * Identifies the path of the directory containing the configuration 
files.
         *
-        * <ul class='seealso'>
-        *      <li class='jf'>{@link ConfigFileStore#FILESTORE_directory}
-        * </ul>
-        *
         * @param value
         *      The new value for this property.
-        *      <br>The default is <js>"."</js>.
+        *      <br>The default is the first value found:
+        *      <ul>
+        *              <li>System property <js>"ConfigFileStore.directory"
+        *              <li>Environment variable <js>"CONFIGFILESTORE_DIRECTORY"
+        *              <li><js>"."</js>.
+        *      </ul>
         * @return This object (for method chaining).
         */
        public ConfigFileStoreBuilder directory(File value) {
-               super.set(FILESTORE_directory, value);
+               directory = value.getAbsolutePath();
                return this;
        }
 
        /**
-        * Configuration property:  Charset.
+        * Charset for external files.
         *
         * <p>
         * Identifies the charset of external files.
         *
-        * <ul class='seealso'>
-        *      <li class='jf'>{@link ConfigFileStore#FILESTORE_charset}
-        * </ul>
-        *
         * @param value
         *      The new value for this property.
-        *      <br>The default is <js>"."</js>.
-        * @return This object (for method chaining).
-        */
-       public ConfigFileStoreBuilder charset(String value) {
-               super.set(FILESTORE_charset, value);
-               return this;
-       }
-
-       /**
-        * Configuration property:  Charset.
-        *
-        * <p>
-        * Identifies the charset of external files.
-        *
-        * <ul class='seealso'>
-        *      <li class='jf'>{@link ConfigFileStore#FILESTORE_charset}
-        * </ul>
-        *
-        * @param value
-        *      The new value for this property.
-        *      <br>The default is <js>"."</js>.
+        *      <br>The default is the first value found:
+        *      <ul>
+        *              <li>System property <js>"ConfigFileStore.charset"
+        *              <li>Environment variable <js>"CONFIGFILESTORE_CHARSET"
+        *              <li>{@link Charset#defaultCharset()}
+        *      </ul>
         * @return This object (for method chaining).
         */
        public ConfigFileStoreBuilder charset(Charset value) {
-               super.set(FILESTORE_charset, value);
+               charset = value;
                return this;
        }
 
        /**
-        * Configuration property:  Use watcher.
+        * Use watcher.
         *
         * <p>
-        * Shortcut for calling <code>useWatcher(<jk>true</jk>)</code>.
+        * Use a file system watcher for file system changes.
         *
-        * <ul class='seealso'>
-        *      <li class='jf'>{@link ConfigFileStore#FILESTORE_enableWatcher}
+        * <ul class='notes'>
+        *      <li>Calling {@link ConfigFileStore#close()} closes the watcher.
         * </ul>
         *
+        *      <p>
+        *      The default is the first value found:
+        *      <ul>
+        *              <li>System property <js>"ConfigFileStore.enableWatcher"
+        *              <li>Environment variable 
<js>"CONFIGFILESTORE_ENABLEWATCHER"
+        *              <li><jk>false</jk>.
+        *      </ul>
+        *
         * @return This object (for method chaining).
         */
        public ConfigFileStoreBuilder enableWatcher() {
-               super.set(FILESTORE_enableWatcher);
+               enableWatcher = true;
                return this;
        }
 
        /**
-        * Configuration property:  Watcher sensitivity.
+        * Watcher sensitivity.
         *
         * <p>
         * Determines how frequently the file system is polled for updates.
         *
-        * <ul class='seealso'>
-        *      <li class='jf'>{@link 
ConfigFileStore#FILESTORE_watcherSensitivity}
+        * <ul class='notes'>
+        *      <li>This relies on internal Sun packages and may not work on 
all JVMs.
         * </ul>
         *
         * @param value
         *      The new value for this property.
-        *      <br>The default is {@link WatcherSensitivity#MEDIUM}
+        *      <br>The default is the first value found:
+        *      <ul>
+        *              <li>System property 
<js>"ConfigFileStore.watcherSensitivity"
+        *              <li>Environment variable 
<js>"CONFIGFILESTORE_WATCHERSENSITIVITY"
+        *              <li>{@link WatcherSensitivity#MEDIUM}
+        *      </ul>
         * @return This object (for method chaining).
         */
        public ConfigFileStoreBuilder watcherSensitivity(WatcherSensitivity 
value) {
-               super.set(FILESTORE_watcherSensitivity, value);
+               watcherSensitivity = value;
                return this;
        }
 
        /**
-        * Configuration property:  Update-on-write.
+        * Update-on-write.
         *
         * <p>
-        * Shortcut for calling <code>useWatcher(<jk>true</jk>)</code>.
+        * When enabled, the {@link ConfigFileStore#update(String, String)} 
method will be called immediately following
+        * calls to {@link ConfigFileStore#write(String, String, String)} when 
the contents are changing.
+        * <br>This allows for more immediate responses to configuration 
changes on file systems that use
+        * polling watchers.
+        * <br>This may cause double-triggering of {@link ConfigStoreListener 
ConfigStoreListeners}.
         *
-        * <ul class='seealso'>
-        *      <li class='jf'>{@link 
ConfigFileStore#FILESTORE_enableUpdateOnWrite}
-        * </ul>
+        *      <p>
+        *      The default is the first value found:
+        *      <ul>
+        *              <li>System property <js>"ConfigFileStore.updateOnWrite"
+        *              <li>Environment variable 
<js>"CONFIGFILESTORE_UPDATEONWRITE"
+        *              <li><jk>false</jk>.
+        *      </ul>
         *
         * @return This object (for method chaining).
         */
-       public ConfigFileStoreBuilder enableUpdateOnWrite() {
-               super.set(FILESTORE_enableUpdateOnWrite);
-               return this;
-       }
-
-       /**
-        * Configuration property:  Watcher sensitivity.
-        *
-        * <p>
-        * Determines how frequently the file system is polled for updates.
-        *
-        * <ul class='seealso'>
-        *      <li class='jf'>{@link 
ConfigFileStore#FILESTORE_watcherSensitivity}
-        * </ul>
-        *
-        * @param value
-        *      The new value for this property.
-        *      <br>The default is {@link WatcherSensitivity#MEDIUM}
-        * @return This object (for method chaining).
-        */
-       public ConfigFileStoreBuilder watcherSensitivity(String value) {
-               super.set(FILESTORE_watcherSensitivity, value);
+       public ConfigFileStoreBuilder updateOnWrite() {
+               updateOnWrite = true;
                return this;
        }
 
        /**
-        * Configuration property:  File extensions.
+        * File extensions.
         *
         * <p>
         * Defines what file extensions to search for when the config name does 
not have an extension.
         *
         * @param value
         *      The new value for this property.
-        *      <br>The default is <js>"cfg"</js>.
+        *      The default is the first value found:
+        *      <ul>
+        *              <li>System property <js>"ConfigFileStore.extensions"
+        *              <li>Environment variable 
<js>"CONFIGFILESTORE_EXTENSIONS"
+        *              <li><js>"cfg"</js>
+        *      </ul>
         * @return This object (for method chaining).
         */
        public ConfigFileStoreBuilder extensions(String value) {
-               super.set(FILESTORE_extensions, value);
+               extensions = value;
                return this;
        }
 
diff --git 
a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigMemoryStore.java
 
b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigMemoryStore.java
index 0984cdd..3408556 100644
--- 
a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigMemoryStore.java
+++ 
b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigMemoryStore.java
@@ -17,7 +17,6 @@ import static org.apache.juneau.internal.StringUtils.*;
 import java.io.*;
 import java.util.concurrent.*;
 
-import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.collections.*;
 
@@ -31,12 +30,6 @@ import org.apache.juneau.collections.*;
 public class ConfigMemoryStore extends ConfigStore {
 
        
//-------------------------------------------------------------------------------------------------------------------
-       // Configurable properties
-       
//-------------------------------------------------------------------------------------------------------------------
-
-       static final String PREFIX = "ConfigMemoryStore";
-
-       
//-------------------------------------------------------------------------------------------------------------------
        // Predefined instances
        
//-------------------------------------------------------------------------------------------------------------------
 
@@ -67,10 +60,10 @@ public class ConfigMemoryStore extends ConfigStore {
        /**
         * Constructor.
         *
-        * @param cp The settings for this content store.
+        * @param builder The builder for this object.
         */
-       protected ConfigMemoryStore(ContextProperties cp) {
-               super(cp);
+       protected ConfigMemoryStore(ConfigMemoryStoreBuilder builder) {
+               super(builder);
        }
 
        @Override /* ConfigStore */
diff --git 
a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigMemoryStoreBuilder.java
 
b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigMemoryStoreBuilder.java
index 64f50a4..5e93834 100644
--- 
a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigMemoryStoreBuilder.java
+++ 
b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigMemoryStoreBuilder.java
@@ -44,7 +44,7 @@ public class ConfigMemoryStoreBuilder extends 
ConfigStoreBuilder {
 
        @Override /* ContextBuilder */
        public ConfigMemoryStore build() {
-               return new ConfigMemoryStore(getContextProperties());
+               return new ConfigMemoryStore(this);
        }
 
        
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigStore.java
 
b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigStore.java
index af87c2a..8d7f9ff 100644
--- 
a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigStore.java
+++ 
b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigStore.java
@@ -35,12 +35,6 @@ import org.apache.juneau.config.internal.*;
 public abstract class ConfigStore extends Context implements Closeable {
 
        
//-------------------------------------------------------------------------------------------------------------------
-       // Configurable properties
-       
//-------------------------------------------------------------------------------------------------------------------
-
-       static final String PREFIX = "ConfigStore";
-
-       
//-------------------------------------------------------------------------------------------------------------------
        // Instance
        
//-------------------------------------------------------------------------------------------------------------------
 
@@ -50,10 +44,10 @@ public abstract class ConfigStore extends Context 
implements Closeable {
        /**
         * Constructor.
         *
-        * @param cp The settings for this content store.
+        * @param builder The builder for this object.
         */
-       protected ConfigStore(ContextProperties cp) {
-               super(cp, false);
+       protected ConfigStore(ConfigStoreBuilder builder) {
+               super(builder);
        }
 
        /**
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java
index daf0f8d..116b40a 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java
@@ -88,7 +88,7 @@ public abstract class Context {
        final ContextProperties properties;
        private final int identityCode;
 
-       private final boolean debug;
+       final boolean debug;
 
        /**
         * Constructor for this class.
@@ -107,6 +107,17 @@ public abstract class Context {
        }
 
        /**
+        * Constructor for this class.
+        *
+        * @param builder The builder for this class.
+        */
+       protected Context(ContextBuilder builder) {
+               debug = builder.debug;
+               identityCode = System.identityHashCode(this);
+               properties = ContextProperties.DEFAULT;
+       }
+
+       /**
         * Returns the keys found in the specified property group.
         *
         * <p>
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ContextBuilder.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ContextBuilder.java
index 12dac4d..b2b14dd 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ContextBuilder.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ContextBuilder.java
@@ -13,9 +13,13 @@
 package org.apache.juneau;
 
 import static org.apache.juneau.Context.*;
+import static org.apache.juneau.internal.ExceptionUtils.*;
 
 import java.lang.reflect.*;
+import java.nio.charset.*;
 import java.util.*;
+import java.util.concurrent.*;
+import java.util.function.*;
 
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.assertions.*;
@@ -48,12 +52,15 @@ public abstract class ContextBuilder {
        /** Contains all the modifiable settings for the implementation class. 
*/
        private final ContextPropertiesBuilder cpb;
 
+       boolean debug;
+
        /**
         * Constructor.
         * Default settings.
         */
        public ContextBuilder() {
                this.cpb = ContextProperties.create();
+               debug = env(Boolean.class, CONTEXT_debug, false);
        }
 
        /**
@@ -63,6 +70,7 @@ public abstract class ContextBuilder {
         */
        public ContextBuilder(Context copyFrom) {
                this.cpb = copyFrom == null ? ContextProperties.DEFAULT.copy() 
: copyFrom.properties.copy();
+               this.debug = copyFrom == null ? env(Boolean.class, 
CONTEXT_debug, false) : copyFrom.debug;
        }
 
        /**
@@ -862,6 +870,50 @@ public abstract class ContextBuilder {
                return this;
        }
 
+       /**
+        * Looks up a default value from the environment.
+        *
+        * <p>
+        * First looks in system properties.  Then converts the name to 
env-safe and looks in the system environment.
+        * Then returns the default if it can't be found.
+        *
+        * @param c The value type.
+        * @param name The property name.
+        * @param def The default value if not found.
+        * @return The default value.
+        */
+       @SuppressWarnings({ "unchecked", "rawtypes" })
+       protected <T> T env(Class<T> c, String name, T def) {
+               String s = System.getProperty(name);
+               if (s == null)
+                       s = System.getenv(envName(name));
+               if (s == null)
+                       return def;
+               if (c.isEnum())
+                       return (T)Enum.valueOf((Class<? extends Enum>) c, s);
+               Function<String,T> f = (Function<String,T>)ENV_FUNCTIONS.get(c);
+               if (f == null)
+                       throw runtimeException("Invalid env type: {0}", c);
+               return f.apply(s);
+       }
+
+       private static final Map<Class<?>,Function<String,?>> ENV_FUNCTIONS = 
new IdentityHashMap<>();
+       static {
+               ENV_FUNCTIONS.put(String.class, x -> x);
+               ENV_FUNCTIONS.put(Boolean.class, x -> Boolean.valueOf(x));
+               ENV_FUNCTIONS.put(Charset.class, x -> Charset.forName(x));
+       }
+
+       private static final ConcurrentHashMap<String,String> PROPERTY_TO_ENV = 
new ConcurrentHashMap<>();
+       private static String envName(String name) {
+               String name2 = PROPERTY_TO_ENV.get(name);
+               if (name2 == null) {
+                       name2 = name.toUpperCase().replace(".", "_");
+                       PROPERTY_TO_ENV.put(name, name2);
+               }
+               return name2;
+       }
+
        // <FluentSetters>
 
        // </FluentSetters>
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/config/ConfigMapListenerTest.java
 
b/juneau-utest/src/test/java/org/apache/juneau/config/ConfigMapListenerTest.java
index 3d4fbd4..a383404 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/config/ConfigMapListenerTest.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/config/ConfigMapListenerTest.java
@@ -478,7 +478,7 @@ public class ConfigMapListenerTest {
                contents.add("[S1]\nk1 = v1c");
                contents.add("[S1]\nk1 = v1c");
 
-               ConfigMemoryStore s = new ConfigMemoryStore(null) {
+               ConfigMemoryStore s = new 
ConfigMemoryStore(ConfigMemoryStore.create()) {
                        @Override
                        public synchronized String read(String name) {
                                return contents.poll();
@@ -515,7 +515,7 @@ public class ConfigMapListenerTest {
        @Test
        public void testMergeWithConstantlyUpdatingFile() throws Exception {
 
-               ConfigMemoryStore s = new ConfigMemoryStore(null) {
+               ConfigMemoryStore s = new 
ConfigMemoryStore(ConfigMemoryStore.create()) {
                        char c = 'a';
                        @Override
                        public synchronized String read(String name) {
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/config/store/ConfigFileStoreTest.java
 
b/juneau-utest/src/test/java/org/apache/juneau/config/store/ConfigFileStoreTest.java
index f5ad150..11b5489 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/config/store/ConfigFileStoreTest.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/config/store/ConfigFileStoreTest.java
@@ -125,7 +125,7 @@ public class ConfigFileStoreTest {
 
        @Test
        public void testCharset() throws Exception {
-               ConfigFileStore fs = 
ConfigFileStore.create().directory(DIR).charset("UTF-8").build();
+               ConfigFileStore fs = 
ConfigFileStore.create().directory(DIR).charset(IOUtils.UTF8).build();
                assertNull(fs.write("X.cfg", null, "foo"));
                assertEquals("foo", fs.read("X.cfg"));
                assertEquals("foo", fs.read("X"));
@@ -133,7 +133,7 @@ public class ConfigFileStoreTest {
 
        @Test
        public void testCharsetNoExtension() throws Exception {
-               ConfigFileStore fs = 
ConfigFileStore.create().directory(DIR).charset("UTF-8").build();
+               ConfigFileStore fs = 
ConfigFileStore.create().directory(DIR).charset(IOUtils.UTF8).build();
                assertNull(fs.write("X", null, "foo"));
                assertEquals("foo", fs.read("X"));
                assertEquals("foo", fs.read("X.cfg"));

Reply via email to