From 48ecd996e8e45dd8144079df4b08aed85894d189 Mon Sep 17 00:00:00 2001 From: Ryan O'Neill Date: Tue, 11 Aug 2015 14:36:10 -0700 Subject: [PATCH] conditional base classes --- .../config/impl/ConfigConditional.java | 20 +++++++------- .../typesafe/config/impl/ConfigParser.java | 2 +- .../typesafe/config/impl/ResolveStatus.java | 4 ++- .../config/impl/SimpleConfigList.java | 5 ++-- .../config/impl/SimpleConfigObject.java | 27 ++++++++++++------- 5 files changed, 35 insertions(+), 23 deletions(-) diff --git a/config/src/main/java/com/typesafe/config/impl/ConfigConditional.java b/config/src/main/java/com/typesafe/config/impl/ConfigConditional.java index b187a9c1..d53b1bd9 100644 --- a/config/src/main/java/com/typesafe/config/impl/ConfigConditional.java +++ b/config/src/main/java/com/typesafe/config/impl/ConfigConditional.java @@ -20,15 +20,17 @@ public class ConfigConditional { } } - public SimpleConfigObject resolve(Map values) { - AbstractConfigValue val = values.get(left.path().first()); - if (val == null) { - throw new ConfigException.BugOrBroken("Could not resolve substitution " + this.left.toString() + " in conditional expression"); - } - if (val.equals(this.right)) { - return this.body; - } else { - return null; + public SimpleConfigObject resolve(ResolveContext context, ResolveSource source) { + try { + AbstractConfigValue val = source.lookupSubst(context, this.left, 0).result.value; + + if (val.equals(this.right)) { + return this.body; + } else { + return SimpleConfigObject.empty(); + } + } catch (AbstractConfigValue.NotPossibleToResolve e){ + throw new ConfigException.BugOrBroken("Could not resolve left side of conditional expression: " + this.left.toString()); } } } diff --git a/config/src/main/java/com/typesafe/config/impl/ConfigParser.java b/config/src/main/java/com/typesafe/config/impl/ConfigParser.java index 01791c4c..d63bc5ee 100644 --- a/config/src/main/java/com/typesafe/config/impl/ConfigParser.java +++ b/config/src/main/java/com/typesafe/config/impl/ConfigParser.java @@ -338,7 +338,7 @@ final class ConfigParser { } } - return new SimpleConfigObject(objectOrigin, values); + return new SimpleConfigObject(objectOrigin, values, conditionals); } private SimpleConfigList parseArray(ConfigNodeArray n) { diff --git a/config/src/main/java/com/typesafe/config/impl/ResolveStatus.java b/config/src/main/java/com/typesafe/config/impl/ResolveStatus.java index 8deeaf52..96fd5625 100644 --- a/config/src/main/java/com/typesafe/config/impl/ResolveStatus.java +++ b/config/src/main/java/com/typesafe/config/impl/ResolveStatus.java @@ -12,11 +12,13 @@ enum ResolveStatus { UNRESOLVED, RESOLVED; final static ResolveStatus fromValues( - Collection values) { + Collection values, Collection conditionals) { for (AbstractConfigValue v : values) { if (v.resolveStatus() == ResolveStatus.UNRESOLVED) return ResolveStatus.UNRESOLVED; } + if (conditionals.size() > 0) + return ResolveStatus.UNRESOLVED; return ResolveStatus.RESOLVED; } diff --git a/config/src/main/java/com/typesafe/config/impl/SimpleConfigList.java b/config/src/main/java/com/typesafe/config/impl/SimpleConfigList.java index a8d8e366..31f088f6 100644 --- a/config/src/main/java/com/typesafe/config/impl/SimpleConfigList.java +++ b/config/src/main/java/com/typesafe/config/impl/SimpleConfigList.java @@ -26,8 +26,7 @@ final class SimpleConfigList extends AbstractConfigValue implements ConfigList, final private boolean resolved; SimpleConfigList(ConfigOrigin origin, List value) { - this(origin, value, ResolveStatus - .fromValues(value)); + this(origin, value, ResolveStatus.fromValues(value, new ArrayList())); } SimpleConfigList(ConfigOrigin origin, List value, @@ -37,7 +36,7 @@ final class SimpleConfigList extends AbstractConfigValue implements ConfigList, this.resolved = status == ResolveStatus.RESOLVED; // kind of an expensive debug check (makes this constructor pointless) - if (status != ResolveStatus.fromValues(value)) + if (status != ResolveStatus.fromValues(value, new ArrayList())) throw new ConfigException.BugOrBroken( "SimpleConfigList created with wrong resolve status: " + this); } diff --git a/config/src/main/java/com/typesafe/config/impl/SimpleConfigObject.java b/config/src/main/java/com/typesafe/config/impl/SimpleConfigObject.java index 9c92463c..01717cec 100644 --- a/config/src/main/java/com/typesafe/config/impl/SimpleConfigObject.java +++ b/config/src/main/java/com/typesafe/config/impl/SimpleConfigObject.java @@ -47,7 +47,7 @@ final class SimpleConfigObject extends AbstractConfigObject implements Serializa this.conditionals = conditionals; // Kind of an expensive debug check. Comment out? - if (status != ResolveStatus.fromValues(value.values())) + if (status != ResolveStatus.fromValues(value.values(), conditionals)) throw new ConfigException.BugOrBroken("Wrong resolved status on " + this); } @@ -60,13 +60,13 @@ final class SimpleConfigObject extends AbstractConfigObject implements Serializa SimpleConfigObject(ConfigOrigin origin, Map value) { - this(origin, value, ResolveStatus.fromValues(value.values()), false /* ignoresFallbacks */, new ArrayList()); + this(origin, value, ResolveStatus.fromValues(value.values(), new ArrayList()), false /* ignoresFallbacks */, new ArrayList()); } SimpleConfigObject(ConfigOrigin origin, Map value, List conditionals) { - this(origin, value, ResolveStatus.fromValues(value.values()), false /* ignoresFallbacks */, conditionals); + this(origin, value, ResolveStatus.fromValues(value.values(), conditionals), false /* ignoresFallbacks */, conditionals); } @Override @@ -131,8 +131,8 @@ final class SimpleConfigObject extends AbstractConfigObject implements Serializa Map updated = new HashMap( value); updated.put(key, v); - return new SimpleConfigObject(origin(), updated, ResolveStatus.fromValues(updated - .values()), ignoresFallbacks); + return new SimpleConfigObject(origin(), updated, + ResolveStatus.fromValues(updated.values(), conditionals), ignoresFallbacks); } else if (next != null || v == null) { // can't descend, nothing to remove return this; @@ -143,8 +143,8 @@ final class SimpleConfigObject extends AbstractConfigObject implements Serializa if (!old.getKey().equals(key)) smaller.put(old.getKey(), old.getValue()); } - return new SimpleConfigObject(origin(), smaller, ResolveStatus.fromValues(smaller - .values()), ignoresFallbacks); + return new SimpleConfigObject(origin(), smaller, + ResolveStatus.fromValues(smaller.values(), conditionals), ignoresFallbacks); } } @@ -162,7 +162,7 @@ final class SimpleConfigObject extends AbstractConfigObject implements Serializa newMap.put(key, (AbstractConfigValue) v); } - return new SimpleConfigObject(origin(), newMap, ResolveStatus.fromValues(newMap.values()), + return new SimpleConfigObject(origin(), newMap, ResolveStatus.fromValues(newMap.values(), conditionals), ignoresFallbacks); } @@ -225,7 +225,7 @@ final class SimpleConfigObject extends AbstractConfigObject implements Serializa else newChildren.remove(old.getKey()); - return new SimpleConfigObject(origin(), newChildren, ResolveStatus.fromValues(newChildren.values()), + return new SimpleConfigObject(origin(), newChildren, ResolveStatus.fromValues(newChildren.values(), conditionals), ignoresFallbacks); } } @@ -322,6 +322,7 @@ final class SimpleConfigObject extends AbstractConfigObject implements Serializa private SimpleConfigObject modifyMayThrow(Modifier modifier) throws Exception { Map changes = null; + for (String k : keySet()) { AbstractConfigValue v = value.get(k); // "modified" may be null, which means remove the child; @@ -413,6 +414,14 @@ final class SimpleConfigObject extends AbstractConfigObject implements Serializa ResolveModifier modifier = new ResolveModifier(context, sourceWithParent); AbstractConfigValue value = modifyMayThrow(modifier); + + for (ConfigConditional cond: this.conditionals) { + SimpleConfigObject body = cond.resolve(context, sourceWithParent); + AbstractConfigObject resolvedBody = body.resolveSubstitutions(context, source).value; + value = this.mergedWithObject(resolvedBody); + } + this.conditionals.clear(); + return ResolveResult.make(modifier.context, value).asObjectResult(); } catch (NotPossibleToResolve e) { throw e;