do a better job with origin when there's an empty config. add Config.empty().

This commit is contained in:
Havoc Pennington 2011-11-14 10:26:53 -05:00
parent 54cd4ec3dd
commit 9b3efbd2d0
5 changed files with 69 additions and 8 deletions

View File

@ -69,6 +69,10 @@ public final class Config {
return ConfigImpl.emptyRoot(rootPath);
}
public static ConfigObject empty() {
return ConfigImpl.empty();
}
public static ConfigRoot systemPropertiesRoot(String rootPath) {
return ConfigImpl.systemPropertiesRoot(rootPath);
}

View File

@ -233,18 +233,39 @@ abstract class AbstractConfigObject extends AbstractConfigValue implements
if (stack.isEmpty())
throw new ConfigException.BugOrBroken(
"can't merge origins on empty list");
final String prefix = "merge of ";
StringBuilder sb = new StringBuilder();
String prefix = "merge of ";
sb.append(prefix);
ConfigOrigin firstOrigin = null;
int numMerged = 0;
for (AbstractConfigValue v : stack) {
if (firstOrigin == null)
firstOrigin = v.origin();
String desc = v.origin().description();
if (desc.startsWith(prefix))
desc = desc.substring(prefix.length());
sb.append(desc);
sb.append(",");
if (v instanceof ConfigObject && ((ConfigObject) v).isEmpty()) {
// don't include empty files or the .empty()
// config in the description, since they are
// likely to be "implementation details"
} else {
sb.append(desc);
sb.append(",");
numMerged += 1;
}
}
if (numMerged > 0) {
sb.setLength(sb.length() - 1); // chop comma
if (numMerged > 1) {
return new SimpleConfigOrigin(prefix + sb.toString());
} else {
return new SimpleConfigOrigin(sb.toString());
}
} else {
// the configs were all empty.
return firstOrigin;
}
sb.setLength(sb.length() - 1); // chop comma
return new SimpleConfigOrigin(sb.toString());
}
static ConfigOrigin mergeOrigins(AbstractConfigObject... stack) {

View File

@ -160,7 +160,13 @@ public class ConfigImpl {
/** For use ONLY by library internals, DO NOT TOUCH not guaranteed ABI */
public static ConfigRoot emptyRoot(String rootPath) {
return SimpleConfigObject.empty().asRoot(Parser.parsePath(rootPath));
return SimpleConfigObject.empty(new SimpleConfigOrigin(rootPath))
.asRoot(
Parser.parsePath(rootPath));
}
public static ConfigObject empty() {
return SimpleConfigObject.empty();
}
/** For use ONLY by library internals, DO NOT TOUCH not guaranteed ABI */

View File

@ -113,8 +113,10 @@ final class SimpleConfigObject extends AbstractConfigObject {
return new HashSet<ConfigValue>(value.values());
}
final static String EMPTY_NAME = "empty config";
final static SimpleConfigObject empty() {
return new SimpleConfigObject(new SimpleConfigOrigin("empty config"),
return new SimpleConfigObject(new SimpleConfigOrigin(EMPTY_NAME),
Collections.<String, AbstractConfigValue> emptyMap());
}

View File

@ -9,6 +9,7 @@ import com.typesafe.config.ConfigObject
import com.typesafe.config.ConfigList
import com.typesafe.config.ConfigException
import com.typesafe.config.ConfigValueType
import com.typesafe.config.ConfigOrigin
class ConfigValueTest extends TestUtils {
@ -330,4 +331,31 @@ class ConfigValueTest extends TestUtils {
assertEquals(Seq(a, b, c, d) map { "xx " + _ + " yy" },
Seq("a", "b", "c", "d") map { obj2.getString(_) })
}
@Test
def mergeOriginsWorks() {
def o(desc: String, empty: Boolean) = {
val values = new java.util.HashMap[String, AbstractConfigValue]()
if (!empty)
values.put("hello", intValue(37))
new SimpleConfigObject(new SimpleConfigOrigin(desc), values);
}
def m(values: AbstractConfigObject*) = {
AbstractConfigObject.mergeOrigins(values: _*).description()
}
// simplest case
assertEquals("merge of a,b", m(o("a", false), o("b", false)))
// combine duplicate "merge of"
assertEquals("merge of a,x,y", m(o("a", false), o("merge of x,y", false)))
assertEquals("merge of a,b,x,y", m(o("merge of a,b", false), o("merge of x,y", false)))
// ignore empty objects
assertEquals("a", m(o("foo", true), o("a", false)))
// unless they are all empty, pick the first one
assertEquals("foo", m(o("foo", true), o("a", true)))
// merge just one
assertEquals("foo", m(o("foo", false)))
// merge three
assertEquals("merge of a,b,c", m(o("a", false), o("b", false), o("c", false)))
}
}