Latest config lib
This commit is contained in:
parent
a9217cec7b
commit
b8be8f3869
50 changed files with 449 additions and 246 deletions
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config;
|
||||
|
||||
import java.util.List;
|
||||
|
|
@ -53,9 +56,6 @@ public interface Config extends ConfigMergeable {
|
|||
@Override
|
||||
Config withFallback(ConfigMergeable other);
|
||||
|
||||
@Override
|
||||
Config withFallbacks(ConfigMergeable... others);
|
||||
|
||||
@Override
|
||||
ConfigObject toValue();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config;
|
||||
|
||||
import java.io.File;
|
||||
|
|
@ -74,7 +77,7 @@ public final class ConfigFactory {
|
|||
Config referenceFiles = parseResourcesForPath(rootPath + ".reference",
|
||||
options);
|
||||
|
||||
return system.withFallbacks(mainFiles, referenceFiles);
|
||||
return system.withFallback(mainFiles).withFallback(referenceFiles);
|
||||
}
|
||||
|
||||
public static ConfigRoot emptyRoot(String rootPath) {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config;
|
||||
|
||||
import java.util.List;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config;
|
||||
|
||||
/**
|
||||
|
|
@ -18,35 +21,16 @@ public interface ConfigMergeable {
|
|||
* Config instances do anything in this method (they need to merge the
|
||||
* fallback keys into themselves). All other values just return the original
|
||||
* value, since they automatically override any fallback.
|
||||
*
|
||||
*
|
||||
* The semantics of merging are described in
|
||||
* https://github.com/havocp/config/blob/master/HOCON.md
|
||||
*
|
||||
* Prefer <code>withFallbacks()</code>, listing all your fallbacks at once,
|
||||
* over this method.
|
||||
*
|
||||
* <i>When using this method, there is an easy way to write a wrong
|
||||
* loop.</i> Even if you don't loop, it's easy to do the equivalent wrong
|
||||
* thing.
|
||||
*
|
||||
* <code>
|
||||
* // WRONG
|
||||
* for (ConfigMergeable fallback : fallbacks) {
|
||||
* // DO NOT DO THIS
|
||||
* result = result.withFallback(fallback);
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* This is wrong because when <code>result</code> is an object and
|
||||
* <code>fallback</code> is a non-object,
|
||||
* <code>result.withFallback(fallback)</code> returns an object. Then if
|
||||
* there are more objects, they are merged into that object. But the correct
|
||||
* semantics are that a non-object will block merging any more objects later
|
||||
* in the list. To get it right, you need to iterate backward. Simplest
|
||||
* solution: prefer <code>withFallbacks()</code> which is harder to get
|
||||
* wrong, and merge all your fallbacks in one call to
|
||||
* <code>withFallbacks()</code>.
|
||||
*
|
||||
*
|
||||
* Note that objects do not merge "across" non-objects; if you do
|
||||
* <code>object.withFallback(nonObject).withFallback(otherObject)</code>,
|
||||
* then <code>otherObject</code> will simply be ignored. This is an
|
||||
* intentional part of how merging works. Both non-objects, and any object
|
||||
* which has fallen back to a non-object, block subsequent fallbacks.
|
||||
*
|
||||
* @param other
|
||||
* an object whose keys should be used if the keys are not
|
||||
* present in this one
|
||||
|
|
@ -54,14 +38,4 @@ public interface ConfigMergeable {
|
|||
* used)
|
||||
*/
|
||||
ConfigMergeable withFallback(ConfigMergeable other);
|
||||
|
||||
/**
|
||||
* Convenience method just calls withFallback() on each of the values;
|
||||
* earlier values in the list win over later ones. The semantics of merging
|
||||
* are described in https://github.com/havocp/config/blob/master/HOCON.md
|
||||
*
|
||||
* @param fallbacks
|
||||
* @return a version of the object with the requested fallbacks merged in
|
||||
*/
|
||||
ConfigMergeable withFallbacks(ConfigMergeable... others);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config;
|
||||
|
||||
import java.util.Map;
|
||||
|
|
@ -58,9 +61,6 @@ public interface ConfigObject extends ConfigValue, Map<String, ConfigValue> {
|
|||
@Override
|
||||
ConfigObject withFallback(ConfigMergeable other);
|
||||
|
||||
@Override
|
||||
ConfigObject withFallbacks(ConfigMergeable... others);
|
||||
|
||||
/**
|
||||
* Gets a ConfigValue at the given key, or returns null if there is no
|
||||
* value. The returned ConfigValue may have ConfigValueType.NULL or any
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config;
|
||||
|
||||
import java.net.URL;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config;
|
||||
|
||||
public final class ConfigResolveOptions {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config;
|
||||
|
||||
/**
|
||||
|
|
@ -21,9 +24,6 @@ public interface ConfigRoot extends Config {
|
|||
@Override
|
||||
ConfigRoot withFallback(ConfigMergeable fallback);
|
||||
|
||||
@Override
|
||||
ConfigRoot withFallbacks(ConfigMergeable... fallbacks);
|
||||
|
||||
/**
|
||||
* Gets the global app name that this root represents.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config;
|
||||
|
||||
public enum ConfigSyntax {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config;
|
||||
|
||||
/**
|
||||
|
|
@ -29,7 +32,4 @@ public interface ConfigValue extends ConfigMergeable {
|
|||
|
||||
@Override
|
||||
ConfigValue withFallback(ConfigMergeable other);
|
||||
|
||||
@Override
|
||||
ConfigValue withFallbacks(ConfigMergeable... fallbacks);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config;
|
||||
|
||||
import java.util.Collection;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -99,54 +102,61 @@ abstract class AbstractConfigObject extends AbstractConfigValue implements
|
|||
return ConfigValueType.OBJECT;
|
||||
}
|
||||
|
||||
protected abstract AbstractConfigObject newCopy(ResolveStatus status);
|
||||
protected abstract AbstractConfigObject newCopy(ResolveStatus status,
|
||||
boolean ignoresFallbacks);
|
||||
|
||||
@Override
|
||||
public AbstractConfigObject withFallbacks(ConfigMergeable... others) {
|
||||
return (AbstractConfigObject) super.withFallbacks(others);
|
||||
protected AbstractConfigObject newCopy(boolean ignoresFallbacks) {
|
||||
return newCopy(resolveStatus(), ignoresFallbacks);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final AbstractConfigObject mergedWithTheUnmergeable(Unmergeable fallback) {
|
||||
if (ignoresFallbacks())
|
||||
throw new ConfigException.BugOrBroken("should not be reached");
|
||||
|
||||
List<AbstractConfigValue> stack = new ArrayList<AbstractConfigValue>();
|
||||
if (this instanceof Unmergeable) {
|
||||
stack.addAll(((Unmergeable) this).unmergedValues());
|
||||
} else {
|
||||
stack.add(this);
|
||||
}
|
||||
stack.addAll(fallback.unmergedValues());
|
||||
return new ConfigDelayedMergeObject(mergeOrigins(stack), stack,
|
||||
((AbstractConfigValue) fallback).ignoresFallbacks());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractConfigObject mergedWithObject(AbstractConfigObject fallback) {
|
||||
if (ignoresFallbacks())
|
||||
throw new ConfigException.BugOrBroken("should not be reached");
|
||||
|
||||
boolean allResolved = true;
|
||||
Map<String, AbstractConfigValue> merged = new HashMap<String, AbstractConfigValue>();
|
||||
Set<String> allKeys = new HashSet<String>();
|
||||
allKeys.addAll(this.keySet());
|
||||
allKeys.addAll(fallback.keySet());
|
||||
for (String key : allKeys) {
|
||||
AbstractConfigValue first = this.peek(key);
|
||||
AbstractConfigValue second = fallback.peek(key);
|
||||
AbstractConfigValue kept;
|
||||
if (first == null)
|
||||
kept = second;
|
||||
else if (second == null)
|
||||
kept = first;
|
||||
else
|
||||
kept = first.withFallback(second);
|
||||
merged.put(key, kept);
|
||||
if (kept.resolveStatus() == ResolveStatus.UNRESOLVED)
|
||||
allResolved = false;
|
||||
}
|
||||
return new SimpleConfigObject(mergeOrigins(this, fallback), merged,
|
||||
ResolveStatus.fromBoolean(allResolved), fallback.ignoresFallbacks());
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractConfigObject withFallback(ConfigMergeable mergeable) {
|
||||
ConfigValue other = mergeable.toValue();
|
||||
|
||||
if (other instanceof Unmergeable) {
|
||||
List<AbstractConfigValue> stack = new ArrayList<AbstractConfigValue>();
|
||||
stack.add(this);
|
||||
stack.addAll(((Unmergeable) other).unmergedValues());
|
||||
return new ConfigDelayedMergeObject(mergeOrigins(stack), stack);
|
||||
} else if (other instanceof AbstractConfigObject) {
|
||||
AbstractConfigObject fallback = (AbstractConfigObject) other;
|
||||
if (fallback.isEmpty()) {
|
||||
return this; // nothing to do
|
||||
} else {
|
||||
boolean allResolved = true;
|
||||
Map<String, AbstractConfigValue> merged = new HashMap<String, AbstractConfigValue>();
|
||||
Set<String> allKeys = new HashSet<String>();
|
||||
allKeys.addAll(this.keySet());
|
||||
allKeys.addAll(fallback.keySet());
|
||||
for (String key : allKeys) {
|
||||
AbstractConfigValue first = this.peek(key);
|
||||
AbstractConfigValue second = fallback.peek(key);
|
||||
AbstractConfigValue kept;
|
||||
if (first == null)
|
||||
kept = second;
|
||||
else if (second == null)
|
||||
kept = first;
|
||||
else
|
||||
kept = first.withFallback(second);
|
||||
merged.put(key, kept);
|
||||
if (kept.resolveStatus() == ResolveStatus.UNRESOLVED)
|
||||
allResolved = false;
|
||||
}
|
||||
return new SimpleConfigObject(mergeOrigins(this, fallback),
|
||||
merged, ResolveStatus.fromBoolean(allResolved));
|
||||
}
|
||||
} else {
|
||||
// falling back to a non-object has no effect, we just override
|
||||
// primitive values.
|
||||
return this;
|
||||
}
|
||||
return (AbstractConfigObject) super.withFallback(mergeable);
|
||||
}
|
||||
|
||||
static ConfigOrigin mergeOrigins(
|
||||
|
|
@ -166,7 +176,9 @@ abstract class AbstractConfigObject extends AbstractConfigValue implements
|
|||
if (desc.startsWith(prefix))
|
||||
desc = desc.substring(prefix.length());
|
||||
|
||||
if (v instanceof ConfigObject && ((ConfigObject) v).isEmpty()) {
|
||||
if (v instanceof AbstractConfigObject
|
||||
&& ((AbstractConfigObject) v).resolveStatus() == ResolveStatus.RESOLVED
|
||||
&& ((ConfigObject) v).isEmpty()) {
|
||||
// don't include empty files or the .empty()
|
||||
// config in the description, since they are
|
||||
// likely to be "implementation details"
|
||||
|
|
@ -206,7 +218,7 @@ abstract class AbstractConfigObject extends AbstractConfigValue implements
|
|||
}
|
||||
}
|
||||
if (changes == null) {
|
||||
return newCopy(newResolveStatus);
|
||||
return newCopy(newResolveStatus, ignoresFallbacks());
|
||||
} else {
|
||||
Map<String, AbstractConfigValue> modified = new HashMap<String, AbstractConfigValue>();
|
||||
for (String k : keySet()) {
|
||||
|
|
@ -216,8 +228,8 @@ abstract class AbstractConfigObject extends AbstractConfigValue implements
|
|||
modified.put(k, peek(k));
|
||||
}
|
||||
}
|
||||
return new SimpleConfigObject(origin(), modified,
|
||||
newResolveStatus);
|
||||
return new SimpleConfigObject(origin(), modified, newResolveStatus,
|
||||
ignoresFallbacks());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -311,7 +323,8 @@ abstract class AbstractConfigObject extends AbstractConfigValue implements
|
|||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
// note that "origin" is deliberately NOT part of equality
|
||||
// note that "origin" is deliberately NOT part of equality.
|
||||
// neither are other "extras" like ignoresFallbacks or resolve status.
|
||||
if (other instanceof ConfigObject) {
|
||||
// optimization to avoid unwrapped() for two ConfigObject,
|
||||
// which is what AbstractConfigValue does.
|
||||
|
|
@ -324,6 +337,7 @@ abstract class AbstractConfigObject extends AbstractConfigValue implements
|
|||
@Override
|
||||
public int hashCode() {
|
||||
// note that "origin" is deliberately NOT part of equality
|
||||
// neither are other "extras" like ignoresFallbacks or resolve status.
|
||||
return mapHash(this);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config.impl;
|
||||
|
||||
import com.typesafe.config.ConfigException;
|
||||
import com.typesafe.config.ConfigMergeable;
|
||||
import com.typesafe.config.ConfigOrigin;
|
||||
import com.typesafe.config.ConfigResolveOptions;
|
||||
|
|
@ -72,17 +76,61 @@ abstract class AbstractConfigValue implements ConfigValue {
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractConfigValue withFallback(ConfigMergeable other) {
|
||||
protected AbstractConfigValue newCopy(boolean ignoresFallbacks) {
|
||||
return this;
|
||||
}
|
||||
|
||||
// this is virtualized rather than a field because only some subclasses
|
||||
// really need to store the boolean, and they may be able to pack it
|
||||
// with another boolean to save space.
|
||||
protected boolean ignoresFallbacks() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private ConfigException badMergeException() {
|
||||
if (ignoresFallbacks())
|
||||
throw new ConfigException.BugOrBroken(
|
||||
"method should not have been called with ignoresFallbacks=true"
|
||||
+ getClass().getSimpleName());
|
||||
else
|
||||
throw new ConfigException.BugOrBroken("should override this in "
|
||||
+ getClass().getSimpleName());
|
||||
}
|
||||
|
||||
protected AbstractConfigValue mergedWithTheUnmergeable(Unmergeable fallback) {
|
||||
throw badMergeException();
|
||||
}
|
||||
|
||||
protected AbstractConfigValue mergedWithObject(AbstractConfigObject fallback) {
|
||||
throw badMergeException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractConfigValue withFallbacks(ConfigMergeable... fallbacks) {
|
||||
// note: this is a no-op unless the subclass overrides withFallback().
|
||||
// But we need to do this because subclass withFallback() may not
|
||||
// just "return this"
|
||||
return ConfigImpl.merge(AbstractConfigValue.class, this, fallbacks);
|
||||
public AbstractConfigValue withFallback(ConfigMergeable mergeable) {
|
||||
if (ignoresFallbacks()) {
|
||||
return this;
|
||||
} else {
|
||||
ConfigValue other = mergeable.toValue();
|
||||
|
||||
if (other instanceof Unmergeable) {
|
||||
return mergedWithTheUnmergeable((Unmergeable) other);
|
||||
} else if (other instanceof AbstractConfigObject) {
|
||||
AbstractConfigObject fallback = (AbstractConfigObject) other;
|
||||
if (fallback.resolveStatus() == ResolveStatus.RESOLVED && fallback.isEmpty()) {
|
||||
if (fallback.ignoresFallbacks())
|
||||
return newCopy(true /* ignoresFallbacks */);
|
||||
else
|
||||
return this;
|
||||
} else {
|
||||
return mergedWithObject((AbstractConfigObject) other);
|
||||
}
|
||||
} else {
|
||||
// falling back to a non-object doesn't merge anything, and also
|
||||
// prohibits merging any objects that we fall back to later.
|
||||
// so we have to switch to ignoresFallbacks mode.
|
||||
return newCopy(true /* ignoresFallbacks */);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean canEqual(Object other) {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config.impl;
|
||||
|
||||
import com.typesafe.config.ConfigOrigin;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -5,10 +8,8 @@ import java.util.Collection;
|
|||
import java.util.List;
|
||||
|
||||
import com.typesafe.config.ConfigException;
|
||||
import com.typesafe.config.ConfigMergeable;
|
||||
import com.typesafe.config.ConfigOrigin;
|
||||
import com.typesafe.config.ConfigResolveOptions;
|
||||
import com.typesafe.config.ConfigValue;
|
||||
import com.typesafe.config.ConfigValueType;
|
||||
|
||||
/**
|
||||
|
|
@ -24,14 +25,26 @@ final class ConfigDelayedMerge extends AbstractConfigValue implements
|
|||
|
||||
// earlier items in the stack win
|
||||
final private List<AbstractConfigValue> stack;
|
||||
final private boolean ignoresFallbacks;
|
||||
|
||||
ConfigDelayedMerge(ConfigOrigin origin, List<AbstractConfigValue> stack) {
|
||||
ConfigDelayedMerge(ConfigOrigin origin, List<AbstractConfigValue> stack,
|
||||
boolean ignoresFallbacks) {
|
||||
super(origin);
|
||||
this.stack = stack;
|
||||
this.ignoresFallbacks = ignoresFallbacks;
|
||||
if (stack.isEmpty())
|
||||
throw new ConfigException.BugOrBroken(
|
||||
"creating empty delayed merge value");
|
||||
|
||||
for (AbstractConfigValue v : stack) {
|
||||
if (v instanceof ConfigDelayedMerge || v instanceof ConfigDelayedMergeObject)
|
||||
throw new ConfigException.BugOrBroken(
|
||||
"placed nested DelayedMerge in a ConfigDelayedMerge, should have consolidated stack");
|
||||
}
|
||||
}
|
||||
|
||||
ConfigDelayedMerge(ConfigOrigin origin, List<AbstractConfigValue> stack) {
|
||||
this(origin, stack, false /* ignoresFallbacks */);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -57,18 +70,19 @@ final class ConfigDelayedMerge extends AbstractConfigValue implements
|
|||
List<AbstractConfigValue> stack, SubstitutionResolver resolver,
|
||||
int depth, ConfigResolveOptions options) {
|
||||
// to resolve substitutions, we need to recursively resolve
|
||||
// the stack of stuff to merge, and then merge the stack.
|
||||
List<AbstractConfigValue> toMerge = new ArrayList<AbstractConfigValue>();
|
||||
// the stack of stuff to merge, and merge the stack so
|
||||
// we won't be a delayed merge anymore.
|
||||
|
||||
AbstractConfigValue merged = null;
|
||||
for (AbstractConfigValue v : stack) {
|
||||
AbstractConfigValue resolved = resolver.resolve(v, depth, options);
|
||||
toMerge.add(resolved);
|
||||
if (merged == null)
|
||||
merged = resolved;
|
||||
else
|
||||
merged = merged.withFallback(resolved);
|
||||
}
|
||||
|
||||
// we shouldn't have a delayed merge object with an empty stack, so
|
||||
// it should be safe to ignore the toMerge.isEmpty case.
|
||||
return ConfigImpl.merge(AbstractConfigValue.class, toMerge.get(0),
|
||||
toMerge.subList(1, toMerge.size()));
|
||||
return merged;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -82,30 +96,40 @@ final class ConfigDelayedMerge extends AbstractConfigValue implements
|
|||
for (AbstractConfigValue o : stack) {
|
||||
newStack.add(o.relativized(prefix));
|
||||
}
|
||||
return new ConfigDelayedMerge(origin(), newStack);
|
||||
return new ConfigDelayedMerge(origin(), newStack, ignoresFallbacks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractConfigValue withFallback(ConfigMergeable mergeable) {
|
||||
ConfigValue other = mergeable.toValue();
|
||||
protected boolean ignoresFallbacks() {
|
||||
return ignoresFallbacks;
|
||||
}
|
||||
|
||||
if (other instanceof AbstractConfigObject
|
||||
|| other instanceof Unmergeable) {
|
||||
// if we turn out to be an object, and the fallback also does,
|
||||
// then a merge may be required; delay until we resolve.
|
||||
List<AbstractConfigValue> newStack = new ArrayList<AbstractConfigValue>();
|
||||
newStack.addAll(stack);
|
||||
if (other instanceof Unmergeable)
|
||||
newStack.addAll(((Unmergeable) other).unmergedValues());
|
||||
else
|
||||
newStack.add((AbstractConfigValue) other);
|
||||
return new ConfigDelayedMerge(
|
||||
AbstractConfigObject.mergeOrigins(newStack), newStack);
|
||||
} else {
|
||||
// if the other is not an object, there won't be anything
|
||||
// to merge with, so we are it even if we are an object.
|
||||
return this;
|
||||
}
|
||||
@Override
|
||||
protected final ConfigDelayedMerge mergedWithTheUnmergeable(Unmergeable fallback) {
|
||||
if (ignoresFallbacks)
|
||||
throw new ConfigException.BugOrBroken("should not be reached");
|
||||
|
||||
// if we turn out to be an object, and the fallback also does,
|
||||
// then a merge may be required; delay until we resolve.
|
||||
List<AbstractConfigValue> newStack = new ArrayList<AbstractConfigValue>();
|
||||
newStack.addAll(stack);
|
||||
newStack.addAll(fallback.unmergedValues());
|
||||
return new ConfigDelayedMerge(AbstractConfigObject.mergeOrigins(newStack), newStack,
|
||||
((AbstractConfigValue) fallback).ignoresFallbacks());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final ConfigDelayedMerge mergedWithObject(AbstractConfigObject fallback) {
|
||||
if (ignoresFallbacks)
|
||||
throw new ConfigException.BugOrBroken("should not be reached");
|
||||
|
||||
// if we turn out to be an object, and the fallback also does,
|
||||
// then a merge may be required; delay until we resolve.
|
||||
List<AbstractConfigValue> newStack = new ArrayList<AbstractConfigValue>();
|
||||
newStack.addAll(stack);
|
||||
newStack.add(fallback);
|
||||
return new ConfigDelayedMerge(AbstractConfigObject.mergeOrigins(newStack), newStack,
|
||||
fallback.ignoresFallbacks());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -18,25 +21,40 @@ class ConfigDelayedMergeObject extends AbstractConfigObject implements
|
|||
Unmergeable {
|
||||
|
||||
final private List<AbstractConfigValue> stack;
|
||||
final private boolean ignoresFallbacks;
|
||||
|
||||
ConfigDelayedMergeObject(ConfigOrigin origin,
|
||||
List<AbstractConfigValue> stack) {
|
||||
this(origin, stack, false /* ignoresFallbacks */);
|
||||
}
|
||||
|
||||
ConfigDelayedMergeObject(ConfigOrigin origin, List<AbstractConfigValue> stack,
|
||||
boolean ignoresFallbacks) {
|
||||
super(origin);
|
||||
this.stack = stack;
|
||||
this.ignoresFallbacks = ignoresFallbacks;
|
||||
|
||||
if (stack.isEmpty())
|
||||
throw new ConfigException.BugOrBroken(
|
||||
"creating empty delayed merge object");
|
||||
if (!(stack.get(0) instanceof AbstractConfigObject))
|
||||
throw new ConfigException.BugOrBroken(
|
||||
"created a delayed merge object not guaranteed to be an object");
|
||||
|
||||
for (AbstractConfigValue v : stack) {
|
||||
if (v instanceof ConfigDelayedMerge || v instanceof ConfigDelayedMergeObject)
|
||||
throw new ConfigException.BugOrBroken(
|
||||
"placed nested DelayedMerge in a ConfigDelayedMergeObject, should have consolidated stack");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigDelayedMergeObject newCopy(ResolveStatus status) {
|
||||
protected ConfigDelayedMergeObject newCopy(ResolveStatus status,
|
||||
boolean ignoresFallbacks) {
|
||||
if (status != resolveStatus())
|
||||
throw new ConfigException.BugOrBroken(
|
||||
"attempt to create resolved ConfigDelayedMergeObject");
|
||||
return new ConfigDelayedMergeObject(origin(), stack);
|
||||
return new ConfigDelayedMergeObject(origin(), stack, ignoresFallbacks);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -64,36 +82,32 @@ class ConfigDelayedMergeObject extends AbstractConfigObject implements
|
|||
for (AbstractConfigValue o : stack) {
|
||||
newStack.add(o.relativized(prefix));
|
||||
}
|
||||
return new ConfigDelayedMergeObject(origin(), newStack);
|
||||
return new ConfigDelayedMergeObject(origin(), newStack,
|
||||
ignoresFallbacks);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean ignoresFallbacks() {
|
||||
return ignoresFallbacks;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ConfigDelayedMergeObject mergedWithObject(AbstractConfigObject fallback) {
|
||||
if (ignoresFallbacks)
|
||||
throw new ConfigException.BugOrBroken("should not be reached");
|
||||
|
||||
// since we are an object, and the fallback is, we'll need to
|
||||
// merge the fallback once we resolve.
|
||||
List<AbstractConfigValue> newStack = new ArrayList<AbstractConfigValue>();
|
||||
newStack.addAll(stack);
|
||||
newStack.add(fallback);
|
||||
return new ConfigDelayedMergeObject(AbstractConfigObject.mergeOrigins(newStack), newStack,
|
||||
fallback.ignoresFallbacks());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigDelayedMergeObject withFallback(ConfigMergeable mergeable) {
|
||||
ConfigValue other = mergeable.toValue();
|
||||
|
||||
if (other instanceof AbstractConfigObject
|
||||
|| other instanceof Unmergeable) {
|
||||
// since we are an object, and the fallback could be,
|
||||
// then a merge may be required; delay until we resolve.
|
||||
List<AbstractConfigValue> newStack = new ArrayList<AbstractConfigValue>();
|
||||
newStack.addAll(stack);
|
||||
if (other instanceof Unmergeable)
|
||||
newStack.addAll(((Unmergeable) other).unmergedValues());
|
||||
else
|
||||
newStack.add((AbstractConfigValue) other);
|
||||
return new ConfigDelayedMergeObject(
|
||||
AbstractConfigObject.mergeOrigins(newStack),
|
||||
newStack);
|
||||
} else {
|
||||
// if the other is not an object, there won't be anything
|
||||
// to merge with.
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigDelayedMergeObject withFallbacks(ConfigMergeable... others) {
|
||||
return (ConfigDelayedMergeObject) super.withFallbacks(others);
|
||||
return (ConfigDelayedMergeObject) super.withFallback(mergeable);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config.impl;
|
||||
|
||||
import com.typesafe.config.ConfigOrigin;
|
||||
|
|
|
|||
|
|
@ -1,20 +1,20 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config.impl;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
|
||||
import com.typesafe.config.Config;
|
||||
import com.typesafe.config.ConfigException;
|
||||
import com.typesafe.config.ConfigIncludeContext;
|
||||
import com.typesafe.config.ConfigIncluder;
|
||||
import com.typesafe.config.ConfigMergeable;
|
||||
import com.typesafe.config.ConfigObject;
|
||||
import com.typesafe.config.ConfigOrigin;
|
||||
import com.typesafe.config.ConfigParseOptions;
|
||||
|
|
@ -26,32 +26,6 @@ import com.typesafe.config.ConfigValue;
|
|||
/** This is public but is only supposed to be used by the "config" package */
|
||||
public class ConfigImpl {
|
||||
|
||||
static <T extends ConfigMergeable> T merge(Class<T> klass, T first,
|
||||
ConfigMergeable... others) {
|
||||
List<ConfigMergeable> stack = Arrays.asList(others);
|
||||
return merge(klass, first, stack);
|
||||
}
|
||||
|
||||
static <T extends ConfigMergeable> T merge(Class<T> klass, T first,
|
||||
List<? extends ConfigMergeable> stack) {
|
||||
if (stack.isEmpty()) {
|
||||
return first;
|
||||
} else {
|
||||
// to be consistent with the semantics of duplicate keys
|
||||
// in the same file, we have to go backward like this.
|
||||
// importantly, a primitive value always permanently
|
||||
// hides a previous object value.
|
||||
ListIterator<? extends ConfigMergeable> i = stack
|
||||
.listIterator(stack.size());
|
||||
ConfigMergeable merged = i.previous();
|
||||
while (i.hasPrevious()) {
|
||||
merged = i.previous().withFallback(merged);
|
||||
}
|
||||
merged = first.withFallback(merged);
|
||||
return klass.cast(merged);
|
||||
}
|
||||
}
|
||||
|
||||
private interface NameSource {
|
||||
ConfigParseable nameToParseable(String name);
|
||||
}
|
||||
|
|
@ -425,7 +399,7 @@ public class ConfigImpl {
|
|||
new SimpleConfigOrigin("env var " + key), entry.getValue()));
|
||||
}
|
||||
return new SimpleConfigObject(new SimpleConfigOrigin("env variables"),
|
||||
m, ResolveStatus.RESOLVED);
|
||||
m, ResolveStatus.RESOLVED, false /* ignoresFallbacks */);
|
||||
}
|
||||
|
||||
/** For use ONLY by library internals, DO NOT TOUCH not guaranteed ABI */
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config.impl;
|
||||
|
||||
import com.typesafe.config.ConfigOrigin;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config.impl;
|
||||
|
||||
import com.typesafe.config.ConfigOrigin;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config.impl;
|
||||
|
||||
import com.typesafe.config.ConfigOrigin;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config.impl;
|
||||
|
||||
import com.typesafe.config.ConfigException;
|
||||
import com.typesafe.config.ConfigOrigin;
|
||||
|
||||
abstract class ConfigNumber extends AbstractConfigValue {
|
||||
|
|
@ -14,11 +18,23 @@ abstract class ConfigNumber extends AbstractConfigValue {
|
|||
this.originalText = originalText;
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract Number unwrapped();
|
||||
|
||||
@Override
|
||||
String transformToString() {
|
||||
return originalText;
|
||||
}
|
||||
|
||||
int intValueRangeChecked(String path) {
|
||||
long l = longValue();
|
||||
if (l < Integer.MIN_VALUE || l > Integer.MAX_VALUE) {
|
||||
throw new ConfigException.WrongType(origin(), path, "32-bit integer",
|
||||
"out-of-range value " + l);
|
||||
}
|
||||
return (int) l;
|
||||
}
|
||||
|
||||
protected abstract long longValue();
|
||||
|
||||
protected abstract double doubleValue();
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config.impl;
|
||||
|
||||
import com.typesafe.config.ConfigOrigin;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -6,7 +9,6 @@ import java.util.Collections;
|
|||
import java.util.List;
|
||||
|
||||
import com.typesafe.config.ConfigException;
|
||||
import com.typesafe.config.ConfigMergeable;
|
||||
import com.typesafe.config.ConfigOrigin;
|
||||
import com.typesafe.config.ConfigResolveOptions;
|
||||
import com.typesafe.config.ConfigValue;
|
||||
|
|
@ -25,17 +27,19 @@ final class ConfigSubstitution extends AbstractConfigValue implements
|
|||
// than one piece everything is stringified and concatenated
|
||||
final private List<Object> pieces;
|
||||
// the length of any prefixes added with relativized()
|
||||
final int prefixLength;
|
||||
final private int prefixLength;
|
||||
final private boolean ignoresFallbacks;
|
||||
|
||||
ConfigSubstitution(ConfigOrigin origin, List<Object> pieces) {
|
||||
this(origin, pieces, 0);
|
||||
this(origin, pieces, 0, false);
|
||||
}
|
||||
|
||||
private ConfigSubstitution(ConfigOrigin origin, List<Object> pieces,
|
||||
int prefixLength) {
|
||||
int prefixLength, boolean ignoresFallbacks) {
|
||||
super(origin);
|
||||
this.pieces = pieces;
|
||||
this.prefixLength = prefixLength;
|
||||
this.ignoresFallbacks = ignoresFallbacks;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -52,26 +56,41 @@ final class ConfigSubstitution extends AbstractConfigValue implements
|
|||
}
|
||||
|
||||
@Override
|
||||
public AbstractConfigValue withFallback(ConfigMergeable mergeable) {
|
||||
ConfigValue other = mergeable.toValue();
|
||||
protected ConfigSubstitution newCopy(boolean ignoresFallbacks) {
|
||||
return new ConfigSubstitution(origin(), pieces, prefixLength, ignoresFallbacks);
|
||||
}
|
||||
|
||||
if (other instanceof AbstractConfigObject
|
||||
|| other instanceof Unmergeable) {
|
||||
// if we turn out to be an object, and the fallback also does,
|
||||
// then a merge may be required; delay until we resolve.
|
||||
List<AbstractConfigValue> newStack = new ArrayList<AbstractConfigValue>();
|
||||
newStack.add(this);
|
||||
if (other instanceof Unmergeable)
|
||||
newStack.addAll(((Unmergeable) other).unmergedValues());
|
||||
else
|
||||
newStack.add((AbstractConfigValue) other);
|
||||
return new ConfigDelayedMerge(
|
||||
AbstractConfigObject.mergeOrigins(newStack), newStack);
|
||||
} else {
|
||||
// if the other is not an object, there won't be anything
|
||||
// to merge with, so we are it even if we are an object.
|
||||
return this;
|
||||
}
|
||||
@Override
|
||||
protected boolean ignoresFallbacks() {
|
||||
return ignoresFallbacks;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractConfigValue mergedWithTheUnmergeable(Unmergeable fallback) {
|
||||
if (ignoresFallbacks)
|
||||
throw new ConfigException.BugOrBroken("should not be reached");
|
||||
|
||||
// if we turn out to be an object, and the fallback also does,
|
||||
// then a merge may be required; delay until we resolve.
|
||||
List<AbstractConfigValue> newStack = new ArrayList<AbstractConfigValue>();
|
||||
newStack.add(this);
|
||||
newStack.addAll(fallback.unmergedValues());
|
||||
return new ConfigDelayedMerge(AbstractConfigObject.mergeOrigins(newStack), newStack,
|
||||
((AbstractConfigValue) fallback).ignoresFallbacks());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractConfigValue mergedWithObject(AbstractConfigObject fallback) {
|
||||
if (ignoresFallbacks)
|
||||
throw new ConfigException.BugOrBroken("should not be reached");
|
||||
|
||||
// if we turn out to be an object, and the fallback also does,
|
||||
// then a merge may be required; delay until we resolve.
|
||||
List<AbstractConfigValue> newStack = new ArrayList<AbstractConfigValue>();
|
||||
newStack.add(this);
|
||||
newStack.add(fallback);
|
||||
return new ConfigDelayedMerge(AbstractConfigObject.mergeOrigins(newStack), newStack,
|
||||
fallback.ignoresFallbacks());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -198,7 +217,7 @@ final class ConfigSubstitution extends AbstractConfigValue implements
|
|||
}
|
||||
}
|
||||
return new ConfigSubstitution(origin(), newPieces, prefixLength
|
||||
+ prefix.length());
|
||||
+ prefix.length(), ignoresFallbacks);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config.impl;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config.impl;
|
||||
|
||||
import com.typesafe.config.ConfigValueType;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config.impl;
|
||||
|
||||
enum FromMapMode {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config.impl;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config.impl;
|
||||
|
||||
import java.io.StringReader;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config.impl;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config.impl;
|
||||
|
||||
import java.util.Stack;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config.impl;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
@ -177,11 +180,12 @@ final class PropertiesParser {
|
|||
.get(parentPath) : root;
|
||||
|
||||
AbstractConfigObject o = new SimpleConfigObject(origin, scope,
|
||||
ResolveStatus.RESOLVED);
|
||||
ResolveStatus.RESOLVED, false /* ignoresFallbacks */);
|
||||
parent.put(scopePath.last(), o);
|
||||
}
|
||||
|
||||
// return root config object
|
||||
return new SimpleConfigObject(origin, root, ResolveStatus.RESOLVED);
|
||||
return new SimpleConfigObject(origin, root, ResolveStatus.RESOLVED,
|
||||
false /* ignoresFallbacks */);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config.impl;
|
||||
|
||||
import java.util.Collection;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config.impl;
|
||||
|
||||
import com.typesafe.config.ConfigMergeable;
|
||||
|
|
@ -32,20 +35,14 @@ final class RootConfig extends SimpleConfig implements ConfigRoot {
|
|||
// if the object is already resolved then we should end up returning
|
||||
// "this" here, since asRoot() should return this if the path
|
||||
// is unchanged.
|
||||
SimpleConfig resolved = resolvedObject(options).toConfig();
|
||||
return resolved.asRoot(rootPath);
|
||||
AbstractConfigObject resolved = resolvedObject(options);
|
||||
return newRootIfObjectChanged(this, resolved);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RootConfig withFallback(ConfigMergeable value) {
|
||||
// this can return "this" if the withFallback does nothing
|
||||
return super.withFallback(value).asRoot(rootPath);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RootConfig withFallbacks(ConfigMergeable... values) {
|
||||
// this can return "this" if the withFallbacks does nothing
|
||||
return super.withFallbacks(values).asRoot(rootPath);
|
||||
return newRootIfObjectChanged(this, super.withFallback(value).toObject());
|
||||
}
|
||||
|
||||
Path rootPathObject() {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -56,6 +59,13 @@ class SimpleConfig implements Config {
|
|||
return new RootConfig(underlying, newRootPath);
|
||||
}
|
||||
|
||||
static protected RootConfig newRootIfObjectChanged(RootConfig self, AbstractConfigObject underlying) {
|
||||
if (underlying == self.object)
|
||||
return self;
|
||||
else
|
||||
return new RootConfig(underlying, self.rootPathObject());
|
||||
}
|
||||
|
||||
protected AbstractConfigObject resolvedObject(ConfigResolveOptions options) {
|
||||
AbstractConfigValue resolved = SubstitutionResolver.resolve(object,
|
||||
object, options);
|
||||
|
|
@ -129,15 +139,20 @@ class SimpleConfig implements Config {
|
|||
return (Boolean) v.unwrapped();
|
||||
}
|
||||
|
||||
private ConfigNumber getConfigNumber(String path) {
|
||||
ConfigValue v = find(path, ConfigValueType.NUMBER, path);
|
||||
return (ConfigNumber) v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Number getNumber(String path) {
|
||||
ConfigValue v = find(path, ConfigValueType.NUMBER, path);
|
||||
return (Number) v.unwrapped();
|
||||
return getConfigNumber(path).unwrapped();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInt(String path) {
|
||||
return getNumber(path).intValue();
|
||||
ConfigNumber n = getConfigNumber(path);
|
||||
return n.intValueRangeChecked(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -245,9 +260,9 @@ class SimpleConfig implements Config {
|
|||
@Override
|
||||
public List<Integer> getIntList(String path) {
|
||||
List<Integer> l = new ArrayList<Integer>();
|
||||
List<Number> numbers = getNumberList(path);
|
||||
for (Number n : numbers) {
|
||||
l.add(n.intValue());
|
||||
List<AbstractConfigValue> numbers = getHomogeneousWrappedList(path, ConfigValueType.NUMBER);
|
||||
for (AbstractConfigValue v : numbers) {
|
||||
l.add(((ConfigNumber) v).intValueRangeChecked(path));
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
|
@ -385,13 +400,6 @@ class SimpleConfig implements Config {
|
|||
return object.withFallback(other).toConfig();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleConfig withFallbacks(ConfigMergeable... others) {
|
||||
// this can return "this" if the withFallbacks doesn't need a new
|
||||
// ConfigObject
|
||||
return object.withFallbacks(others).toConfig();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean equals(Object other) {
|
||||
if (other instanceof SimpleConfig) {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config.impl;
|
||||
|
||||
import java.util.AbstractMap;
|
||||
|
|
@ -17,21 +20,23 @@ final class SimpleConfigObject extends AbstractConfigObject {
|
|||
// this map should never be modified - assume immutable
|
||||
final private Map<String, AbstractConfigValue> value;
|
||||
final private boolean resolved;
|
||||
final private boolean ignoresFallbacks;
|
||||
|
||||
SimpleConfigObject(ConfigOrigin origin,
|
||||
Map<String, AbstractConfigValue> value, ResolveStatus status) {
|
||||
Map<String, AbstractConfigValue> value, ResolveStatus status,
|
||||
boolean ignoresFallbacks) {
|
||||
super(origin);
|
||||
if (value == null)
|
||||
throw new ConfigException.BugOrBroken(
|
||||
"creating config object with null map");
|
||||
this.value = value;
|
||||
this.resolved = status == ResolveStatus.RESOLVED;
|
||||
this.ignoresFallbacks = ignoresFallbacks;
|
||||
}
|
||||
|
||||
SimpleConfigObject(ConfigOrigin origin,
|
||||
Map<String, AbstractConfigValue> value) {
|
||||
this(origin, value, ResolveStatus.fromValues(value
|
||||
.values()));
|
||||
this(origin, value, ResolveStatus.fromValues(value.values()), false /* ignoresFallbacks */);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -40,9 +45,8 @@ final class SimpleConfigObject extends AbstractConfigObject {
|
|||
}
|
||||
|
||||
@Override
|
||||
public SimpleConfigObject newCopy(ResolveStatus newStatus) {
|
||||
return new SimpleConfigObject(origin(), value,
|
||||
newStatus);
|
||||
protected SimpleConfigObject newCopy(ResolveStatus newStatus, boolean newIgnoresFallbacks) {
|
||||
return new SimpleConfigObject(origin(), value, newStatus, newIgnoresFallbacks);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -50,6 +54,11 @@ final class SimpleConfigObject extends AbstractConfigObject {
|
|||
return ResolveStatus.fromBoolean(resolved);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean ignoresFallbacks() {
|
||||
return ignoresFallbacks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> unwrapped() {
|
||||
Map<String, Object> m = new HashMap<String, Object>();
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config.impl;
|
||||
|
||||
import com.typesafe.config.ConfigOrigin;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config.impl;
|
||||
|
||||
import java.util.IdentityHashMap;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config.impl;
|
||||
|
||||
class Token {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config.impl;
|
||||
|
||||
enum TokenType {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config.impl;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config.impl;
|
||||
|
||||
import java.util.List;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Copyright (C) 2011 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config.impl;
|
||||
|
||||
import java.util.Collection;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue