diff --git a/config/src/main/java/com/typesafe/config/impl/AbstractConfigObject.java b/config/src/main/java/com/typesafe/config/impl/AbstractConfigObject.java index 0d8b07dd..54e2c09b 100644 --- a/config/src/main/java/com/typesafe/config/impl/AbstractConfigObject.java +++ b/config/src/main/java/com/typesafe/config/impl/AbstractConfigObject.java @@ -57,7 +57,7 @@ abstract class AbstractConfigObject extends AbstractConfigValue implements Confi * @param key * @return the unmodified raw value or null */ - protected final AbstractConfigValue peekAssumingResolved(String key, String originalPath) { + protected final AbstractConfigValue peekAssumingResolved(String key, Path originalPath) { try { return attemptPeekWithPartialResolve(key); } catch (ConfigException.NotResolved e) { @@ -138,7 +138,7 @@ abstract class AbstractConfigObject extends AbstractConfigValue implements Confi } } } catch (ConfigException.NotResolved e) { - throw ConfigImpl.improveNotResolved(path.render(), e); + throw ConfigImpl.improveNotResolved(path, e); } } diff --git a/config/src/main/java/com/typesafe/config/impl/ConfigImpl.java b/config/src/main/java/com/typesafe/config/impl/ConfigImpl.java index eac3cb45..3702174b 100644 --- a/config/src/main/java/com/typesafe/config/impl/ConfigImpl.java +++ b/config/src/main/java/com/typesafe/config/impl/ConfigImpl.java @@ -526,9 +526,10 @@ public class ConfigImpl { // toplevel error message. the "original" exception may however have extra // detail about what happened. call this if you have a better "what" than // further down on the stack. - static ConfigException.NotResolved improveNotResolved(String what, + static ConfigException.NotResolved improveNotResolved(Path what, ConfigException.NotResolved original) { - String newMessage = what + " has not been resolved, you need to call Config#resolve()," + String newMessage = what.render() + + " has not been resolved, you need to call Config#resolve()," + " see API docs for Config#resolve()"; if (newMessage.equals(original.getMessage())) return original; diff --git a/config/src/main/java/com/typesafe/config/impl/Path.java b/config/src/main/java/com/typesafe/config/impl/Path.java index fbbe1e08..2b283465 100644 --- a/config/src/main/java/com/typesafe/config/impl/Path.java +++ b/config/src/main/java/com/typesafe/config/impl/Path.java @@ -123,6 +123,23 @@ final class Path implements Serializable { return p; } + Path subPath(int firstIndex, int lastIndex) { + if (lastIndex < firstIndex) + throw new ConfigException.BugOrBroken("bad call to subPath"); + + Path from = subPath(firstIndex); + PathBuilder pb = new PathBuilder(); + int count = lastIndex - firstIndex; + while (count > 0) { + count -= 1; + pb.appendKey(from.first()); + from = from.remainder(); + if (from == null) + throw new ConfigException.BugOrBroken("subPath lastIndex out of range " + lastIndex); + } + return pb.result(); + } + @Override public boolean equals(Object other) { if (other instanceof Path) { diff --git a/config/src/main/java/com/typesafe/config/impl/SimpleConfig.java b/config/src/main/java/com/typesafe/config/impl/SimpleConfig.java index 96238a3d..eb4c43cf 100644 --- a/config/src/main/java/com/typesafe/config/impl/SimpleConfig.java +++ b/config/src/main/java/com/typesafe/config/impl/SimpleConfig.java @@ -72,7 +72,7 @@ final class SimpleConfig implements Config, MergeableValue, Serializable { try { peeked = object.peekPath(path); } catch (ConfigException.NotResolved e) { - throw ConfigImpl.improveNotResolved(pathExpression, e); + throw ConfigImpl.improveNotResolved(path, e); } return peeked != null && peeked.valueType() != ConfigValueType.NULL; } @@ -107,33 +107,27 @@ final class SimpleConfig implements Config, MergeableValue, Serializable { return entries; } - static private AbstractConfigValue find(AbstractConfigObject self, - String pathExpression, ConfigValueType expected, String originalPath) { - Path path = Path.newPath(pathExpression); - return find(self, path, expected, originalPath); - } - static private AbstractConfigValue findKey(AbstractConfigObject self, String key, - ConfigValueType expected, String originalPath) { + ConfigValueType expected, Path originalPath) { AbstractConfigValue v = self.peekAssumingResolved(key, originalPath); if (v == null) - throw new ConfigException.Missing(originalPath); + throw new ConfigException.Missing(originalPath.render()); if (expected != null) v = DefaultTransformer.transform(v, expected); if (v.valueType() == ConfigValueType.NULL) - throw new ConfigException.Null(v.origin(), originalPath, + throw new ConfigException.Null(v.origin(), originalPath.render(), expected != null ? expected.name() : null); else if (expected != null && v.valueType() != expected) - throw new ConfigException.WrongType(v.origin(), originalPath, expected.name(), v - .valueType().name()); + throw new ConfigException.WrongType(v.origin(), originalPath.render(), expected.name(), + v.valueType().name()); else return v; } static private AbstractConfigValue find(AbstractConfigObject self, Path path, - ConfigValueType expected, String originalPath) { + ConfigValueType expected, Path originalPath) { try { String key = path.first(); Path next = path.remainder(); @@ -141,33 +135,38 @@ final class SimpleConfig implements Config, MergeableValue, Serializable { return findKey(self, key, expected, originalPath); } else { AbstractConfigObject o = (AbstractConfigObject) findKey(self, key, - ConfigValueType.OBJECT, originalPath); + ConfigValueType.OBJECT, + originalPath.subPath(0, originalPath.length() - next.length())); assert (o != null); // missing was supposed to throw return find(o, next, expected, originalPath); } } catch (ConfigException.NotResolved e) { - throw ConfigImpl.improveNotResolved(path.render(), e); + throw ConfigImpl.improveNotResolved(path, e); } } - AbstractConfigValue find(String pathExpression, ConfigValueType expected, - String originalPath) { + AbstractConfigValue find(Path pathExpression, ConfigValueType expected, Path originalPath) { return find(object, pathExpression, expected, originalPath); } + AbstractConfigValue find(String pathExpression, ConfigValueType expected) { + Path path = Path.newPath(pathExpression); + return find(path, expected, path); + } + @Override public AbstractConfigValue getValue(String path) { - return find(path, null, path); + return find(path, null); } @Override public boolean getBoolean(String path) { - ConfigValue v = find(path, ConfigValueType.BOOLEAN, path); + ConfigValue v = find(path, ConfigValueType.BOOLEAN); return (Boolean) v.unwrapped(); } private ConfigNumber getConfigNumber(String path) { - ConfigValue v = find(path, ConfigValueType.NUMBER, path); + ConfigValue v = find(path, ConfigValueType.NUMBER); return (ConfigNumber) v; } @@ -194,20 +193,19 @@ final class SimpleConfig implements Config, MergeableValue, Serializable { @Override public String getString(String path) { - ConfigValue v = find(path, ConfigValueType.STRING, path); + ConfigValue v = find(path, ConfigValueType.STRING); return (String) v.unwrapped(); } @Override public ConfigList getList(String path) { - AbstractConfigValue v = find(path, ConfigValueType.LIST, path); + AbstractConfigValue v = find(path, ConfigValueType.LIST); return (ConfigList) v; } @Override public AbstractConfigObject getObject(String path) { - AbstractConfigObject obj = (AbstractConfigObject) find(path, - ConfigValueType.OBJECT, path); + AbstractConfigObject obj = (AbstractConfigObject) find(path, ConfigValueType.OBJECT); return obj; } @@ -218,7 +216,7 @@ final class SimpleConfig implements Config, MergeableValue, Serializable { @Override public Object getAnyRef(String path) { - ConfigValue v = find(path, null, path); + ConfigValue v = find(path, null); return v.unwrapped(); } @@ -228,7 +226,7 @@ final class SimpleConfig implements Config, MergeableValue, Serializable { try { size = getLong(path); } catch (ConfigException.WrongType e) { - ConfigValue v = find(path, ConfigValueType.STRING, path); + ConfigValue v = find(path, ConfigValueType.STRING); size = parseBytes((String) v.unwrapped(), v.origin(), path); } @@ -248,7 +246,7 @@ final class SimpleConfig implements Config, MergeableValue, Serializable { try { ns = TimeUnit.MILLISECONDS.toNanos(getLong(path)); } catch (ConfigException.WrongType e) { - ConfigValue v = find(path, ConfigValueType.STRING, path); + ConfigValue v = find(path, ConfigValueType.STRING); ns = parseDuration((String) v.unwrapped(), v.origin(), path); } return ns;