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 2da2017  Config API changes.
2da2017 is described below

commit 2da2017e37944d6a574aa6d73f6c6e164482cdf2
Author: JamesBognar <[email protected]>
AuthorDate: Sun Feb 25 20:10:32 2018 -0500

    Config API changes.
---
 .../main/java/org/apache/juneau/config/Config.java |  27 +-
 .../apache/juneau/config/event/ConfigEvent.java    |   2 +-
 .../org/apache/juneau/config/store/ConfigMap.java  |  30 +-
 .../apache/juneau/config/ConfigBuilderTest.java    |   4 +-
 .../juneau/config/ConfigMapListenerTest.java       |  24 +-
 .../org/apache/juneau/config/ConfigMapTest.java    |  78 +-
 .../java/org/apache/juneau/config/ConfigTest.java  |  74 +-
 juneau-doc/src/main/javadoc/overview.html          | 953 +++++++++------------
 8 files changed, 506 insertions(+), 686 deletions(-)

diff --git 
a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/Config.java 
b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/Config.java
index 9d99aa1..3630319 100644
--- 
a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/Config.java
+++ 
b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/Config.java
@@ -275,7 +275,6 @@ public final class Config extends Context implements 
ConfigEventListener, Writab
        private final boolean beansOnSeparateLines, readOnly;
        private final ConfigMap configMap;
        private final BeanSession beanSession;
-       private volatile boolean closed;
        private final List<ConfigEventListener> listeners = 
Collections.synchronizedList(new LinkedList<ConfigEventListener>());
 
 
@@ -1015,7 +1014,7 @@ public final class Config extends Context implements 
ConfigEventListener, Writab
         * 
         * @param section 
         *      The section name to write from.
-        *      <br>If empty or <js>"default"</js>, refers to the default 
section.
+        *      <br>If empty, refers to the default section.
         *      <br>Must not be <jk>null</jk>.
         * @return
         *      An unmodifiable set of keys, or an empty set if the section 
doesn't exist.
@@ -1029,7 +1028,7 @@ public final class Config extends Context implements 
ConfigEventListener, Writab
         * 
         * @param section 
         *      The section name to write from.
-        *      <br>If empty or <js>"default"</js>, refers to the default 
section.
+        *      <br>If empty, refers to the default section.
         *      <br>Must not be <jk>null</jk>.
         * @param bean The bean to set the properties on.
         * @param ignoreUnknownProperties
@@ -1070,7 +1069,7 @@ public final class Config extends Context implements 
ConfigEventListener, Writab
         * 
         * @param section 
         *      The section name to write from.
-        *      <br>If empty or <js>"default"</js>, refers to the default 
section.
+        *      <br>If empty, refers to the default section.
         *      <br>Must not be <jk>null</jk>.
         * @param c The bean class to create.
         * @return A new bean instance.
@@ -1113,7 +1112,7 @@ public final class Config extends Context implements 
ConfigEventListener, Writab
         * 
         * @param section 
         *      The section name to write from.
-        *      <br>If empty or <js>"default"</js>, refers to the default 
section.
+        *      <br>If empty, refers to the default section.
         *      <br>Must not be <jk>null</jk>.
         * @param c The bean class to create.
         * @param ignoreUnknownProperties
@@ -1150,7 +1149,7 @@ public final class Config extends Context implements 
ConfigEventListener, Writab
         * 
         * @param section 
         *      The section name to write from.
-        *      <br>If empty or <js>"default"</js>, refers to the default 
section.
+        *      <br>If empty, refers to the default section.
         *      <br>Must not be <jk>null</jk>.
         * @return A new {@link ObjectMap}, or <jk>null</jk> if the section 
doesn't exist.
         * @throws ParseException 
@@ -1229,7 +1228,7 @@ public final class Config extends Context implements 
ConfigEventListener, Writab
         * 
         * @param section 
         *      The section name to write from.
-        *      <br>If empty or <js>"default"</js>, refers to the default 
section.
+        *      <br>If empty, refers to the default section.
         *      <br>Must not be <jk>null</jk>.
         * @param c The proxy interface class.
         * @return The proxy interface.
@@ -1280,7 +1279,7 @@ public final class Config extends Context implements 
ConfigEventListener, Writab
         * @param name 
         *      The section name.
         *      <br>Must not be <jk>null</jk>.
-        *      <br>Use blank or <js>"default"</js> for the default section.
+        *      <br>Use blank for the default section.
         * @param preLines 
         *      Optional comment and blank lines to add immediately before the 
section.
         *      <br>If <jk>null</jk>, previous pre-lines will not be replaced.
@@ -1301,7 +1300,7 @@ public final class Config extends Context implements 
ConfigEventListener, Writab
         * @param name 
         *      The section name.
         *      <br>Must not be <jk>null</jk>.
-        *      <br>Use <js>"default"</js> for the default section.
+        *      <br>Use blank for the default section.
         * @param preLines 
         *      Optional comment and blank lines to add immediately before the 
section.
         *      <br>If <jk>null</jk>, previous pre-lines will not be replaced.
@@ -1411,7 +1410,6 @@ public final class Config extends Context implements 
ConfigEventListener, Writab
         */
        public void close() throws IOException {
                configMap.unregister(this);
-               closed = true;
        }
        
        /**
@@ -1604,7 +1602,7 @@ public final class Config extends Context implements 
ConfigEventListener, Writab
                assertFieldNotNull(key, "key");
                int i = key.indexOf('/');
                if (i == -1)
-                       return "default";
+                       return "";
                return key.substring(0, i);
        }
 
@@ -1618,7 +1616,7 @@ public final class Config extends Context implements 
ConfigEventListener, Writab
        private String section(String section) {
                assertFieldNotNull(section, "section");
                if (isEmpty(section))
-                       return "default";
+                       return "";
                return section;
        }
        
@@ -1639,9 +1637,6 @@ public final class Config extends Context implements 
ConfigEventListener, Writab
        
        @Override /* Object */
        protected void finalize() throws Throwable {
-               // If Config objects are not closed, listeners on the 
underlying ConfigMap don't get cleaned up.
-               if (! closed) {
-                       System.err.println("Config object not closed.");
-               }
+               close();
        }
 }
diff --git 
a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/event/ConfigEvent.java
 
b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/event/ConfigEvent.java
index 70fd1ce..1870dfa 100644
--- 
a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/event/ConfigEvent.java
+++ 
b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/event/ConfigEvent.java
@@ -189,7 +189,7 @@ public class ConfigEvent {
                        case REMOVE_SECTION:
                                return "REMOVE_SECTION("+section+")";
                        case REMOVE_ENTRY:
-                               return "REMOVE_ENTRY("+section+"/"+key+")";
+                               return 
"REMOVE_ENTRY("+section+(section.isEmpty() ? "" : "/")+key+")";
                        case SET_SECTION:
                                return "SET_SECTION("+section+", 
preLines="+StringUtils.join(preLines, '|')+")";
                        case SET_ENTRY:
diff --git 
a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigMap.java
 
b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigMap.java
index efa837d..89f0747 100644
--- 
a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigMap.java
+++ 
b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigMap.java
@@ -93,7 +93,7 @@ public class ConfigMap implements ConfigStoreListener {
                        }
                }
                
-               // Add [default] section.
+               // Add [blank] section.
                boolean inserted = false;
                boolean foundComment = false;
                for (ListIterator<String> li = lines.listIterator(); 
li.hasNext();) {
@@ -101,7 +101,7 @@ public class ConfigMap implements ConfigStoreListener {
                        char c = StringUtils.firstNonWhitespaceChar(l);
                        if (c != '#') {
                                if (c == 0 && foundComment) {
-                                       li.set("[default]");
+                                       li.set("[]");
                                        inserted = true;
                                }
                                break;
@@ -109,7 +109,7 @@ public class ConfigMap implements ConfigStoreListener {
                        foundComment = true;
                }
                if (! inserted)
-                       lines.add(0, "[default]");
+                       lines.add(0, "[]");
                
                // Collapse any multi-lines.
                ListIterator<String> li = lines.listIterator(lines.size());
@@ -181,7 +181,7 @@ public class ConfigMap implements ConfigStoreListener {
         * @param section 
         *      The section name.
         *      <br>Must not be <jk>null</jk>.
-        *      <br>Use <js>"default"</js> to refer to the default section.
+        *      <br>Use blank to refer to the default section.
         * @param key 
         *      The entry key.
         *      <br>Must not be <jk>null</jk>.
@@ -208,7 +208,7 @@ public class ConfigMap implements ConfigStoreListener {
         * @param section 
         *      The section name.
         *      <br>Must not be <jk>null</jk>.
-        *      <br>Use <js>"default"</js> to refer to the default section.
+        *      <br>Use blank to refer to the default section.
         * @return
         *      An unmodifiable list of lines, or <jk>null</jk> if the section 
doesn't exist.
         */
@@ -239,7 +239,7 @@ public class ConfigMap implements ConfigStoreListener {
         * @param section 
         *      The section name.
         *      <br>Must not be <jk>null</jk>.
-        *      <br>Use <js>"default"</js> to refer to the default section.
+        *      <br>Use blank to refer to the default section.
         * @return
         *      An unmodifiable set of keys, or an empty set if the section 
doesn't exist.
         */
@@ -255,7 +255,7 @@ public class ConfigMap implements ConfigStoreListener {
         * @param section 
         *      The section name.
         *      <br>Must not be <jk>null</jk>.
-        *      <br>Use <js>"default"</js> to refer to the default section.
+        *      <br>Use blank to refer to the default section.
         * @return <jk>true</jk> if this config has the specified section.
         */
        public boolean hasSection(String section) {
@@ -273,7 +273,7 @@ public class ConfigMap implements ConfigStoreListener {
         * @param section 
         *      The section name.
         *      <br>Must not be <jk>null</jk>.
-        *      <br>Use <js>"default"</js> to refer to the default section.
+        *      <br>Use blank to refer to the default section.
         * @param preLines
         *      The pre-lines on the section.
         *      <br>If <jk>null</jk>, the previous value will not be 
overwritten.
@@ -290,7 +290,7 @@ public class ConfigMap implements ConfigStoreListener {
         * @param section 
         *      The section name.
         *      <br>Must not be <jk>null</jk>.
-        *      <br>Use <js>"default"</js> to refer to the default section.
+        *      <br>Use blank to refer to the default section.
         * @param key 
         *      The entry key.
         *      <br>Must not be <jk>null</jk>.
@@ -325,7 +325,7 @@ public class ConfigMap implements ConfigStoreListener {
         * @param section 
         *      The section name.
         *      <br>Must not be <jk>null</jk>.
-        *      <br>Use <js>"default"</js> to refer to the default section.
+        *      <br>Use blank to refer to the default section.
         * @return This object (for method chaining).
         */
        public ConfigMap removeSection(String section) {
@@ -339,7 +339,7 @@ public class ConfigMap implements ConfigStoreListener {
         * @param section 
         *      The section name.
         *      <br>Must not be <jk>null</jk>.
-        *      <br>Use <js>"default"</js> to refer to the default section.
+        *      <br>Use blank to refer to the default section.
         * @param key 
         *      The entry key.
         *      <br>Must not be <jk>null</jk>.
@@ -606,7 +606,7 @@ public class ConfigMap implements ConfigStoreListener {
        }
 
        private void checkSectionName(String s) {
-               if (! ("default".equals(s) || isValidNewSectionName(s)))
+               if (! ("".equals(s) || isValidNewSectionName(s)))
                        throw new IllegalArgumentException("Invalid section 
name: '" + s + "'");
        }
 
@@ -635,8 +635,6 @@ public class ConfigMap implements ConfigStoreListener {
                s = s.trim();
                if (s.isEmpty())
                        return false;
-               if ("default".equals(s))
-                       return false;
                for (int i = 0; i < s.length(); i++) {
                        char c = s.charAt(i);
                        if (c == '/' || c == '\\' || c == '[' || c == ']')
@@ -705,7 +703,7 @@ public class ConfigMap implements ConfigStoreListener {
        
        class ConfigSection {
 
-               final String name;   // The config section name, or "default" 
if the default section.  Never null.
+               final String name;   // The config section name, or blank if 
the default section.  Never null.
 
                final List<String> preLines = Collections.synchronizedList(new 
ArrayList<String>());
                private final String rawLine;
@@ -778,7 +776,7 @@ public class ConfigMap implements ConfigStoreListener {
                        for (String s : preLines)
                                w.append(s).append('\n');
                        
-                       if (! name.equals("default"))
+                       if (! name.equals(""))
                                w.append(rawLine).append('\n');
                        else {
                                // Need separation between default prelines and 
first-entry prelines.
diff --git 
a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/config/ConfigBuilderTest.java
 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/config/ConfigBuilderTest.java
index 9cebe35..1e2aee8 100755
--- 
a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/config/ConfigBuilderTest.java
+++ 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/config/ConfigBuilderTest.java
@@ -51,10 +51,10 @@ public class ConfigBuilderTest {
                assertFalse(f.exists());
 
                cf.save();
-               assertObjectEquals("{'default':{},Test:{A:'a'}}", cf.asMap());
+               assertObjectEquals("{'':{},Test:{A:'a'}}", cf.asMap());
 
                String NL = System.getProperty("line.separator");
                cf = cf.write("[Test]"+NL+"A = b"+NL, true);
-               assertObjectEquals("{'default':{},Test:{A:'b'}}", cf.asMap());
+               assertObjectEquals("{'':{},Test:{A:'b'}}", cf.asMap());
        }
 }
\ No newline at end of file
diff --git 
a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/config/ConfigMapListenerTest.java
 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/config/ConfigMapListenerTest.java
index ee2fbca..52b0e50 100644
--- 
a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/config/ConfigMapListenerTest.java
+++ 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/config/ConfigMapListenerTest.java
@@ -46,7 +46,7 @@ public class ConfigMapListenerTest {
                
                ConfigMap cm = s.getMap("Foo.cfg");
                cm.register(l);
-               cm.setEntry("default", "foo", "baz", null, null, null);
+               cm.setEntry("", "foo", "baz", null, null, null);
                cm.save();
                wait(latch);
                assertNull(l.error);
@@ -102,7 +102,7 @@ public class ConfigMapListenerTest {
 
                ConfigMap cm = s.getMap("Foo.cfg");
                cm.register(l);
-               cm.setEntry("default", "k", "vb", null, null, null);
+               cm.setEntry("", "k", "vb", null, null, null);
                cm.setEntry("S1", "k1", "v1b", null, null, null);
                cm.save();
                wait(latch);
@@ -128,7 +128,7 @@ public class ConfigMapListenerTest {
 
                ConfigMap cm = s.getMap("Foo.cfg");
                cm.register(l);
-               cm.setEntry("default", "k", "kb", "^*", "C", 
Arrays.asList("#k"));
+               cm.setEntry("", "k", "kb", "^*", "C", Arrays.asList("#k"));
                cm.setEntry("S1", "k1", "k1b", "^*", "C1", 
Arrays.asList("#k1"));
                cm.save();
                wait(latch);
@@ -160,7 +160,7 @@ public class ConfigMapListenerTest {
 
                ConfigMap cm = s.getMap("Foo.cfg");
                cm.register(l);
-               cm.setEntry("default", "k", "kb", "^*", "Cb", 
Arrays.asList("#kb"));
+               cm.setEntry("", "k", "kb", "^*", "Cb", Arrays.asList("#kb"));
                cm.setEntry("S1", "k1", "k1b", "^*", "Cb1", 
Arrays.asList("#k1b"));
                cm.save();
                wait(latch);
@@ -187,13 +187,13 @@ public class ConfigMapListenerTest {
                LatchedListener l = new LatchedListener(latch) {
                        @Override
                        public void check(List<ConfigEvent> events) throws 
Exception {
-                               
assertObjectEquals("['REMOVE_ENTRY(default/k)','REMOVE_ENTRY(S1/k1)']", events);
+                               
assertObjectEquals("['REMOVE_ENTRY(k)','REMOVE_ENTRY(S1/k1)']", events);
                        }
                };
 
                ConfigMap cm = s.getMap("Foo.cfg");
                cm.register(l);
-               cm.removeEntry("default", "k");
+               cm.removeEntry("", "k");
                cm.removeEntry("S1", "k1");
                cm.save();
                wait(latch);
@@ -219,13 +219,13 @@ public class ConfigMapListenerTest {
                LatchedListener l = new LatchedListener(latch) {
                        @Override
                        public void check(List<ConfigEvent> events) throws 
Exception {
-                               
assertObjectEquals("['REMOVE_ENTRY(default/k)','REMOVE_ENTRY(S1/k1)']", events);
+                               
assertObjectEquals("['REMOVE_ENTRY(k)','REMOVE_ENTRY(S1/k1)']", events);
                        }
                };
 
                ConfigMap cm = s.getMap("Foo.cfg");
                cm.register(l);
-               cm.removeEntry("default", "k");
+               cm.removeEntry("", "k");
                cm.removeEntry("S1", "k1");
                cm.save();
                wait(latch);
@@ -255,7 +255,7 @@ public class ConfigMapListenerTest {
 
                ConfigMap cm = s.getMap("Foo.cfg");
                cm.register(l);
-               cm.setSection("default", Arrays.asList("#D1"));
+               cm.setSection("", Arrays.asList("#D1"));
                cm.setSection("S1", Arrays.asList("#S1"));
                cm.setSection("S2", null);
                cm.setSection("S3", Collections.<String>emptyList());
@@ -290,7 +290,7 @@ public class ConfigMapListenerTest {
 
                ConfigMap cm = s.getMap("Foo.cfg");
                cm.register(l);
-               cm.setSection("default", Arrays.asList("#Db"));
+               cm.setSection("", Arrays.asList("#Db"));
                cm.setSection("S1", Arrays.asList("#S1b"));
                cm.setSection("S2", null);
                cm.setSection("S3", Collections.<String>emptyList());
@@ -329,13 +329,13 @@ public class ConfigMapListenerTest {
                LatchedListener l = new LatchedListener(latch) {
                        @Override
                        public void check(List<ConfigEvent> events) throws 
Exception {
-                               
assertObjectEquals("['REMOVE_ENTRY(default/k)','REMOVE_ENTRY(S1/k1)','REMOVE_ENTRY(S2/k2)']",
 events);
+                               
assertObjectEquals("['REMOVE_ENTRY(k)','REMOVE_ENTRY(S1/k1)','REMOVE_ENTRY(S2/k2)']",
 events);
                        }
                };
 
                ConfigMap cm = s.getMap("Foo.cfg");
                cm.register(l);
-               cm.removeSection("default");
+               cm.removeSection("");
                cm.removeSection("S1");
                cm.removeSection("S2");
                cm.removeSection("S3");
diff --git 
a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/config/ConfigMapTest.java
 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/config/ConfigMapTest.java
index fb6c865..b70bf84 100644
--- 
a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/config/ConfigMapTest.java
+++ 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/config/ConfigMapTest.java
@@ -64,10 +64,10 @@ public class ConfigMapTest {
                
                assertTextEquals("foo=bar|", cm);
                
-               assertEquals("", join(cm.getPreLines("default"), '|'));
-               assertEquals("", join(cm.getEntry("default", 
"foo").getPreLines(), '|'));
+               assertEquals("", join(cm.getPreLines(""), '|'));
+               assertEquals("", join(cm.getEntry("", "foo").getPreLines(), 
'|'));
                
-               assertEquals("bar", cm.getEntry("default", "foo").getValue());
+               assertEquals("bar", cm.getEntry("", "foo").getValue());
                
                // Round trip.
                s.update("Foo.cfg", cm.toString());
@@ -88,10 +88,10 @@ public class ConfigMapTest {
                
                assertTextEquals("#comment|foo=bar|", cm);
 
-               assertEquals("", join(cm.getPreLines("default"), '|'));
-               assertEquals("#comment", join(cm.getEntry("default", 
"foo").getPreLines(), '|'));
+               assertEquals("", join(cm.getPreLines(""), '|'));
+               assertEquals("#comment", join(cm.getEntry("", 
"foo").getPreLines(), '|'));
 
-               assertEquals("bar", cm.getEntry("default", "foo").getValue());
+               assertEquals("bar", cm.getEntry("", "foo").getValue());
                
                // Round trip.
                s.update("Foo.cfg", cm.toString());
@@ -112,7 +112,7 @@ public class ConfigMapTest {
                
                assertTextEquals("[MySection]|foo=bar|", cm);
                
-               assertEquals("", join(cm.getPreLines("default"), '|'));
+               assertEquals("", join(cm.getPreLines(""), '|'));
                assertEquals("", join(cm.getPreLines("MySection"), '|'));
                assertEquals("", join(cm.getEntry("MySection", 
"foo").getPreLines(), '|'));
                
@@ -137,7 +137,7 @@ public class ConfigMapTest {
                
                assertTextEquals("[MySection]|foo=bar|", cm);
                
-               assertEquals("", join(cm.getPreLines("default"), '|'));
+               assertEquals("", join(cm.getPreLines(""), '|'));
                
                assertNull(cm.getPreLines("XXX"));
 
@@ -163,7 +163,7 @@ public class ConfigMapTest {
                ConfigMap cm = s.getMap("Foo.cfg");
                assertTextEquals("#S1|[S1]|#k1|k1=v1|#S2|[S2]|#k2|k2=v2|", cm);
                
-               assertEquals("", join(cm.getPreLines("default"), '|'));
+               assertEquals("", join(cm.getPreLines(""), '|'));
                assertEquals("#S1", join(cm.getPreLines("S1"), '|'));
                assertEquals("#k1", join(cm.getEntry("S1", "k1").getPreLines(), 
'|'));
                assertEquals("#S2", join(cm.getPreLines("S2"), '|'));
@@ -196,12 +196,12 @@ public class ConfigMapTest {
                ConfigMap cm = s.getMap("Foo.cfg");
                assertTextEquals("#D||#k|k=v|#S1|[S1]|#k1|k1=v1|", cm);
 
-               assertEquals("#D", join(cm.getPreLines("default"), '|'));
-               assertEquals("#k", join(cm.getEntry("default", 
"k").getPreLines(), '|'));
+               assertEquals("#D", join(cm.getPreLines(""), '|'));
+               assertEquals("#k", join(cm.getEntry("", "k").getPreLines(), 
'|'));
                assertEquals("#S1", join(cm.getPreLines("S1"), '|'));
                assertEquals("#k1", join(cm.getEntry("S1", "k1").getPreLines(), 
'|'));
                
-               assertEquals("v", cm.getEntry("default", "k").getValue());
+               assertEquals("v", cm.getEntry("", "k").getValue());
                assertEquals("v1", cm.getEntry("S1", "k1").getValue());
                
                // Round trip.
@@ -240,12 +240,12 @@ public class ConfigMapTest {
                ConfigMap cm = s.getMap("Foo.cfg");
                
assertTextEquals("#Da|#Db||#ka||#kb||k=v||#S1a||#S1b||[S1]||#k1a||#k1b||k1=v1|",
 cm);
 
-               assertEquals("#Da|#Db", join(cm.getPreLines("default"), '|'));
-               assertEquals("#ka||#kb|", join(cm.getEntry("default", 
"k").getPreLines(), '|'));
+               assertEquals("#Da|#Db", join(cm.getPreLines(""), '|'));
+               assertEquals("#ka||#kb|", join(cm.getEntry("", 
"k").getPreLines(), '|'));
                assertEquals("|#S1a||#S1b|", join(cm.getPreLines("S1"), '|'));
                assertEquals("|#k1a||#k1b|", join(cm.getEntry("S1", 
"k1").getPreLines(), '|'));
                
-               assertEquals("v", cm.getEntry("default", "k").getValue());
+               assertEquals("v", cm.getEntry("", "k").getValue());
                assertEquals("v1", cm.getEntry("S1", "k1").getValue());
                
                // Round trip.
@@ -261,7 +261,7 @@ public class ConfigMapTest {
        public void testMalformedSectionHeaders() throws Exception {
                
                String[] test = {
-                       "[default]", "[ default ]", " [ default ] ", 
"\t[\tdefault\t]\t",
+                       "[]", "[  ]", " [  ] ", "\t[\t\t]\t",
                        "[/]", "[[]", "[]]", "[\\]", 
                        "[foo/bar]", "[foo[bar]", "[foo]bar]", "[foo\\bar]", 
                        "[]", "[ ]", "[\t]", " [] ",
@@ -315,13 +315,13 @@ public class ConfigMapTest {
                );              
                ConfigMap cm = s.getMap("Foo.cfg");
                
-               assertEquals("", join(cm.getEntry("default", 
"k1").getPreLines(), '|'));
-               assertEquals("", join(cm.getEntry("default", 
"k2").getPreLines(), '|'));
+               assertEquals("", join(cm.getEntry("", "k1").getPreLines(), 
'|'));
+               assertEquals("", join(cm.getEntry("", "k2").getPreLines(), 
'|'));
 
                assertTextEquals("k1 = v1a,|\tv1b,|\tv1c|k2 = 
v2a,|\tv2b,|\tv2c|", cm);
 
-               assertEquals("v1a,\nv1b,\nv1c", cm.getEntry("default", 
"k1").getValue());
-               assertEquals("v2a,\nv2b,\nv2c", cm.getEntry("default", 
"k2").getValue());
+               assertEquals("v1a,\nv1b,\nv1c", cm.getEntry("", 
"k1").getValue());
+               assertEquals("v2a,\nv2b,\nv2c", cm.getEntry("", 
"k2").getValue());
                
                // Round trip.
                s.update("Foo.cfg", cm.toString());
@@ -347,13 +347,13 @@ public class ConfigMapTest {
                );              
                ConfigMap cm = s.getMap("Foo.cfg");
                
-               assertEquals("|#k1|", join(cm.getEntry("default", 
"k1").getPreLines(), '|'));
-               assertEquals("|#k2|", join(cm.getEntry("default", 
"k2").getPreLines(), '|'));
+               assertEquals("|#k1|", join(cm.getEntry("", "k1").getPreLines(), 
'|'));
+               assertEquals("|#k2|", join(cm.getEntry("", "k2").getPreLines(), 
'|'));
 
                assertTextEquals("|#k1||k1 = v1a,|      v1b,|   v1c||#k2||k2 = 
v2a,|    v2b,|   v2c|", cm);
 
-               assertEquals("v1a,\nv1b,\nv1c", cm.getEntry("default", 
"k1").getValue());
-               assertEquals("v2a,\nv2b,\nv2c", cm.getEntry("default", 
"k2").getValue());
+               assertEquals("v1a,\nv1b,\nv1c", cm.getEntry("", 
"k1").getValue());
+               assertEquals("v2a,\nv2b,\nv2c", cm.getEntry("", 
"k2").getValue());
                
                // Round trip.
                s.update("Foo.cfg", cm.toString());
@@ -549,12 +549,12 @@ public class ConfigMapTest {
                ConfigStore s = initStore("Foo.cfg");           
                ConfigMap cm = s.getMap("Foo.cfg");
                
-               cm.setEntry("default", "k", "v1\nv2\nv3", null, null, null);
+               cm.setEntry("", "k", "v1\nv2\nv3", null, null, null);
                cm.setEntry("S1", "k1", "v1\nv2\nv3", null, null, null);
                
                assertTextEquals("k = v1|       v2|     v3|[S1]|k1 = v1|        
v2|     v3|", cm);
                
-               assertEquals("v1\nv2\nv3", cm.getEntry("default", 
"k").getValue());
+               assertEquals("v1\nv2\nv3", cm.getEntry("", "k").getValue());
                assertEquals("v1\nv2\nv3", cm.getEntry("S1", "k1").getValue());
                cm.save();
                assertTextEquals("k = v1|       v2|     v3|[S1]|k1 = v1|        
v2|     v3|", cm);
@@ -569,12 +569,12 @@ public class ConfigMapTest {
                ConfigStore s = initStore("Foo.cfg");           
                ConfigMap cm = s.getMap("Foo.cfg");
                
-               cm.setEntry("default", "k", "v1 \n v2 \n v3", null, null, null);
+               cm.setEntry("", "k", "v1 \n v2 \n v3", null, null, null);
                cm.setEntry("S1", "k1", "v1\t\n\tv2\t\n\tv3", null, null, null);
                
                assertTextEquals("k = v1 |       v2 |    v3|[S1]|k1 = v1        
|               v2      |               v3|", cm);
                
-               assertEquals("v1 \n v2 \n v3", cm.getEntry("default", 
"k").getValue());
+               assertEquals("v1 \n v2 \n v3", cm.getEntry("", "k").getValue());
                assertEquals("v1\t\n\tv2\t\n\tv3", cm.getEntry("S1", 
"k1").getValue());
                cm.save();
                assertTextEquals("k = v1 |       v2 |    v3|[S1]|k1 = v1        
|               v2      |               v3|", cm);
@@ -611,11 +611,11 @@ public class ConfigMapTest {
                );              
                ConfigMap cm = s.getMap("Foo.cfg");
                
-               cm.setSection("default", Arrays.asList("#D"));
+               cm.setSection("", Arrays.asList("#D"));
                assertTextEquals("#D||[S1]|k1 = v1|", cm);
-               cm.setSection("default", Collections.<String>emptyList());
+               cm.setSection("", Collections.<String>emptyList());
                assertTextEquals("[S1]|k1 = v1|", cm);
-               cm.setSection("default", null);
+               cm.setSection("", null);
                assertTextEquals("[S1]|k1 = v1|", cm);
        }
 
@@ -643,7 +643,7 @@ public class ConfigMapTest {
                String[] test = {
                        "/", "[", "]",
                        "foo/bar", "foo[bar", "foo]bar", 
-                       "", " ",
+                       " ",
                        null
                };
                
@@ -711,12 +711,6 @@ public class ConfigMapTest {
                assertTextEquals("[S1]|k1 = v1|[S2]|k2 = v2|", cm);
                
                try {
-                       cm.removeSection("");
-                       fail();
-               } catch (IllegalArgumentException e) {
-                       assertEquals("Invalid section name: ''", 
e.getLocalizedMessage());
-               }
-               try {
                        cm.removeSection(null);
                        fail();
                } catch (IllegalArgumentException e) {
@@ -736,7 +730,7 @@ public class ConfigMapTest {
                );              
                ConfigMap cm = s.getMap("Foo.cfg");
                
-               cm.removeSection("default");
+               cm.removeSection("");
                assertTextEquals("[S1]|k1 = v1|[S2]|k2 = v2|", cm);
        }
        
@@ -755,7 +749,7 @@ public class ConfigMapTest {
                );              
                ConfigMap cm = s.getMap("Foo.cfg");
                
-               cm.removeSection("default");
+               cm.removeSection("");
                assertTextEquals("[S1]|k1 = v1|[S2]|k2 = v2|", cm);
        }
        
@@ -890,7 +884,7 @@ public class ConfigMapTest {
                String[] test = {
                        "/", "[", "]",
                        "foo/bar", "foo[bar", "foo]bar", 
-                       "", " ",
+                       " ",
                        null
                };
                
@@ -1086,7 +1080,7 @@ public class ConfigMapTest {
                String[] test = {
                        "/", "[", "]",
                        "foo/bar", "foo[bar", "foo]bar", 
-                       "", " ",
+                       " ",
                        null
                };
                
diff --git 
a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/config/ConfigTest.java
 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/config/ConfigTest.java
index 0bd1bfe..9795ace 100755
--- 
a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/config/ConfigTest.java
+++ 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/config/ConfigTest.java
@@ -49,7 +49,7 @@ public class ConfigTest {
                Config c = init("a=1", "[S]", "b=2");
                
                assertEquals("1", c.get("a"));
-               assertEquals("1", c.get("default/a"));
+               assertEquals("1", c.get("a"));
                assertEquals("2", c.get("S/b"));
                assertNull(c.get("b"));
                assertNull(c.get("S/c"));
@@ -73,13 +73,13 @@ public class ConfigTest {
                
                c.set("a1", "2");
                c.set("a2", "3");
-               c.set("default/a3", "4");
+               c.set("a3", "4");
                c.set("S/b1", "5");
                c.set("S/b2", "6");
                c.set("T/c1", "7");
                
                assertEquals("2", c.get("a1"));
-               assertEquals("3", c.get("default/a2"));
+               assertEquals("3", c.get("a2"));
                assertEquals("4", c.get("a3"));
                assertEquals("5", c.get("S/b1"));
                assertEquals("6", c.get("S/b2"));
@@ -88,7 +88,7 @@ public class ConfigTest {
                c.save();
                
                assertEquals("2", c.get("a1"));
-               assertEquals("3", c.get("default/a2"));
+               assertEquals("3", c.get("a2"));
                assertEquals("4", c.get("a3"));
                assertEquals("5", c.get("S/b1"));
                assertEquals("6", c.get("S/b2"));
@@ -97,7 +97,7 @@ public class ConfigTest {
                c = cb.build();
                
                assertEquals("2", c.get("a1"));
-               assertEquals("3", c.get("default/a2"));
+               assertEquals("3", c.get("a2"));
                assertEquals("4", c.get("a3"));
                assertEquals("5", c.get("S/b1"));
                assertEquals("6", c.get("S/b2"));
@@ -115,13 +115,13 @@ public class ConfigTest {
                
                c.set("a1", 2);
                c.set("a2", 3);
-               c.set("default/a3", 4);
+               c.set("a3", 4);
                c.set("S/b1", 5);
                c.set("S/b2", 6);
                c.set("T/c1", 7);
                
                assertEquals("2", c.get("a1"));
-               assertEquals("3", c.get("default/a2"));
+               assertEquals("3", c.get("a2"));
                assertEquals("4", c.get("a3"));
                assertEquals("5", c.get("S/b1"));
                assertEquals("6", c.get("S/b2"));
@@ -130,7 +130,7 @@ public class ConfigTest {
                c.save();
                
                assertEquals("2", c.get("a1"));
-               assertEquals("3", c.get("default/a2"));
+               assertEquals("3", c.get("a2"));
                assertEquals("4", c.get("a3"));
                assertEquals("5", c.get("S/b1"));
                assertEquals("6", c.get("S/b2"));
@@ -139,7 +139,7 @@ public class ConfigTest {
                c = cb.build();
                
                assertEquals("2", c.get("a1"));
-               assertEquals("3", c.get("default/a2"));
+               assertEquals("3", c.get("a2"));
                assertEquals("4", c.get("a3"));
                assertEquals("5", c.get("S/b1"));
                assertEquals("6", c.get("S/b2"));
@@ -158,13 +158,13 @@ public class ConfigTest {
                ABean b = new ABean().init();
                c.set("a1", b, UonSerializer.DEFAULT);
                c.set("a2", b, UonSerializer.DEFAULT);
-               c.set("default/a3", b, UonSerializer.DEFAULT);
+               c.set("a3", b, UonSerializer.DEFAULT);
                c.set("S/b1", b, UonSerializer.DEFAULT);
                c.set("S/b2", b, UonSerializer.DEFAULT);
                c.set("T/c1", b, UonSerializer.DEFAULT);
                
                assertEquals("(foo=bar)", c.get("a1"));
-               assertEquals("(foo=bar)", c.get("default/a2"));
+               assertEquals("(foo=bar)", c.get("a2"));
                assertEquals("(foo=bar)", c.get("a3"));
                assertEquals("(foo=bar)", c.get("S/b1"));
                assertEquals("(foo=bar)", c.get("S/b2"));
@@ -181,7 +181,7 @@ public class ConfigTest {
                ABean b = new ABean().init();
                c.set("a1", b, UonSerializer.DEFAULT, ENCODED, "comment", 
Arrays.asList("#c1","#c2"));
                c.set("a2", b, UonSerializer.DEFAULT, ENCODED, "comment", 
Arrays.asList("#c1","#c2"));
-               c.set("default/a3", b, UonSerializer.DEFAULT, ENCODED, 
"comment", Arrays.asList("#c1","#c2"));
+               c.set("a3", b, UonSerializer.DEFAULT, ENCODED, "comment", 
Arrays.asList("#c1","#c2"));
                c.set("S/b1", b, UonSerializer.DEFAULT, ENCODED, "comment", 
Arrays.asList("#c1","#c2"));
                c.set("S/b2", b, UonSerializer.DEFAULT, ENCODED, "comment", 
Arrays.asList("#c1","#c2"));
                c.set("T/c1", b, UonSerializer.DEFAULT, ENCODED, "comment", 
Arrays.asList("#c1","#c2"));
@@ -193,7 +193,7 @@ public class ConfigTest {
                assertTextEquals("#c1|#c2|a1* = {RhMWWFIFVksf} # 
comment|#c1|#c2|a2* = {RhMWWFIFVksf} # comment|#c1|#c2|a3* = {RhMWWFIFVksf} # 
comment|[S]|#c1|#c2|b1* = {RhMWWFIFVksf} # comment|#c1|#c2|b2* = {RhMWWFIFVksf} 
# comment|[T]|#c1|#c2|c1* = {RhMWWFIFVksf} # comment|", c.toString());
 
                assertEquals("(foo=bar)", c.get("a1"));
-               assertEquals("(foo=bar)", c.get("default/a2"));
+               assertEquals("(foo=bar)", c.get("a2"));
                assertEquals("(foo=bar)", c.get("a3"));
                assertEquals("(foo=bar)", c.get("S/b1"));
                assertEquals("(foo=bar)", c.get("S/b2"));
@@ -208,8 +208,8 @@ public class ConfigTest {
                Config c = init("a1=1", "a2=2", "[S]", "b1=1");
                
                c.remove("a1");
-               c.remove("default/a2");
-               c.remove("default/a3");
+               c.remove("a2");
+               c.remove("a3");
                c.remove("S/b1");
                c.remove("T/c1");
                
@@ -228,7 +228,7 @@ public class ConfigTest {
                Config c = init("a1=1", "a2=2", "[S]", "b1=1", "b2=");
                
                assertEquals("1", c.getString("a1"));
-               assertEquals("2", c.getString("default/a2"));
+               assertEquals("2", c.getString("a2"));
                assertEquals(null, c.getString("a3"));
                assertEquals("1", c.getString("S/b1"));
                assertEquals("", c.getString("S/b2"));
@@ -244,7 +244,7 @@ public class ConfigTest {
                Config c = init("a1=1", "a2=2", "[S]", "b1=1", "b2=");
                
                assertEquals("1", c.getString("a1", "foo"));
-               assertEquals("2", c.getString("default/a2", "foo"));
+               assertEquals("2", c.getString("a2", "foo"));
                assertEquals("foo", c.getString("a3", "foo"));
                assertEquals("1", c.getString("S/b1", "foo"));
                assertEquals("foo", c.getString("S/b2", "foo"));
@@ -260,7 +260,7 @@ public class ConfigTest {
                Config c = init("a1=1,2", "a2= 2 , 3 ", "[S]", "b1=1", "b2=");
                
                assertObjectEquals("['1','2']", c.getStringArray("a1"));
-               assertObjectEquals("['2','3']", c.getStringArray("default/a2"));
+               assertObjectEquals("['2','3']", c.getStringArray("a2"));
                assertObjectEquals("[]", c.getStringArray("a3"));
                assertObjectEquals("['1']", c.getStringArray("S/b1"));
                assertObjectEquals("[]", c.getStringArray("S/b2"));
@@ -276,7 +276,7 @@ public class ConfigTest {
                Config c = init("a1=1,2", "a2= 2 , 3 ", "[S]", "b1=1", "b2=");
                
                assertObjectEquals("['1','2']", c.getStringArray("a1", new 
String[] {"foo"}));
-               assertObjectEquals("['2','3']", c.getStringArray("default/a2", 
new String[] {"foo"}));
+               assertObjectEquals("['2','3']", c.getStringArray("a2", new 
String[] {"foo"}));
                assertObjectEquals("['foo']", c.getStringArray("a3", new 
String[] {"foo"}));
                assertObjectEquals("['1']", c.getStringArray("S/b1", new 
String[] {"foo"}));
                assertObjectEquals("['foo']", c.getStringArray("S/b2", new 
String[] {"foo"}));
@@ -292,7 +292,7 @@ public class ConfigTest {
                Config c = init("a1=1", "a2=2", "[S]", "b1=1", "b2=");
                
                assertEquals(1, c.getInt("a1"));
-               assertEquals(2, c.getInt("default/a2"));
+               assertEquals(2, c.getInt("a2"));
                assertEquals(0, c.getInt("a3"));
                assertEquals(1, c.getInt("S/b1"));
                assertEquals(0, c.getInt("S/b2"));
@@ -330,7 +330,7 @@ public class ConfigTest {
                Config c = init("a1=1", "a2=2", "[S]", "b1=1", "b2=");
                
                assertEquals(1, c.getInt("a1", -1));
-               assertEquals(2, c.getInt("default/a2", -1));
+               assertEquals(2, c.getInt("a2", -1));
                assertEquals(-1, c.getInt("a3", -1));
                assertEquals(1, c.getInt("S/b1", -1));
                assertEquals(-1, c.getInt("S/b2", -1));
@@ -368,7 +368,7 @@ public class ConfigTest {
                Config c = init("a1=true", "a2=false", "[S]", "b1=TRUE", "b2=");
                
                assertEquals(true, c.getBoolean("a1"));
-               assertEquals(false, c.getBoolean("default/a2"));
+               assertEquals(false, c.getBoolean("a2"));
                assertEquals(false, c.getBoolean("a3"));
                assertEquals(true, c.getBoolean("S/b1"));
                assertEquals(false, c.getBoolean("S/b2"));
@@ -394,7 +394,7 @@ public class ConfigTest {
                Config c = init("a1=true", "a2=false", "[S]", "b1=TRUE", "b2=");
                
                assertEquals(true, c.getBoolean("a1", true));
-               assertEquals(false, c.getBoolean("default/a2", true));
+               assertEquals(false, c.getBoolean("a2", true));
                assertEquals(true, c.getBoolean("a3", true));
                assertEquals(true, c.getBoolean("S/b1", true));
                assertEquals(true, c.getBoolean("S/b2", true));
@@ -420,7 +420,7 @@ public class ConfigTest {
                Config c = init("a1=1", "a2=2", "[S]", "b1=1", "b2=");
                
                assertEquals(1l, c.getLong("a1"));
-               assertEquals(2l, c.getLong("default/a2"));
+               assertEquals(2l, c.getLong("a2"));
                assertEquals(0l, c.getLong("a3"));
                assertEquals(1l, c.getLong("S/b1"));
                assertEquals(0l, c.getLong("S/b2"));
@@ -458,7 +458,7 @@ public class ConfigTest {
                Config c = init("a1=1", "a2=2", "[S]", "b1=1", "b2=");
                
                assertEquals(1l, c.getLong("a1", Long.MAX_VALUE));
-               assertEquals(2l, c.getLong("default/a2", Long.MAX_VALUE));
+               assertEquals(2l, c.getLong("a2", Long.MAX_VALUE));
                assertEquals(Long.MAX_VALUE, c.getLong("a3", Long.MAX_VALUE));
                assertEquals(1l, c.getLong("S/b1", Long.MAX_VALUE));
                assertEquals(Long.MAX_VALUE, c.getLong("S/b2", Long.MAX_VALUE));
@@ -496,7 +496,7 @@ public class ConfigTest {
                Config c = init("a1=Zm9v", "a2=Zm", "\t9v", "a3=");
                
                assertObjectEquals("[102,111,111]", c.getBytes("a1"));
-               assertObjectEquals("[102,111,111]", c.getBytes("default/a2"));
+               assertObjectEquals("[102,111,111]", c.getBytes("a2"));
                assertObjectEquals("[]", c.getBytes("a3"));
                assertNull(null, c.getBytes("a4"));
        }
@@ -509,7 +509,7 @@ public class ConfigTest {
                Config c = init("a1=Zm9v", "a2=Zm", "\t9v", "a3=");
                
                assertObjectEquals("[102,111,111]", c.getBytes("a1", new byte[] 
{1}));
-               assertObjectEquals("[102,111,111]", c.getBytes("default/a2", 
new byte[] {1}));
+               assertObjectEquals("[102,111,111]", c.getBytes("a2", new byte[] 
{1}));
                assertObjectEquals("[1]", c.getBytes("a3", new byte[] {1}));
                assertObjectEquals("[1]", c.getBytes("a4", new byte[] {1}));
        }
@@ -865,7 +865,7 @@ public class ConfigTest {
        public void getKeys() throws Exception {
                Config c = init("a1=1", "a2=2", "[S]", "b1=1", "b2=");
                
-               assertObjectEquals("['a1','a2']", c.getKeys("default"));
+               assertObjectEquals("['a1','a2']", c.getKeys(""));
                assertObjectEquals("['a1','a2']", c.getKeys(""));
                assertObjectEquals("['b1','b2']", c.getKeys("S"));
                assertTrue(c.getKeys("T").isEmpty());
@@ -913,7 +913,7 @@ public class ConfigTest {
 
                c.writeProperties("", b, true);
                assertObjectEquals("{foo:'qux'}", b);
-               c.writeProperties("default", a, true);
+               c.writeProperties("", a, true);
                assertObjectEquals("{foo:'qux'}", a);
 
                try {
@@ -935,14 +935,14 @@ public class ConfigTest {
                
                a = c.getSectionAsBean("", ABean.class);
                assertObjectEquals("{foo:'qux'}", a);
-               a = c.getSectionAsBean("default", ABean.class);
+               a = c.getSectionAsBean("", ABean.class);
                assertObjectEquals("{foo:'qux'}", a);
                a = c.getSectionAsBean("S", ABean.class);
                assertObjectEquals("{foo:'baz'}", a);
                
                b = c.getSectionAsBean("", BBean.class);
                assertObjectEquals("{foo:'qux'}", b);
-               b = c.getSectionAsBean("default", BBean.class);
+               b = c.getSectionAsBean("", BBean.class);
                assertObjectEquals("{foo:'qux'}", b);
                b = c.getSectionAsBean("S", BBean.class);
                assertObjectEquals("{foo:'baz'}", b);
@@ -1026,7 +1026,7 @@ public class ConfigTest {
                Config c = init("a=1", "[S]", "b=2", "[T]");
                
                assertObjectEquals("{a:'1'}", c.getSectionAsMap(""));
-               assertObjectEquals("{a:'1'}", c.getSectionAsMap("default"));
+               assertObjectEquals("{a:'1'}", c.getSectionAsMap(""));
                assertObjectEquals("{b:'2'}", c.getSectionAsMap("S"));
                assertObjectEquals("{}", c.getSectionAsMap("T"));
                assertNull(c.getSectionAsMap("U"));
@@ -1049,7 +1049,7 @@ public class ConfigTest {
                a = c.getSectionAsInterface("", AInterface.class);
                assertEquals("qux", a.getFoo());
        
-               a = c.getSectionAsInterface("default", AInterface.class);
+               a = c.getSectionAsInterface("", AInterface.class);
                assertEquals("qux", a.getFoo());
 
                a = c.getSectionAsInterface("S", AInterface.class);
@@ -1101,7 +1101,7 @@ public class ConfigTest {
                c.setSection("", Arrays.asList("#C1", "#C2"));
                assertTextEquals("#C1|#C2||", c);
 
-               c.setSection("default", Arrays.asList("#C3", "#C4"));
+               c.setSection("", Arrays.asList("#C3", "#C4"));
                assertTextEquals("#C3|#C4||", c);
                
                c.setSection("S1", Arrays.asList("", "#C5", "#C6"));
@@ -1132,7 +1132,7 @@ public class ConfigTest {
                c.setSection("", Arrays.asList("#C1", "#C2"), m);
                assertTextEquals("#C1|#C2||a = b|", c);
 
-               c.setSection("default", Arrays.asList("#C3", "#C4"), m);
+               c.setSection("", Arrays.asList("#C3", "#C4"), m);
                assertTextEquals("#C3|#C4||a = b|", c);
                
                c.setSection("S1", Arrays.asList("", "#C5", "#C6"), m);
@@ -1164,7 +1164,7 @@ public class ConfigTest {
                
                assertTextEquals("a=1|", c);
                
-               c.removeSection("default");
+               c.removeSection("");
                assertTextEquals("", c);
        }
 
@@ -1426,7 +1426,7 @@ public class ConfigTest {
                                @Override
                                public void onConfigChange(List<ConfigEvent> 
events) {
                                        for (ConfigEvent ce : events) {
-                                               String key = 
(ce.getSection().equals("default") ? "" : (ce.getSection() + '/')) + 
ce.getKey();
+                                               String key = 
(ce.getSection().equals("") ? "" : (ce.getSection() + '/')) + ce.getKey();
                                                if (ce.getType() == 
ConfigEventType.REMOVE_ENTRY) {
                                                        
changes.add("REMOVE_ENTRY("+key+")");
                                                } else if (ce.getType() == 
ConfigEventType.REMOVE_SECTION) {
diff --git a/juneau-doc/src/main/javadoc/overview.html 
b/juneau-doc/src/main/javadoc/overview.html
index ed2ca98..e15f399 100644
--- a/juneau-doc/src/main/javadoc/overview.html
+++ b/juneau-doc/src/main/javadoc/overview.html
@@ -4672,372 +4672,276 @@
        <a id="juneau-config.Overview"></a>
        <h3 class='topic' onclick='toggle(this)'>6.1 - Overview</h3>
        <div class='topic'>
-       </div>
-
-       <!-- 
========================================================================================================
 -->
-       <a id="juneau-config.EntryTypes"></a>
-       <h3 class='topic' onclick='toggle(this)'>6.2 - Entry Types</h3>
-       <div class='topic'>
-
-               <!-- 
========================================================================================================
 -->
-               <a id="juneau-config.PrimitiveTypes"></a>
-               <h4 class='topic' onclick='toggle(this)'>6.2.1 - Primitive 
Types</h4>
-               <div class='topic'>
-               </div>
-
-               <!-- 
========================================================================================================
 -->
-               <a id="juneau-config.POJOs"></a>
-               <h4 class='topic' onclick='toggle(this)'>6.2.2 - POJOs</h4>
-               <div class='topic'>
-               </div>
-
-               <!-- 
========================================================================================================
 -->
-               <a id="juneau-config.Arrays"></a>
-               <h4 class='topic' onclick='toggle(this)'>6.2.3 - Arrays</h4>
-               <div class='topic'>
-               </div>
-
-               <!-- 
========================================================================================================
 -->
-               <a id="juneau-config.Collections"></a>
-               <h4 class='topic' onclick='toggle(this)'>6.2.4 - 
Collections</h4>
-               <div class='topic'>
-               </div>
-
-               <!-- 
========================================================================================================
 -->
-               <a id="juneau-config.BinaryData"></a>
-               <h4 class='topic' onclick='toggle(this)'>6.2.5 - Binary 
Data</h4>
-               <div class='topic'>
-               </div>
-
-       </div>
-
-       <!-- 
========================================================================================================
 -->
-       <a id="juneau-config.Variables"></a>
-       <h3 class='topic' onclick='toggle(this)'>6.3 - Variables</h3>
-       <div class='topic'>
-       </div>
-
-       <!-- 
========================================================================================================
 -->
-       <a id="juneau-config.EncodedEntries"></a>
-       <h3 class='topic' onclick='toggle(this)'>6.4 - Encoded Entries</h3>
-       <div class='topic'>
-       </div>
-
-       <!-- 
========================================================================================================
 -->
-       <a id="juneau-config.SectionMaps"></a>
-       <h3 class='topic' onclick='toggle(this)'>6.5 - Section Maps</h3>
-       <div class='topic'>
-       </div>
-
-       <!-- 
========================================================================================================
 -->
-       <a id="juneau-config.SectionBeans"></a>
-       <h3 class='topic' onclick='toggle(this)'>6.6 - Section Beans</h3>
-       <div class='topic'>
-       </div>
-
-       <!-- 
========================================================================================================
 -->
-       <a id="juneau-config.SectionInterfaces"></a>
-       <h3 class='topic' onclick='toggle(this)'>6.7 - Section Interfaces</h3>
-       <div class='topic'>
-       </div>
-
-       <!-- 
========================================================================================================
 -->
-       <a id="juneau-config.SettingValues"></a>
-       <h3 class='topic' onclick='toggle(this)'>6.8 - Setting Values</h3>
-       <div class='topic'>
-
-               <!-- 
========================================================================================================
 -->
-               <a id="juneau-config.CustomEntrySerialization"></a>
-               <h4 class='topic' onclick='toggle(this)'>6.8.1 - Custom Entry 
Serialization</h4>
-               <div class='topic'>
-               </div>
-
-               <!-- 
========================================================================================================
 -->
-               <a id="juneau-config.BulkSettingValues"></a>
-               <h4 class='topic' onclick='toggle(this)'>6.8.2 - Setting Values 
in Bulk</h4>
-               <div class='topic'>
-               </div>
-
-       </div>
-
-       <!-- 
========================================================================================================
 -->
-       <a id="juneau-config.Listeners"></a>
-       <h3 class='topic' onclick='toggle(this)'>6.9 - Listeners</h3>
-       <div class='topic'>
-       </div>
-
-       <!-- 
========================================================================================================
 -->
-       <a id="juneau-config.Serializing"></a>
-       <h3 class='topic' onclick='toggle(this)'>6.10 - Serializing</h3>
-       <div class='topic'>
-       </div>
-
-       <!-- 
========================================================================================================
 -->
-       <a id="juneau-config.ConfigStores"></a>
-       <h3 class='topic' onclick='toggle(this)'>6.11 - Config Stores</h3>
-       <div class='topic'>
-               
-               <!-- 
========================================================================================================
 -->
-               <a id="juneau-config.ConfigMemoryStore"></a>
-               <h4 class='topic' onclick='toggle(this)'>6.11.1 - 
ConfigMemoryStore</h4>
-               <div class='topic'>
-               </div>
-               
-               <!-- 
========================================================================================================
 -->
-               <a id="juneau-config.ConfigFileStore"></a>
-               <h4 class='topic' onclick='toggle(this)'>6.11.2 - 
ConfigFileStoren</h4>
-               <div class='topic'>
-               </div>
-
-       </div>
-
-       <!-- 
========================================================================================================
 -->
-       <a id="juneau-config.ReadOnlyConfigs"></a>
-       <h3 class='topic' onclick='toggle(this)'>6.12 - Read-only Configs</h3>
-       <div class='topic'>
-       </div>
-
-       <!-- 
========================================================================================================
 -->
-       <a id="#juneau-config.ClosingConfigs"></a>
-       <h3 class='topic' onclick='toggle(this)'>6.13 - Closing Configs</h3>
-       <div class='topic'>
-       </div>
-
-       
-       <!-- 
========================================================================================================
 -->
-       <a id="juneau-config.Overview"></a>
-       <h3 class='topic' onclick='toggle(this)'>6.1 - Overview</h3>
-       <div class='topic'>
                <p>
                        The <code>juneau-config</code> library contains a 
powerful API for creating and using INI-style config files.
                </p>
                <p>
-                       An example of the cotents of a config file:
+                       An example of the contents of a config file:
                </p>
                <p class='bcode'>
-       <cc># Default section</cc>
+       <cs>[Section1]</cs>
+
+       <cc># An integer</cc>
        <ck>key1</ck> = <cv>1</cv>
+
+       <cc># A boolean</cc>
        <ck>key2</ck> = <cv>true</cv>
-       <ck>key3</ck> = <cv>[1,2,3]</cv>
-       <ck>key4</ck> = <cv>http://foo</cv>
        
-       <cc># Section 1</cc>
-       <cs>[Section1]</cs>
-       <ck>key1</ck> = <cv>2</cv>
-       <ck>key2</ck> = <cv>false</cv>
-       <ck>key3</ck> = <cv>[4,5,6]</cv>
+       <cc># An array</cc>
+       <ck>key3</ck> = <cv>1,2,3</cv>
+
+       <cc># A POJO</cc>
        <ck>key4</ck> = <cv>http://bar</cv>
                </p>
                <p>
-                       This class can be used to easily access contents of the 
file:
+                       This code shows how the file can be accessed:
                </p>
                <p class='bcode'>
-       <jk>int</jk> key1;
-       <jk>boolean</jk> key2;
-       <jk>int</jk>[] key3;
-       URL key4;
-       
        <jc>// Load our config file</jc>
-       Config f = 
Config.<jsm>create</jsm>().name(<js>"MyConfig.cfg"</js>).build();
-       
-       <jc>// Read values from default section</jc>
-       key1 = f.getInt(<js>"key1"</js>);
-       key2 = f.getBoolean(<js>"key2"</js>);
-       key3 = f.getObject(<jk>int</jk>[].<jk>class</jk>, <js>"key3"</js>);
-       key4 = f.getObject(URL.<jk>class</jk>, <js>"key4"</js>);
+       Config c = 
Config.<jsm>create</jsm>().name(<js>"MyConfig.cfg"</js>).build();
        
        <jc>// Read values from section #1</jc>
-       key1 = f.getInt(<js>"Section1/key1"</js>);
-       key2 = f.getBoolean(<js>"Section1/key2"</js>);
-       key3 = f.getObject(<jk>int</jk>[].<jk>class</jk>, 
<js>"Section1/key3"</js>);
-       key4 = f.getObject(URL.<jk>class</jk>, <js>"Section1/key4"</js>);
+       <jk>int</jk> key1 = c.getInt(<js>"Section1/key1"</js>);
+       <jk>boolean</jk>key2 = c.getBoolean(<js>"Section1/key2"</js>);
+       <jk>int</jk>[]key3 = c.getObject(<js>"Section1/key3"</js>, 
<jk>int</jk>[].<jk>class</jk>, );
+       URL key4 = c.getObject(<js>"Section1/key4"</js>, URL.<jk>class</jk>);
                </p>
                <p>
-                       The interface also allows a config file to be easily 
constructed programmatically:
-               </p>
-               <p class='bcode'>
-       <jc>// Construct the sample config file programmatically</jc>
-       Config cf = 
Config.<jsm>create</jsm>().name(<js>"MyConfig.cfg"</js>).build()
-               .addLines(<jk>null</jk>,
-                       <js>"# Default section"</js>,
-                       <js>"key1 = 1"</js>,
-                       <js>"key2 = true"</js>,
-                       <js>"key3 = [1,2,3]"</js>,
-                       <js>"key4 = http://foo";</js>,
-                       <js>""</js>)
-               .addHeaderComments(<js>"Section1"</js>,
-                       <js>"# Section 1"</js>)
-               .addLines(<js>"Section1"</js>,
-                       <js>"key1 = 2"</js>,
-                       <js>"key2 = false"</js>,
-                       <js>"key3 = [4,5,6]"</js>,
-                       <js>"key4 = http://bar";</js>)
-               .save();
-               </p>
-               <p>
-                       The following is equivalent, except that it uses 
<code><del>Config#put(String, Object)</del></code> 
-                       to set values:
-               </p>
-               <p class='bcode'>
-       <jc>// Construct the sample config file programmatically</jc>
-       Config cf = 
Config.<jsm>create</jsm>().name(<js>"MyConfig.cfg"</js>).build()
-               .addLines(<jk>null</jk>,
-                       <js>"# Default section"</js>)
-               .addHeaderComments(<js>"section1"</js>,
-                       <js>"# Section 1"</js>);
-       cf.put(<js>"key1"</js>, 1);
-       cf.put(<js>"key2"</js>, <jk>true</jk>);
-       cf.put(<js>"key3"</js>, <jk>new int</jk>[]{1,2,3});
-       cf.put(<js>"key4"</js>, <jk>new</jk> URL(<js>"http://foo";</js>));
-       cf.put(<js>"Section1/key1"</js>, 2);
-       cf.put(<js>"Section1/key2"</js>, <jk>false</jk>);
-       cf.put(<js>"Section1/key3"</js>, <jk>new int</jk>[]{4,5,6});
-       cf.put(<js>"Section1/key4"</js>, <jk>new</jk> 
URL(<js>"http://bar";</js>));
-       cf.save();
-               </p>
-               <p>
-                       Values are LAX JSON (i.e. unquoted attributes, single 
quotes) except for top-level strings which are left 
-                       unquoted.  
-                       <br>Any <a class='doclink' 
href='#juneau-marshall.PojoCategories'>parsable</a> types are supported as 
values (e.g. arrays, collections, beans, swappable objects, 
-                       enums, etc...).
-               </p>
-               <p>
-                       The config file looks deceptively simple, the config 
file API is a very powerful feature with many 
-                       capabilities, including:
+                       The config language may look simple, but it is a very 
powerful feature with many capabilities including:
                </p>
                <ul class='spaced-list'>
                        <li>
-                               The ability to use variables to reference 
environment variables, system properties, other config file 
-                               entries, and a host of other types.
-                       <li>
                                APIs for updating, modifying, and saving 
configuration files <b style='text-decoration: underline;'>without losing 
comments or formatting</b>!
                        <li>
+                               The ability to use variables to reference 
environment variables, system properties, other config file entries, and a host 
of other types.
+                       <li>
                                Extensive listener APIs.
+                       <li>
+                               Full file system watcher integration.
+                       <li>
+                               Support for user-defined storage mechanisms.
                </ul>
                
-               <h5 class='figure'>Example:</h5>
-               <p class='bcode'>
-       <cc>#--------------------------</cc>
-       <cc># My section</cc>
-       <cc>#--------------------------</cc>
-       <cs>[MySection]</cs>
-       
-       <cc># An integer</cc>
-       <ck>anInt</ck> = <cv>1</cv> 
-       
-       <cc># A boolean</cc>
-       <ck>aBoolean</ck> = <cv>true</cv>
-       
-       <cc># An int array</cc>
-       <ck>anIntArray</ck> = <cv>[1,2,3]</cv>
-       
-       <cc># A POJO that can be converted from a String</cc>
-       <ck>aURL</ck> = <cv>http://foo </cv>
-       
-       <cc># A POJO that can be converted from JSON</cc>
-       <ck>aBean</ck> = <cv>{foo:'bar',baz:123}</cv>
-               </p>
-               <p class='bcode'>
-       <jc>// Java code for accessing config entries above.</jc>
-       Config cf = 
Config.<jsf>create</jsf>().name(<js>"MyConfig.cfg"</js>).build();
+               <!-- 
========================================================================================================
 -->
+               <a id="juneau-config.EntryTypes"></a>
+               <h4 class='topic' onclick='toggle(this)'>6.1.1 - Formatting 
Rules</h4>
+               <div class='topic'>
+                       <p>
+                               Each config file contains zero or more sections 
containing zero or more entries:
+                       </p>
+                       <p class='bcode'>
+               <cs>[Section1]</cs>
+               <ck>key1</ck> = <cv>1</cv>
        
-       <jk>int</jk> anInt = cf.getInt(<js>"MySection/anInt"</js>); 
-       <jk>boolean</jk> aBoolean = 
cf.getBoolean(<js>"MySection/aBoolean"</js>); 
-       <jk>int</jk>[] anIntArray = cf.getObject(<jk>int</jk>[].<jk>class</jk>, 
<js>"MySection/anIntArray"</js>); 
-       URL aURL = cf.getObject(URL.<jk>class</jk>, <js>"MySection/aURL"</js>); 
-       MyBean aBean = cf.getObject(MyBean.<jk>class</jk>, 
<js>"MySection/aBean"</js>); 
-               </p>
+               <cs>[Section2]</cs>
+               <ck>key1</ck> = <cv>2</cv>
+                       </p>
+                       <p>
+                               Comments start with the <js>'#'</js> character 
and can be placed on lines before sections and entries:
+                       </p>
+                       <p class='bcode'>
+               <cs># A comment about this section</cs>
+               <cs>[Section1]</cs>
+               
+               <cs># A comment about this entry</cs>
+               <ck>key1</ck> = <cv>1</cv>
+                       </p>
+                       <p>
+                               Comments can also be placed on the same line as 
entries:
+                       </p>
+                       <p class='bcode'>
+               
+               <ck>key1</ck> = <cv>1</cv> <cs># A comment about this entry
+                       </p>
+                       <p>
+                               Values containing <js>'#'</js> must be escaped 
to prevent identification as a comment character:
+                       </p>
+                       <p class='bcode'>
+               <ck>valueContainingPound</ck> = <cv>Value containing \# 
character</cv>
+                       </p>
+                       <p>
+                               Values containing newlines can span multiple 
lines.
+                               <br>Subsequent lines start with a tab character.
+                       </p>
+                       <p class='bcode'>
+               <ck>multiLineValue</ck> = <cv>Line 1,</cv>
+                       <cv>Line 2,</cv>
+                       <cv>Line 3</cv>
+                       </p>
+                       <p>
+                               Blank lines can be used anywhere in the file.
+                       </p>
+                       <p class='bcode'>
+               <cs># A comment line</cs>
+               
+               <cs># Another comment line</cs>
+               <cs>[Section1]</cs>
+                       </p>
+                       <p>
+                               Values located before any sections are 
considered part of the no-name section, meaning
+                               they are accessed simply by key and not 
section+key.
+                       </p>
+                       <p class='bcode'>
+               <cs># Top of file</cs>
+               
+               <cs># A value in the no-name section</cs>
+               <ck>key1</ck> = <cv>val1</cv>
+               
+               <cs># The first section</cs>
+               <cs>[Section1]</cs>
+                       </p>
+                       <p>
+                               Section and key names must be at least one 
character long and not consist of any of the following
+                               characters:
+                               <br><code>/ \ [ ] = #</code>
+                       </p>
+                       <p>
+                               Leading and trailing whitespace on values are 
ignored.
+                       </p>
+               </div>
        </div>
-       
+               
        <!-- 
========================================================================================================
 -->
-       <a id="juneau-config.SectionBeans"></a>
-       <h3 class='topic' onclick='toggle(this)'>6.2 - Section Beans</h3>
+       <a id="juneau-config.EntryTypes"></a>
+       <h3 class='topic' onclick='toggle(this)'>6.2 - Entry Types</h3>
        <div class='topic'>
                <p>
-                       Config files can also be used to directly populate 
beans using the 
-                       {@link 
org.apache.juneau.config.Config#getSectionAsBean(String,Class,boolean)}:
+                       Configuration files can contain entries for anything 
from primitive types up to complex hierarchies of POJOs consisting of maps, 
collections, and/or beans.
                </p>
-               <p class='bcode'>
-       <jc>// Example config file</jc>
-       <cs>[MyAddress]</cs>
-       <ck>name</ck> = <cv>John Smith</cv>
-       <ck>street</ck> = <cv>123 Main Street</cv>
-       <ck>city</ck> = <cv>Anywhere</cv>
-       <ck>state</ck> = <cv>NY</cv>
-       <ck>zip</ck> = <cv>12345</cv>
-
-       <jc>// Example bean</jc>
-       <jk>public class</jk> Address {
-               public String name, street, city;
-               public StateEnum state;
-               public int zip;
-       }
-
-       <jc>// Example usage</jc>
-       Config cf = 
Config.<jsm>create</jsm>().name(<js>"MyConfig.cfg"</js>).build();
-       Address myAddress = cf.getSectionAsBean(<js>"MySection"</js>, 
Address.<jk>class</jk>);
-               </p>
-       </div>
 
-       <!-- 
========================================================================================================
 -->
-       <a id="juneau-config.SectionInterfaces"></a>
-       <h3 class='topic' onclick='toggle(this)'>6.3 - Section Interfaces</h3>
-       <div class='topic'>
-               <p>
-                       Config file sections can also be accessed via interface 
proxies using 
-                       {@link 
org.apache.juneau.config.Config#getSectionAsInterface(String,Class)}:
-               </p>
-               <p class='bcode'>
-       <jc>// Example config file</jc>
-       <cs>[MySection]</cs>
-       <ck>string</ck> = <cv>foo</cv>
-       <ck>int</ck> = <cv>123</cv>
-       <ck>enum</ck> = <cv>ONE</cv>
-       <ck>bean</ck> = <cv>{foo:'bar',baz:123}</cv>
-       <ck>int3dArray</ck> = <cv>[[[123,null],null],null]</cv>
-       <ck>bean1d3dListMap</ck> = <cv>{key:[[[[{foo:'bar',baz:123}]]]]}</cv>
+               <!-- 
========================================================================================================
 -->
+               <a id="juneau-config.PrimitiveTypes"></a>
+               <h4 class='topic' onclick='toggle(this)'>6.2.1 - Primitive 
Types</h4>
+               <div class='topic'>
+                       <p>
+                               The most common case for configuration values 
are primitives.
+                       </p>
+                       <p class='bcode'>
+       <cc># A string</cc>
+       <ck>key1</ck> = <cv>foo</cv>
 
-       <jc>// Example interface.</jc>
-       <jc>// Setters are optional.</jc>
-       <jk>public interface</jk> MyConfigInterface {
+       <cc># A boolean</cc>
+       <ck>key2</ck> = <cv>true</cv>
 
-               String getString();
-               <jk>void</jk> setString(String x);
+       <cc># An integer</cc>
+       <ck>key3</ck> = <cv>123</cv>
+       
+       <cc># A long</cc>
+       <ck>key4</ck> = <cv>10000000000</cv>
+                       </p>
+                       <p>
+                               The following methods are provided for 
accessing primitive values:
+                       </p>
+                       <ul class='doctree'>
+                               <li class='jc'>{@link 
org.apache.juneau.config.Config}
+                               <ul>
+                                       <li class='jm'>{@link 
org.apache.juneau.config.Config#getString(String) getString(String)}
+                                       <li class='jm'>{@link 
org.apache.juneau.config.Config#getString(String,String) 
getString(String,String)}
+                                       <li class='jm'>{@link 
org.apache.juneau.config.Config#getBoolean(String) getBoolean(String)}
+                                       <li class='jm'>{@link 
org.apache.juneau.config.Config#getBoolean(String,boolean) 
getBoolean(String,boolean)}
+                                       <li class='jm'>{@link 
org.apache.juneau.config.Config#getInt(String) getInt(String)}
+                                       <li class='jm'>{@link 
org.apache.juneau.config.Config#getInt(String,int) getInt(String,int)}
+                                       <li class='jm'>{@link 
org.apache.juneau.config.Config#getLong(String) getLong(String)}
+                                       <li class='jm'>{@link 
org.apache.juneau.config.Config#getLong(String,long) getLong(String,long)}
+                               </ul>
+                       </ul>
+                       <p>
+                               On integers and longs, <js>"K"</js>, 
<js>"M"</js>, and <js>"G"</js> can be used to identify kilo, mega, and giga.
+                       </p>    
+                       <p class='bcode'>
+       <ck>key1</ck> = <cv>100K</cv> <cc># Same as 1024000</cc>
+       <ck>key2</ck> = <cv>100M</cv> <cc># Same as 104857600</cc>
+                       </p>
+                       <p>
+                               Strings can be broken into separate lines by 
starting the next line with a tab:
+                       </p>
+                       <p class='bcode'>
+       <ck>key1</ck> = <cv>This is a particularly long sentence that we want 
to split</cv>
+               <cv>onto separate lines</cv>.
+                       </p>
+                       <p>
+                               Broken lines are not trimmed between lines, and 
are concatenated with newlines.
+                               <br>The example above translates to <js>"This 
is a particularly....split\nonto separate lines"</js>, but
+                               could could pad the start and end of lines with 
spaces if you wish.
+                       </p>
 
-               <jk>int</jk> getInt();
-               <jk>void</jk> setInt(<jk>int</jk> x);
+               </div>
 
-               MyEnum getEnum();
-               <jk>void</jk> setEnum(MyEnum x);
+               <!-- 
========================================================================================================
 -->
+               <a id="juneau-config.POJOs"></a>
+               <h4 class='topic' onclick='toggle(this)'>6.2.2 - POJOs</h4>
+               <div class='topic'>
+                       <p>
+                               The following methods are provided for 
accessing POJO values:
+                       </p>
+                       <ul class='doctree'>
+                               <li class='jc'>{@link 
org.apache.juneau.config.Config}
+                               <ul>
+                                       <li class='jm'>{@link 
org.apache.juneau.config.Config#getObject(String,Class) getObject(String,Class)}
+                                       <li class='jm'>{@link 
org.apache.juneau.config.Config#getObject(String,Parser,Class) 
getObject(String,Parser,Class)}
+                                       <li class='jm'>{@link 
org.apache.juneau.config.Config#getObjectWithDefault(String,T,Class) 
getObjectWithDefault(String,T,Class)}
+                                       <li class='jm'>{@link 
org.apache.juneau.config.Config#getObjectWithDefault(String,T,Parser,Class) 
getObjectWithDefault(String,T,Parser,Class)}
+                               </ul>
+                       </ul>
+               </div>
 
-               MyBean getBean();
-               <jk>void</jk> setBean(MyBean x);
+               <!-- 
========================================================================================================
 -->
+               <a id="juneau-config.Arrays"></a>
+               <h4 class='topic' onclick='toggle(this)'>6.2.3 - Arrays</h4>
+               <div class='topic'>
+                       <p>
+                               The following methods are provided for 
accessing arrays:
+                       </p>
+                       <ul class='doctree'>
+                               <li class='jc'>{@link 
org.apache.juneau.config.Config}
+                               <ul>
+                                       <li class='jm'>{@link 
org.apache.juneau.config.Config#getStringArray(String) getStringArray(String)}
+                                       <li class='jm'>{@link 
org.apache.juneau.config.Config#getStringArray(String,String[]) 
getStringArray(String,String)}
+                                       <li class='jm'>{@link 
org.apache.juneau.config.Config#getObject(String,Class) getObject(String,Class)}
+                                       <li class='jm'>{@link 
org.apache.juneau.config.Config#getObject(String,Parser,Class) 
getObject(String,Parser,Class)}
+                               </ul>
+                       </ul>
+               </div>
 
-               <jk>int</jk>[][][] getInt3dArray();
-               <jk>void</jk> setInt3dArray(<jk>int</jk>[][][] x);
-               
-               Map&lt;String,List&lt;MyBean[][][]&gt;&gt; getBean1d3dListMap();
-               <jk>void</jk> 
setBean1d3dListMap(Map&lt;String,List&lt;MyBean[][][]&gt;&gt; x);
-       }
-       
-       <jc>// Example usage.</jc>
-       Config cf = 
Config.<jsm>create</jsm>().name(<js>"MyConfig.cfg"</js>).build();
-       MyConfigInterface ci = cf.getSectionAsInterface(<js>"MySection"</js>, 
MyConfigInterface.<jk>class</jk>);
-       
-       <jc>// Read a value.</jc>
-       <jk>int</jk> myInt = ci.getInt();
+               <!-- 
========================================================================================================
 -->
+               <a id="juneau-config.Collections"></a>
+               <h4 class='topic' onclick='toggle(this)'>6.2.4 - 
Collections</h4>
+               <div class='topic'>
+                       <p>
+                               The following methods are provided for 
accessing maps and collections:
+                       </p>
+                       <ul class='doctree'>
+                               <li class='jc'>{@link 
org.apache.juneau.config.Config}
+                               <ul>
+                                       <li class='jm'>{@link 
org.apache.juneau.config.Config#getObject(String,Type,Type...) 
getObject(String,Type,Type...)}
+                                       <li class='jm'>{@link 
org.apache.juneau.config.Config#getObject(String,Parser,Type,Type...) 
getObject(String,Parser,Type,Type...)}
+                                       <li class='jm'>{@link 
org.apache.juneau.config.Config#getObjectWithDefault(String,T,Type,Type...) 
getObjectWithDefault(String,T,Type,Type...)}
+                                       <li class='jm'>{@link 
org.apache.juneau.config.Config#getObjectWithDefault(String,T,Parser,Type,Type...)
 getObjectWithDefault(String,T,Parser,Type,Type...)}
+                               </ul>
+                       </ul>
+               </div>
 
-       <jc>// Write a value.</jc>
-       ci.setBean(<jk>new</jk> MyBean());
+               <!-- 
========================================================================================================
 -->
+               <a id="juneau-config.BinaryData"></a>
+               <h4 class='topic' onclick='toggle(this)'>6.2.5 - Binary 
Data</h4>
+               <div class='topic'>
+                       <p>
+                               The following methods are provided for 
accessing maps and collections:
+                       </p>
+                       <ul class='doctree'>
+                               <li class='jc'>{@link 
org.apache.juneau.config.Config}
+                               <ul>
+                                       <li class='jm'>{@link 
org.apache.juneau.config.Config#getBytes(String) getBytes(String)}
+                                       <li class='jm'>{@link 
org.apache.juneau.config.Config#getBytes(String,byte[]) getBytes(String,byte[])}
+                               </ul>
+                       </ul>
+               </div>
 
-       <jc>// Save your changes.</jc>
-       cf.save();
-               </p>
        </div>
 
        <!-- 
========================================================================================================
 -->
        <a id="juneau-config.Variables"></a>
-       <h3 class='topic' onclick='toggle(this)'>6.4 - Variables</h3>
+       <h3 class='topic' onclick='toggle(this)'>6.3 - Variables</h3>
        <div class='topic'>
                <p>
                        Config files can contain variables that get resolved 
dynamically using the 
@@ -5134,10 +5038,10 @@
                        <li><code>$UE</code> - URL-encoding function.
                </ul>
        </div>
-       
+
        <!-- 
========================================================================================================
 -->
        <a id="juneau-config.EncodedEntries"></a>
-       <h3 class='topic' onclick='toggle(this)'>6.5 - Encoded Entries</h3>
+       <h3 class='topic' onclick='toggle(this)'>6.4 - Encoded Entries</h3>
        <div class='topic'>
                <p>
                        If a config file contains sensitive information such as 
passwords, those values can be 
@@ -5169,10 +5073,138 @@
                        <code><del>ConfigBuilder#encoder(Encoder)</del></code> 
method.
                </p>
        </div>
+
+       <!-- 
========================================================================================================
 -->
+       <a id="juneau-config.SectionMaps"></a>
+       <h3 class='topic' onclick='toggle(this)'>6.5 - Section Maps</h3>
+       <div class='topic'>
+       </div>
+
+       <!-- 
========================================================================================================
 -->
+       <a id="juneau-config.SectionBeans"></a>
+       <h3 class='topic' onclick='toggle(this)'>6.6 - Section Beans</h3>
+       <div class='topic'>
+               <p>
+                       Config files can also be used to directly populate 
beans using the 
+                       {@link 
org.apache.juneau.config.Config#getSectionAsBean(String,Class,boolean)}:
+               </p>
+               <p class='bcode'>
+       <jc>// Example config file</jc>
+       <cs>[MyAddress]</cs>
+       <ck>name</ck> = <cv>John Smith</cv>
+       <ck>street</ck> = <cv>123 Main Street</cv>
+       <ck>city</ck> = <cv>Anywhere</cv>
+       <ck>state</ck> = <cv>NY</cv>
+       <ck>zip</ck> = <cv>12345</cv>
+
+       <jc>// Example bean</jc>
+       <jk>public class</jk> Address {
+               public String name, street, city;
+               public StateEnum state;
+               public int zip;
+       }
+
+       <jc>// Example usage</jc>
+       Config cf = 
Config.<jsm>create</jsm>().name(<js>"MyConfig.cfg"</js>).build();
+       Address myAddress = cf.getSectionAsBean(<js>"MySection"</js>, 
Address.<jk>class</jk>);
+               </p>
+       </div>
+
+       <!-- 
========================================================================================================
 -->
+       <a id="juneau-config.SectionInterfaces"></a>
+       <h3 class='topic' onclick='toggle(this)'>6.7 - Section Interfaces</h3>
+       <div class='topic'>
+               <p>
+                       Config file sections can also be accessed via interface 
proxies using 
+                       {@link 
org.apache.juneau.config.Config#getSectionAsInterface(String,Class)}:
+               </p>
+               <p class='bcode'>
+       <jc>// Example config file</jc>
+       <cs>[MySection]</cs>
+       <ck>string</ck> = <cv>foo</cv>
+       <ck>int</ck> = <cv>123</cv>
+       <ck>enum</ck> = <cv>ONE</cv>
+       <ck>bean</ck> = <cv>{foo:'bar',baz:123}</cv>
+       <ck>int3dArray</ck> = <cv>[[[123,null],null],null]</cv>
+       <ck>bean1d3dListMap</ck> = <cv>{key:[[[[{foo:'bar',baz:123}]]]]}</cv>
+
+       <jc>// Example interface.</jc>
+       <jc>// Setters are optional.</jc>
+       <jk>public interface</jk> MyConfigInterface {
+
+               String getString();
+               <jk>void</jk> setString(String x);
+
+               <jk>int</jk> getInt();
+               <jk>void</jk> setInt(<jk>int</jk> x);
+
+               MyEnum getEnum();
+               <jk>void</jk> setEnum(MyEnum x);
+
+               MyBean getBean();
+               <jk>void</jk> setBean(MyBean x);
+
+               <jk>int</jk>[][][] getInt3dArray();
+               <jk>void</jk> setInt3dArray(<jk>int</jk>[][][] x);
+               
+               Map&lt;String,List&lt;MyBean[][][]&gt;&gt; getBean1d3dListMap();
+               <jk>void</jk> 
setBean1d3dListMap(Map&lt;String,List&lt;MyBean[][][]&gt;&gt; x);
+       }
+       
+       <jc>// Example usage.</jc>
+       Config cf = 
Config.<jsm>create</jsm>().name(<js>"MyConfig.cfg"</js>).build();
+       MyConfigInterface ci = cf.getSectionAsInterface(<js>"MySection"</js>, 
MyConfigInterface.<jk>class</jk>);
        
+       <jc>// Read a value.</jc>
+       <jk>int</jk> myInt = ci.getInt();
+
+       <jc>// Write a value.</jc>
+       ci.setBean(<jk>new</jk> MyBean());
+
+       <jc>// Save your changes.</jc>
+       cf.save();
+               </p>
+       </div>
+
+       <!-- 
========================================================================================================
 -->
+       <a id="juneau-config.SettingValues"></a>
+       <h3 class='topic' onclick='toggle(this)'>6.8 - Setting Values</h3>
+       <div class='topic'>
+
+               <p>
+                       The interface also allows a config file to be easily 
constructed programmatically:
+               </p>
+               <p class='bcode'>
+       <jc>// Construct the sample config file programmatically</jc>
+       Config cf = 
Config.<jsm>create</jsm>().name(<js>"MyConfig.cfg"</js>).build()
+               .set(<js>"key1"</js>, 1)
+               .set(<js>"key2"</js>, <jk>true</jk>)
+               .set(<js>"key3"</js>, <jk>new int</jk>[]{1,2,3})
+               .set(<js>"key4"</js>, <jk>new</jk> URI(<js>"http://foo";</js>))
+               .set(<js>"Section1/key1"</js>, 2)
+               .set(<js>"Section1/key2"</js>, <jk>false</jk>)
+               .set(<js>"Section1/key3"</js>, <jk>new int</jk>[]{4,5,6})
+               .set(<js>"Section1/key4"</js>, <jk>new</jk> 
URI(<js>"http://bar";</js>))
+               .save();
+               </p>
+
+               <!-- 
========================================================================================================
 -->
+               <a id="juneau-config.CustomEntrySerialization"></a>
+               <h4 class='topic' onclick='toggle(this)'>6.8.1 - Custom Entry 
Serialization</h4>
+               <div class='topic'>
+               </div>
+
+               <!-- 
========================================================================================================
 -->
+               <a id="juneau-config.BulkSettingValues"></a>
+               <h4 class='topic' onclick='toggle(this)'>6.8.2 - Setting Values 
in Bulk</h4>
+               <div class='topic'>
+               </div>
+
+       </div>
+
        <!-- 
========================================================================================================
 -->
        <a id="juneau-config.Listeners"></a>
-       <h3 class='topic' onclick='toggle(this)'>6.6 - Listeners</h3>
+       <h3 class='topic' onclick='toggle(this)'>6.9 - Listeners</h3>
        <div class='topic'>
                <p>
                        The following method is provided for listening to 
changes made on config files:
@@ -5208,256 +5240,57 @@
        );
                </p>
        </div>
-       
-       
+
        <!-- 
========================================================================================================
 -->
        <a id="juneau-config.Serializing"></a>
-       <h3 class='topic' onclick='toggle(this)'>6.8 - Serializing Config 
Files</h3>
+       <h3 class='topic' onclick='toggle(this)'>6.10 - Serializing</h3>
        <div class='topic'>
-               <p>
-                       Instances of {@link org.apache.juneau.config.Config} 
are POJOs that can be serialized to and parsed from
-                               all supported Juneau languages.
-               </p>
-               <p>
-                       The 
<code>org.apache.juneau.microservice.resources.ConfigResource</code> is a 
predefined REST interface that
-                       allows access to the config file used by a microservice.
-                       <br>The <code>juneau-examples-rest</code> project is a 
microservice that includes this resource
-                       at <code>http://localhost:10000/sample/config</code>.
-                       <br>The sample microservice uses the following config 
file <code>juneau-examples.cfg</code>:
-               </p>
-               <p class='bcode'>
-       
<cc>#================================================================================
-       # Basic configuration file for SaaS microservices
-       # Subprojects can use this as a starting point.
-       
#================================================================================</cc>
-       
-       
<cc>#================================================================================
-       # REST settings
-       
#================================================================================</cc>
-       <cs>[REST]</cs>
-       
-       <cc># The HTTP port number to use.
-       # Default is Rest-Port setting in manifest file, or 8000.</cc>
-       <ck>port</ck> = <cv>10000</cv>
-       
-       <cc># A JSON map of servlet paths to servlet classes.
-       # Example:  
-       #       resourceMap = {'/*':'com.foo.MyServlet'}
-       # Either resourceMap or resources must be specified.</cc>
-       <ck>resourceMap</ck> = 
-
-       <cc># A comma-delimited list of names of classes that extend from 
Servlet.
-       # Resource paths are pulled from @RestResource.path() annotation, or
-       #       "/*" if annotation not specified.
-       # Example:  
-       #       resources = com.foo.MyServlet
-       # Default is Rest-Resources in manifest file.
-       # Either resourceMap or resources must be specified.</cc>
-       <ck>resources</ck> = 
-
-       <cc># The context root of the Jetty server.
-       # Default is Rest-ContextPath in manifest file, or "/".</cc>
-       <ck>contextPath</ck> = 
+       </div>
 
-       <cc># Authentication:  NONE, BASIC.</cc>
-       <ck>authType</ck> = <cv>NONE</cv>
-       
-       <cc># The BASIC auth username.
-       # Default is Rest-LoginUser in manifest file.</cc>
-       <ck>loginUser</ck> = 
-       
-       <cc># The BASIC auth password.
-       # Default is Rest-LoginPassword in manifest file.</cc>
-       <ck>loginPassword</ck> = 
-       
-       <cc># The BASIC auth realm.
-       # Default is Rest-AuthRealm in manifest file.</cc>
-       <ck>authRealm</ck> = 
-       
-       <cc># Stylesheet to use for HTML views.
-       # The default options are:
-       #  - styles/juneau.css
-       #  - styles/devops.css
-       # Other stylesheets can be referenced relative to the servlet package 
or working
-       #       directory.</cc>
-       <ck>stylesheet</ck> = <cv>styles/devops.css</cv>
-       
-       <cc># What to do when the config file is saved.
-       # Possible values:
-       #       NOTHING - Don't do anything. 
-       #       RESTART_SERVER - Restart the Jetty server.
-       #       RESTART_SERVICE - Shutdown and exit with code '3'.</cc>
-       <ck>saveConfigAction</ck> = <cv>RESTART_SERVER</cv>
-       
-       <cc># Enable SSL support.</cc>
-       <ck>useSsl</ck> = false
-       
-       
<cc>#================================================================================
-       # Bean properties on the org.eclipse.jetty.util.ssl.SslSocketFactory 
class
-       
#--------------------------------------------------------------------------------
-       # Ignored if REST/useSsl is false.
-       
#================================================================================</cc>
-       <cs>[REST-SslContextFactory]</cs>
-       <ck>keyStorePath</ck> = <cv>client_keystore.jks</cv>
-       <ck>keyStorePassword*</ck> = <cv>{HRAaRQoT}</cv>
-       <ck>excludeCipherSuites</ck> = <cv>TLS_DHE.*, TLS_EDH.*</cv>
-       <ck>excludeProtocols</ck> = <cv>SSLv3</cv>
-       <ck>allowRenegotiate</ck> = <cv>false</cv>
-       
-       
<cc>#================================================================================
-       # Logger settings
-       # See FileHandler Java class for details.
-       
#================================================================================</cc>
-       <cs>[Logging]</cs>
+       <!-- 
========================================================================================================
 -->
+       <a id="juneau-config.ConfigStores"></a>
+       <h3 class='topic' onclick='toggle(this)'>6.11 - Config Stores</h3>
+       <div class='topic'>
+               
+               <!-- 
========================================================================================================
 -->
+               <a id="juneau-config.ConfigMemoryStore"></a>
+               <h4 class='topic' onclick='toggle(this)'>6.11.1 - 
ConfigMemoryStore</h4>
+               <div class='topic'>
+               </div>
+               
+               <!-- 
========================================================================================================
 -->
+               <a id="juneau-config.ConfigFileStore"></a>
+               <h4 class='topic' onclick='toggle(this)'>6.11.2 - 
ConfigFileStoren</h4>
+               <div class='topic'>
+               </div>
 
-       <cc># The directory where to create the log file.
-       # Default is "."</cc>
-       <ck>logDir</ck> = <cv>logs</cv>
-       
-       <cc># The name of the log file to create for the main logger.
-       # The logDir and logFile make up the pattern that's passed to the 
FileHandler
-       # constructor.
-       # If value is not specified, then logging to a file will not be set 
up.</cc>
-       <ck>logFile</ck> = <cv>microservice.%g.log</cv>
-       
-       <cc># Whether to append to the existing log file or create a new one.
-       # Default is false.</cc>
-       <ck>append</ck> = 
-       
-       <cc># The SimpleDateFormat format to use for dates.
-       # Default is "yyyy.MM.dd hh:mm:ss".</cc>
-       <ck>dateFormat</ck> = 
-       
-       <cc># The log message format.
-       # The value can contain any of the following variables:
-       #       {date} - The date, formatted per dateFormat.
-       #       {class} - The class name.
-       #       {method} - The method name.
-       #       {logger} - The logger name.
-       #       {level} - The log level name.
-       #       {msg} - The log message.
-       #       {threadid} - The thread ID.
-       #       {exception} - The localized exception message.
-       # Default is "[{date} {level}] {msg}%n".</cc>
-       <ck>format</ck> =
-       
-       <cc># The maximum log file size.
-       # Suffixes available for numbers.
-       # See ConfigFile.getInt(String,int) for details.
-       # Default is 1M.</cc>
-       <ck>limit</ck> = <cv>10M</cv>
-       
-       <cc># Max number of log files.
-       # Default is 1.</cc>
-       <ck>count</ck> = <cv>5</cv>
-       
-       <cc># Default log levels.
-       # Keys are logger names.
-       # Values are serialized Level POJOs.</cc>
-       <ck>levels</ck> = <cv>{ org.apache.juneau:'INFO' }</cv>
-       
-       <cc># Only print unique stack traces once and then refer to them by a 
simple 8 character hash identifier.
-       # Useful for preventing log files from filling up with duplicate stack 
traces.
-       # Default is false.</cc>
-       <ck>useStackTraceHashes</ck> = <cv>true</cv>
-       
-       <cc># The default level for the console logger.
-       # Default is WARNING.</cc>
-       <ck>consoleLevel</ck> = 
-       
-       
<cc>#================================================================================
-       # System properties
-       
#--------------------------------------------------------------------------------
-       # These are arbitrary system properties that are set during startup.
-       
#================================================================================</cc>
-       <cs>[SystemProperties]</cs>
-       
-       <cc># Configure Jetty for StdErrLog Logging</cc>
-       <ck>org.eclipse.jetty.util.log.class</ck> = 
<cv>org.eclipse.jetty.util.log.StrErrLog</cv>
-       
-       <cc># Jetty logging level</cc>
-       <ck>org.eclipse.jetty.LEVEL</ck> = <cv>WARN</cv>                
-               </p>
-               <p>
-                       The config file looks deceivingly simple.
-                       However, it should be noticed that the config file is a 
VERY powerful feature with many capabilities including:
-               </p>
-               <p>
-                       When you point your browser to this resource, you'll 
notice that the contents of the config file are being 
-                       serialized to HTML as a POJO: 
-               </p>
-               <img class='bordered' 
src="doc-files/juneau-config.Serializing.1.png">
-               <p>
-                       Likewise, the config file can also be serialized as any 
of the supported languages such as JSON: 
-               </p>
-               <img class='bordered' 
src="doc-files/juneau-config.Serializing.2.png">
-               <p>
-                       The code for implementing this page could not be any 
simpler, since it simply returns the config file returned 
-                       by the <code>RestServlet.getConfig()</code> method.
-               </p>
-               <p class='bcode'>
-       <ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/"</js>, 
description=<js>"Show contents of config file."</js>)
-       <jk>public</jk> Config getConfigContents() <jk>throws</jk> Exception {
-               <jk>return</jk> getConfig();
-       }
-               </p>
-               <p>
-                       The edit page takes you to an editor that allows you to 
modify the contents of the config file: 
-               </p>
-               <img class='bordered' 
src="doc-files/juneau-config.Serializing.3.png">
-               <p>
-                       This latter page uses the {@link 
org.apache.juneau.config.Config#toString()} method to retrieve the
-                       contents of the config file in INI format.
-               </p>
-               <p>
-                       Since config files are serializable, that mean they can 
also be retrieved through the <code>RestClient</code> 
-                       API.
-               </p>
-               <p class='bcode'>
-       <jc>// Create a new REST client with JSON support</jc>
-       RestClient c = RestClient.<jsm>create</jsm>().build();
+       </div>
 
-       <jc>// Retrieve config file through REST interface</jc>
-       Config cf = 
c.doGet(<js>"http://localhost:10000/sample/config";</js>).getResponse(Config.<jk>class</jk>);
-               </p>
+       <!-- 
========================================================================================================
 -->
+       <a id="juneau-config.ReadOnlyConfigs"></a>
+       <h3 class='topic' onclick='toggle(this)'>6.12 - Read-only Configs</h3>
+       <div class='topic'>
        </div>
-       
+
        <!-- 
========================================================================================================
 -->
-       <a id="juneau-config.Merging"></a>
-       <h3 class='topic' onclick='toggle(this)'>6.9 - Merging Config Files</h3>
+       <a id="#juneau-config.ClosingConfigs"></a>
+       <h3 class='topic' onclick='toggle(this)'>6.13 - Closing Configs</h3>
        <div class='topic'>
-               <!--p>
-                       In the previous example, an edit page was shown that 
allows you to edit config files through
-                       a REST interface.
-                       <br>Note that if only a single entry is modified in the 
config file, we only want to trigger
-                       listeners for that change, not trigger all listeners.
-                       <br>This is where the 
<code><del>Config#merge(ConfigFile)</del></code> method comes into play.
-                       <br>This method will copy the contents of one config 
file over to another config file, but only
-                       trigger listeners when the values are different.
-               </p>
                <p>
-                       The edit page is implemented with this method which is 
a simple PUT with the contents of the new config file as 
-                       the body of the HTTP request:
+                       In general, it's good practice to close Config if 
you're only creating them temporarily so that
+                       their listeners get unregistered from the underlying 
storage APIs.
                </p>
                <p class='bcode'>
-       <ja>@RestMethod</ja>(name=<jsf>PUT</jsf>, path=<js>"/"</js>,
-               description=<js>"Sets contents of config file."</js>,
-               parameters={
-                       <ja>@Parameter</ja>(in=<js>"body"</js>, 
description=<js>"New contents in INI file format."</js>)
-               }
-       )
-       <jk>public</jk> ConfigFile setConfigContents(<ja>@Body</ja> Reader 
contents) <jk>throws</jk> Exception {
-               
-               <jc>// Create a new in-memory config file based on the contents 
of the HTTP request.</jc>
-               ConfigFile cf2 = new ConfigFileBuilder.build().load(contents);
-               
-               <jc>// Merge the in-memory config file into the existing config 
file and save it.
-               // Then return the modified config file to be parsed as a 
POJO.</jc>
-               <jk>return</jk> getConfig().merge(cf2).save();
-       }
-               </p-->
+                       <jc>// Create a transient config.</jc>
+                       Config c = 
Config.<jsm>create</jsm>().name(<js>"MyConfig.cfg"</js>).build();
+                       
+                       <jc>// Do stuff with it.</jc>
+                       
+                       <jc>// Then close the config to unregister the 
listeners.</jc>
+                       c.close();
+               </p>
        </div>
-       
+
 </div>
 
 <!-- 
===========================================================================================================
 -->

-- 
To stop receiving notification emails like this one, please contact
[email protected].

Reply via email to