mirror of
https://github.com/lightbend/config.git
synced 2025-02-23 17:50:30 +08:00
Add ConfigRenderOptions and ConfigValue#render(options)
This mostly lets you choose whether you want whitespace and comments, and somewhat as a side effect, you can get plain JSON by turning off comments.
This commit is contained in:
parent
985958521d
commit
387e106856
@ -0,0 +1,134 @@
|
||||
/**
|
||||
* Copyright (C) 2011-2012 Typesafe Inc. <http://typesafe.com>
|
||||
*/
|
||||
package com.typesafe.config;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* A set of options related to rendering a {@link ConfigValue}. Passed to
|
||||
* {@link ConfigValue#render(ConfigRenderOptions)}.
|
||||
*
|
||||
* <p>
|
||||
* Here is an example of creating a {@code ConfigRenderOptions}:
|
||||
*
|
||||
* <pre>
|
||||
* ConfigRenderOptions options =
|
||||
* ConfigRenderOptions.defaults().setComments(false)
|
||||
* </pre>
|
||||
*/
|
||||
public final class ConfigRenderOptions {
|
||||
private final boolean originComments;
|
||||
private final boolean comments;
|
||||
private final boolean formatted;
|
||||
|
||||
private ConfigRenderOptions(boolean originComments, boolean comments, boolean formatted) {
|
||||
this.originComments = originComments;
|
||||
this.comments = comments;
|
||||
this.formatted = formatted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default render options which are verbose (commented and
|
||||
* formatted). See {@link ConfigRenderOptions#concise} for stripped-down
|
||||
* options. This rendering will not be valid JSON since it has comments.
|
||||
*
|
||||
* @return the default render options
|
||||
*/
|
||||
public static ConfigRenderOptions defaults() {
|
||||
return new ConfigRenderOptions(true, true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns concise render options (no whitespace or comments). For a
|
||||
* resolved {@link Config}, the concise rendering will be valid JSON.
|
||||
*
|
||||
* @return the concise render options
|
||||
*/
|
||||
public static ConfigRenderOptions concise() {
|
||||
return new ConfigRenderOptions(false, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns options with comments toggled. This controls human-written
|
||||
* comments but not the autogenerated "origin of this setting" comments,
|
||||
* which are controlled by {@link ConfigRenderOptions#setOriginComments}.
|
||||
*
|
||||
* @param value
|
||||
* true to include comments in the render
|
||||
* @return options with requested setting for comments
|
||||
*/
|
||||
public ConfigRenderOptions setComments(boolean value) {
|
||||
if (value == comments)
|
||||
return this;
|
||||
else
|
||||
return new ConfigRenderOptions(originComments, value, formatted);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the options enable comments. This method is mostly used
|
||||
* by the config lib internally, not by applications.
|
||||
*
|
||||
* @return true if comments should be rendered
|
||||
*/
|
||||
public boolean getComments() {
|
||||
return comments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns options with origin comments toggled. If this is enabled, the
|
||||
* library generates comments for each setting based on the
|
||||
* {@link ConfigValue#origin} of that setting's value. For example these
|
||||
* comments might tell you which file a setting comes from.
|
||||
*
|
||||
* <p>
|
||||
* {@code setOriginComments()} controls only these autogenerated
|
||||
* "origin of this setting" comments, to toggle regular comments use
|
||||
* {@link ConfigRenderOptions#setComments}.
|
||||
*
|
||||
* @param value
|
||||
* true to include autogenerated setting-origin comments in the
|
||||
* render
|
||||
* @return options with origin comments toggled
|
||||
*/
|
||||
public ConfigRenderOptions setOriginComments(boolean value) {
|
||||
if (value == originComments)
|
||||
return this;
|
||||
else
|
||||
return new ConfigRenderOptions(value, comments, formatted);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the options enable automated origin comments. This method
|
||||
* is mostly used by the config lib internally, not by applications.
|
||||
*
|
||||
* @return true if origin comments should be rendered
|
||||
*/
|
||||
public boolean getOriginComments() {
|
||||
return originComments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns options with formatting toggled. Formatting means indentation and
|
||||
* whitespace, enabling formatting makes things prettier but larger.
|
||||
*
|
||||
* @param value
|
||||
* true to include comments in the render
|
||||
* @return options with requested setting for formatting
|
||||
*/
|
||||
public ConfigRenderOptions setFormatted(boolean value) {
|
||||
if (value == formatted)
|
||||
return this;
|
||||
else
|
||||
return new ConfigRenderOptions(originComments, comments, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the options enable formatting. This method is mostly used
|
||||
* by the config lib internally, not by applications.
|
||||
*
|
||||
* @return true if comments should be rendered
|
||||
*/
|
||||
public boolean getFormatted() {
|
||||
return formatted;
|
||||
}
|
||||
}
|
@ -46,15 +46,43 @@ public interface ConfigValue extends ConfigMergeable {
|
||||
/**
|
||||
* Renders the config value as a HOCON string. This method is primarily
|
||||
* intended for debugging, so it tries to add helpful comments and
|
||||
* whitespace. If the config value has not been resolved (see
|
||||
* {@link Config#resolve}), it's possible that it can't be rendered as valid
|
||||
* HOCON. In that case the rendering should still be useful for debugging
|
||||
* but you might not be able to parse it.
|
||||
*
|
||||
* whitespace.
|
||||
*
|
||||
* <p>
|
||||
* If the config value has not been resolved (see {@link Config#resolve}),
|
||||
* it's possible that it can't be rendered as valid HOCON. In that case the
|
||||
* rendering should still be useful for debugging but you might not be able
|
||||
* to parse it.
|
||||
*
|
||||
* <p>
|
||||
* This method is equivalent to
|
||||
* {@code render(ConfigRenderOptions.defaults())}.
|
||||
*
|
||||
* @return the rendered value
|
||||
*/
|
||||
String render();
|
||||
|
||||
/**
|
||||
* Renders the config value to a string, using the provided options.
|
||||
*
|
||||
* <p>
|
||||
* If the config value has not been resolved (see {@link Config#resolve}),
|
||||
* it's possible that it can't be rendered as valid HOCON. In that case the
|
||||
* rendering should still be useful for debugging but you might not be able
|
||||
* to parse it.
|
||||
*
|
||||
* <p>
|
||||
* If the config value has been resolved and the options disable all
|
||||
* HOCON-specific features (such as comments), the rendering will be valid
|
||||
* JSON. If you enable HOCON-only features such as comments, the rendering
|
||||
* will not be valid JSON.
|
||||
*
|
||||
* @param options
|
||||
* the rendering options
|
||||
* @return the rendered value
|
||||
*/
|
||||
String render(ConfigRenderOptions options);
|
||||
|
||||
@Override
|
||||
ConfigValue withFallback(ConfigMergeable other);
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import com.typesafe.config.ConfigException;
|
||||
import com.typesafe.config.ConfigMergeable;
|
||||
import com.typesafe.config.ConfigObject;
|
||||
import com.typesafe.config.ConfigOrigin;
|
||||
import com.typesafe.config.ConfigRenderOptions;
|
||||
import com.typesafe.config.ConfigValue;
|
||||
import com.typesafe.config.ConfigValueType;
|
||||
|
||||
@ -212,7 +213,7 @@ abstract class AbstractConfigObject extends AbstractConfigValue implements Confi
|
||||
public abstract AbstractConfigValue get(Object key);
|
||||
|
||||
@Override
|
||||
protected abstract void render(StringBuilder sb, int indent, boolean formatted);
|
||||
protected abstract void render(StringBuilder sb, int indent, ConfigRenderOptions options);
|
||||
|
||||
private static UnsupportedOperationException weAreImmutable(String method) {
|
||||
return new UnsupportedOperationException("ConfigObject is immutable, you can't call Map."
|
||||
|
@ -11,6 +11,7 @@ import java.util.List;
|
||||
import com.typesafe.config.ConfigException;
|
||||
import com.typesafe.config.ConfigMergeable;
|
||||
import com.typesafe.config.ConfigOrigin;
|
||||
import com.typesafe.config.ConfigRenderOptions;
|
||||
import com.typesafe.config.ConfigValue;
|
||||
|
||||
/**
|
||||
@ -276,36 +277,45 @@ abstract class AbstractConfigValue implements ConfigValue, MergeableValue {
|
||||
@Override
|
||||
public final String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
render(sb, 0, null /* atKey */, false /* formatted */);
|
||||
render(sb, 0, null /* atKey */, ConfigRenderOptions.concise());
|
||||
return getClass().getSimpleName() + "(" + sb.toString() + ")";
|
||||
}
|
||||
|
||||
protected static void indent(StringBuilder sb, int indent) {
|
||||
int remaining = indent;
|
||||
while (remaining > 0) {
|
||||
sb.append(" ");
|
||||
--remaining;
|
||||
protected static void indent(StringBuilder sb, int indent, ConfigRenderOptions options) {
|
||||
if (options.getFormatted()) {
|
||||
int remaining = indent;
|
||||
while (remaining > 0) {
|
||||
sb.append(" ");
|
||||
--remaining;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void render(StringBuilder sb, int indent, String atKey, boolean formatted) {
|
||||
protected void render(StringBuilder sb, int indent, String atKey, ConfigRenderOptions options) {
|
||||
if (atKey != null) {
|
||||
sb.append(ConfigImplUtil.renderJsonString(atKey));
|
||||
sb.append(" : ");
|
||||
if (options.getFormatted())
|
||||
sb.append(" : ");
|
||||
else
|
||||
sb.append(":");
|
||||
}
|
||||
render(sb, indent, formatted);
|
||||
render(sb, indent, options);
|
||||
}
|
||||
|
||||
protected void render(StringBuilder sb, int indent, boolean formatted) {
|
||||
protected void render(StringBuilder sb, int indent, ConfigRenderOptions options) {
|
||||
Object u = unwrapped();
|
||||
sb.append(u.toString());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final String render() {
|
||||
return render(ConfigRenderOptions.defaults());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String render(ConfigRenderOptions options) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
render(sb, 0, null, true /* formatted */);
|
||||
render(sb, 0, null, options);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@ import java.util.List;
|
||||
import com.typesafe.config.ConfigException;
|
||||
import com.typesafe.config.ConfigObject;
|
||||
import com.typesafe.config.ConfigOrigin;
|
||||
import com.typesafe.config.ConfigRenderOptions;
|
||||
import com.typesafe.config.ConfigValueType;
|
||||
|
||||
/**
|
||||
@ -222,9 +223,9 @@ final class ConfigConcatenation extends AbstractConfigValue implements Unmergeab
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void render(StringBuilder sb, int indent, boolean formatted) {
|
||||
protected void render(StringBuilder sb, int indent, ConfigRenderOptions options) {
|
||||
for (AbstractConfigValue p : pieces) {
|
||||
p.render(sb, indent, formatted);
|
||||
p.render(sb, indent, options);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@ import java.util.List;
|
||||
|
||||
import com.typesafe.config.ConfigException;
|
||||
import com.typesafe.config.ConfigOrigin;
|
||||
import com.typesafe.config.ConfigRenderOptions;
|
||||
import com.typesafe.config.ConfigValueType;
|
||||
|
||||
/**
|
||||
@ -215,18 +216,20 @@ final class ConfigDelayedMerge extends AbstractConfigValue implements Unmergeabl
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void render(StringBuilder sb, int indent, String atKey, boolean formatted) {
|
||||
render(stack, sb, indent, atKey, formatted);
|
||||
protected void render(StringBuilder sb, int indent, String atKey, ConfigRenderOptions options) {
|
||||
render(stack, sb, indent, atKey, options);
|
||||
}
|
||||
|
||||
// static method also used by ConfigDelayedMergeObject.
|
||||
static void render(List<AbstractConfigValue> stack, StringBuilder sb, int indent, String atKey,
|
||||
boolean formatted) {
|
||||
if (formatted) {
|
||||
ConfigRenderOptions options) {
|
||||
boolean commentMerge = options.getComments();
|
||||
if (commentMerge) {
|
||||
sb.append("# unresolved merge of " + stack.size() + " values follows (\n");
|
||||
if (atKey == null) {
|
||||
indent(sb, indent);
|
||||
indent(sb, indent, options);
|
||||
sb.append("# this unresolved merge will not be parseable because it's at the root of the object\n");
|
||||
indent(sb, indent, options);
|
||||
sb.append("# the HOCON format has no way to list multiple root objects in a single file\n");
|
||||
}
|
||||
}
|
||||
@ -237,8 +240,8 @@ final class ConfigDelayedMerge extends AbstractConfigValue implements Unmergeabl
|
||||
|
||||
int i = 0;
|
||||
for (AbstractConfigValue v : reversed) {
|
||||
if (formatted) {
|
||||
indent(sb, indent);
|
||||
if (commentMerge) {
|
||||
indent(sb, indent, options);
|
||||
if (atKey != null) {
|
||||
sb.append("# unmerged value " + i + " for key "
|
||||
+ ConfigImplUtil.renderJsonString(atKey) + " from ");
|
||||
@ -248,30 +251,36 @@ final class ConfigDelayedMerge extends AbstractConfigValue implements Unmergeabl
|
||||
i += 1;
|
||||
sb.append(v.origin().description());
|
||||
sb.append("\n");
|
||||
|
||||
for (String comment : v.origin().comments()) {
|
||||
indent(sb, indent);
|
||||
indent(sb, indent, options);
|
||||
sb.append("# ");
|
||||
sb.append(comment);
|
||||
sb.append("\n");
|
||||
}
|
||||
indent(sb, indent);
|
||||
}
|
||||
indent(sb, indent, options);
|
||||
|
||||
if (atKey != null) {
|
||||
sb.append(ConfigImplUtil.renderJsonString(atKey));
|
||||
sb.append(" : ");
|
||||
if (options.getFormatted())
|
||||
sb.append(" : ");
|
||||
else
|
||||
sb.append(":");
|
||||
}
|
||||
v.render(sb, indent, formatted);
|
||||
v.render(sb, indent, options);
|
||||
sb.append(",");
|
||||
if (formatted)
|
||||
if (options.getFormatted())
|
||||
sb.append('\n');
|
||||
}
|
||||
// chop comma or newline
|
||||
sb.setLength(sb.length() - 1);
|
||||
if (formatted) {
|
||||
if (options.getFormatted()) {
|
||||
sb.setLength(sb.length() - 1); // also chop comma
|
||||
sb.append("\n"); // put a newline back
|
||||
indent(sb, indent);
|
||||
}
|
||||
if (commentMerge) {
|
||||
indent(sb, indent, options);
|
||||
sb.append("# ) end of unresolved merge\n");
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import com.typesafe.config.ConfigException;
|
||||
import com.typesafe.config.ConfigList;
|
||||
import com.typesafe.config.ConfigMergeable;
|
||||
import com.typesafe.config.ConfigOrigin;
|
||||
import com.typesafe.config.ConfigRenderOptions;
|
||||
import com.typesafe.config.ConfigValue;
|
||||
|
||||
// This is just like ConfigDelayedMerge except we know statically
|
||||
@ -168,13 +169,13 @@ final class ConfigDelayedMergeObject extends AbstractConfigObject implements Unm
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void render(StringBuilder sb, int indent, String atKey, boolean formatted) {
|
||||
ConfigDelayedMerge.render(stack, sb, indent, atKey, formatted);
|
||||
protected void render(StringBuilder sb, int indent, String atKey, ConfigRenderOptions options) {
|
||||
ConfigDelayedMerge.render(stack, sb, indent, atKey, options);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void render(StringBuilder sb, int indent, boolean formatted) {
|
||||
render(sb, indent, null, formatted);
|
||||
protected void render(StringBuilder sb, int indent, ConfigRenderOptions options) {
|
||||
render(sb, indent, null, options);
|
||||
}
|
||||
|
||||
private static ConfigException notResolved() {
|
||||
|
@ -7,6 +7,7 @@ import java.io.ObjectStreamException;
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.typesafe.config.ConfigOrigin;
|
||||
import com.typesafe.config.ConfigRenderOptions;
|
||||
import com.typesafe.config.ConfigValueType;
|
||||
|
||||
/**
|
||||
@ -41,7 +42,7 @@ final class ConfigNull extends AbstractConfigValue implements Serializable {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void render(StringBuilder sb, int indent, boolean formatted) {
|
||||
protected void render(StringBuilder sb, int indent, ConfigRenderOptions options) {
|
||||
sb.append("null");
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@ import java.util.Collections;
|
||||
|
||||
import com.typesafe.config.ConfigException;
|
||||
import com.typesafe.config.ConfigOrigin;
|
||||
import com.typesafe.config.ConfigRenderOptions;
|
||||
import com.typesafe.config.ConfigValueType;
|
||||
|
||||
/**
|
||||
@ -126,7 +127,7 @@ final class ConfigReference extends AbstractConfigValue implements Unmergeable {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void render(StringBuilder sb, int indent, boolean formatted) {
|
||||
protected void render(StringBuilder sb, int indent, ConfigRenderOptions options) {
|
||||
sb.append(expr.toString());
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ import java.io.ObjectStreamException;
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.typesafe.config.ConfigOrigin;
|
||||
import com.typesafe.config.ConfigRenderOptions;
|
||||
import com.typesafe.config.ConfigValueType;
|
||||
|
||||
final class ConfigString extends AbstractConfigValue implements Serializable {
|
||||
@ -36,7 +37,7 @@ final class ConfigString extends AbstractConfigValue implements Serializable {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void render(StringBuilder sb, int indent, boolean formatted) {
|
||||
protected void render(StringBuilder sb, int indent, ConfigRenderOptions options) {
|
||||
sb.append(ConfigImplUtil.renderJsonString(value));
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@ import java.util.ListIterator;
|
||||
import com.typesafe.config.ConfigException;
|
||||
import com.typesafe.config.ConfigList;
|
||||
import com.typesafe.config.ConfigOrigin;
|
||||
import com.typesafe.config.ConfigRenderOptions;
|
||||
import com.typesafe.config.ConfigValue;
|
||||
import com.typesafe.config.ConfigValueType;
|
||||
|
||||
@ -166,39 +167,40 @@ final class SimpleConfigList extends AbstractConfigValue implements ConfigList,
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void render(StringBuilder sb, int indent, boolean formatted) {
|
||||
protected void render(StringBuilder sb, int indent, ConfigRenderOptions options) {
|
||||
if (value.isEmpty()) {
|
||||
sb.append("[]");
|
||||
} else {
|
||||
sb.append("[");
|
||||
if (formatted)
|
||||
if (options.getFormatted())
|
||||
sb.append('\n');
|
||||
for (AbstractConfigValue v : value) {
|
||||
if (formatted) {
|
||||
indent(sb, indent + 1);
|
||||
if (options.getOriginComments()) {
|
||||
indent(sb, indent + 1, options);
|
||||
sb.append("# ");
|
||||
sb.append(v.origin().description());
|
||||
sb.append("\n");
|
||||
|
||||
}
|
||||
if (options.getComments()) {
|
||||
for (String comment : v.origin().comments()) {
|
||||
indent(sb, indent + 1);
|
||||
indent(sb, indent + 1, options);
|
||||
sb.append("# ");
|
||||
sb.append(comment);
|
||||
sb.append("\n");
|
||||
}
|
||||
|
||||
indent(sb, indent + 1);
|
||||
}
|
||||
v.render(sb, indent + 1, formatted);
|
||||
indent(sb, indent + 1, options);
|
||||
|
||||
v.render(sb, indent + 1, options);
|
||||
sb.append(",");
|
||||
if (formatted)
|
||||
if (options.getFormatted())
|
||||
sb.append('\n');
|
||||
}
|
||||
sb.setLength(sb.length() - 1); // chop or newline
|
||||
if (formatted) {
|
||||
if (options.getFormatted()) {
|
||||
sb.setLength(sb.length() - 1); // also chop comma
|
||||
sb.append('\n');
|
||||
indent(sb, indent);
|
||||
indent(sb, indent, options);
|
||||
}
|
||||
sb.append("]");
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import java.util.Set;
|
||||
import com.typesafe.config.ConfigException;
|
||||
import com.typesafe.config.ConfigObject;
|
||||
import com.typesafe.config.ConfigOrigin;
|
||||
import com.typesafe.config.ConfigRenderOptions;
|
||||
import com.typesafe.config.ConfigValue;
|
||||
|
||||
final class SimpleConfigObject extends AbstractConfigObject implements Serializable {
|
||||
@ -324,41 +325,43 @@ final class SimpleConfigObject extends AbstractConfigObject implements Serializa
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void render(StringBuilder sb, int indent, boolean formatted) {
|
||||
protected void render(StringBuilder sb, int indent, ConfigRenderOptions options) {
|
||||
if (isEmpty()) {
|
||||
sb.append("{}");
|
||||
} else {
|
||||
sb.append("{");
|
||||
if (formatted)
|
||||
if (options.getFormatted())
|
||||
sb.append('\n');
|
||||
for (String k : keySet()) {
|
||||
AbstractConfigValue v;
|
||||
v = value.get(k);
|
||||
|
||||
if (formatted) {
|
||||
indent(sb, indent + 1);
|
||||
if (options.getOriginComments()) {
|
||||
indent(sb, indent + 1, options);
|
||||
sb.append("# ");
|
||||
sb.append(v.origin().description());
|
||||
sb.append("\n");
|
||||
}
|
||||
if (options.getComments()) {
|
||||
for (String comment : v.origin().comments()) {
|
||||
indent(sb, indent + 1);
|
||||
indent(sb, indent + 1, options);
|
||||
sb.append("# ");
|
||||
sb.append(comment);
|
||||
sb.append("\n");
|
||||
}
|
||||
indent(sb, indent + 1);
|
||||
}
|
||||
v.render(sb, indent + 1, k, formatted);
|
||||
indent(sb, indent + 1, options);
|
||||
v.render(sb, indent + 1, k, options);
|
||||
sb.append(",");
|
||||
if (formatted)
|
||||
if (options.getFormatted())
|
||||
sb.append('\n');
|
||||
}
|
||||
// chop comma or newline
|
||||
sb.setLength(sb.length() - 1);
|
||||
if (formatted) {
|
||||
if (options.getFormatted()) {
|
||||
sb.setLength(sb.length() - 1); // also chop comma
|
||||
sb.append("\n"); // put a newline back
|
||||
indent(sb, indent);
|
||||
indent(sb, indent, options);
|
||||
}
|
||||
sb.append("}");
|
||||
}
|
||||
|
@ -1,17 +1,26 @@
|
||||
import com.typesafe.config.ConfigFactory
|
||||
import com.typesafe.config.ConfigRenderOptions
|
||||
|
||||
object RenderExample extends App {
|
||||
val formatted = args.contains("--formatted")
|
||||
val originComments = args.contains("--origin-comments")
|
||||
val comments = args.contains("--comments")
|
||||
val options = ConfigRenderOptions.defaults()
|
||||
.setFormatted(formatted)
|
||||
.setOriginComments(originComments)
|
||||
.setComments(comments)
|
||||
|
||||
def render(what: String) {
|
||||
val conf = ConfigFactory.defaultOverrides()
|
||||
.withFallback(ConfigFactory.parseResourcesAnySyntax(classOf[ConfigFactory], "/" + what))
|
||||
.withFallback(ConfigFactory.defaultReference())
|
||||
|
||||
println("=== BEGIN UNRESOLVED " + what)
|
||||
println(conf.root.render())
|
||||
println(conf.root.render(options))
|
||||
println("=== END UNRESOLVED " + what)
|
||||
|
||||
println("=== BEGIN RESOLVED " + what)
|
||||
println(conf.resolve().root.render())
|
||||
println(conf.resolve().root.render(options))
|
||||
println("=== END RESOLVED " + what)
|
||||
|
||||
println("=== BEGIN UNRESOLVED toString() " + what)
|
||||
|
@ -51,7 +51,7 @@ class ConcatenationTest extends TestUtils {
|
||||
assertTrue("wrong exception: " + e.getMessage,
|
||||
e.getMessage.contains("Cannot concatenate") &&
|
||||
e.getMessage.contains("abc") &&
|
||||
e.getMessage.contains("""{"x" : "y"}"""))
|
||||
e.getMessage.contains("""{"x":"y"}"""))
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -62,7 +62,7 @@ class ConcatenationTest extends TestUtils {
|
||||
assertTrue("wrong exception: " + e.getMessage,
|
||||
e.getMessage.contains("Cannot concatenate") &&
|
||||
e.getMessage.contains("null") &&
|
||||
e.getMessage.contains("""{"x" : "y"}"""))
|
||||
e.getMessage.contains("""{"x":"y"}"""))
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -293,7 +293,7 @@ class ConcatenationTest extends TestUtils {
|
||||
}
|
||||
assertTrue("wrong exception: " + e.getMessage,
|
||||
e.getMessage.contains("Cannot concatenate") &&
|
||||
e.getMessage.contains("\"x\" : \"y\"") &&
|
||||
e.getMessage.contains("\"x\":\"y\"") &&
|
||||
e.getMessage.contains("[2]"))
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,8 @@ import java.io.File
|
||||
import com.typesafe.config.ConfigParseOptions
|
||||
import com.typesafe.config.ConfigFactory
|
||||
import com.typesafe.config.ConfigMergeable
|
||||
import com.typesafe.config.ConfigRenderOptions
|
||||
import com.typesafe.config.ConfigSyntax
|
||||
|
||||
class ConfigTest extends TestUtils {
|
||||
|
||||
@ -989,22 +991,46 @@ class ConfigTest extends TestUtils {
|
||||
|
||||
@Test
|
||||
def renderRoundTrip() {
|
||||
val allBooleans = true :: false :: Nil
|
||||
val optionsCombos = {
|
||||
for (
|
||||
formatted <- allBooleans;
|
||||
originComments <- allBooleans;
|
||||
comments <- allBooleans
|
||||
) yield ConfigRenderOptions.defaults()
|
||||
.setFormatted(formatted)
|
||||
.setOriginComments(originComments)
|
||||
.setComments(comments)
|
||||
} toSeq
|
||||
|
||||
for (i <- 1 to 10) {
|
||||
val numString = i.toString
|
||||
val name = "/test" + { if (numString.size == 1) "0" else "" } + numString
|
||||
val conf = ConfigFactory.parseResourcesAnySyntax(classOf[ConfigTest], name,
|
||||
ConfigParseOptions.defaults().setAllowMissing(false))
|
||||
val unresolvedRender = conf.root.render()
|
||||
val resolved = conf.resolve()
|
||||
val resolvedRender = resolved.root.render()
|
||||
try {
|
||||
assertEquals(conf.root, ConfigFactory.parseString(unresolvedRender, ConfigParseOptions.defaults()).root)
|
||||
assertEquals(resolved.root, ConfigFactory.parseString(resolvedRender, ConfigParseOptions.defaults()).root)
|
||||
} catch {
|
||||
case e: Throwable =>
|
||||
System.err.println("unresolvedRender = " + unresolvedRender)
|
||||
System.err.println("resolvedRender = " + resolvedRender)
|
||||
throw e
|
||||
for (renderOptions <- optionsCombos) {
|
||||
val unresolvedRender = conf.root.render(renderOptions)
|
||||
val resolved = conf.resolve()
|
||||
val resolvedRender = resolved.root.render(renderOptions)
|
||||
try {
|
||||
assertEquals(conf.root, ConfigFactory.parseString(unresolvedRender, ConfigParseOptions.defaults()).root)
|
||||
assertEquals(resolved.root, ConfigFactory.parseString(resolvedRender, ConfigParseOptions.defaults()).root)
|
||||
} catch {
|
||||
case e: Exception =>
|
||||
System.err.println("unresolvedRender = " + unresolvedRender)
|
||||
System.err.println("resolvedRender = " + resolvedRender)
|
||||
throw e
|
||||
}
|
||||
if (!(renderOptions.getComments() || renderOptions.getOriginComments())) {
|
||||
// should get valid JSON if we don't have comments and are resolved
|
||||
val json = try {
|
||||
ConfigFactory.parseString(resolvedRender, ConfigParseOptions.defaults().setSyntax(ConfigSyntax.JSON));
|
||||
} catch {
|
||||
case e: Exception =>
|
||||
System.err.println("resolvedRender is not valid json: " + resolvedRender)
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user