Merge pull request #127 from typesafehub/wip/havocp-render-tweaks

Rendering tweaks
This commit is contained in:
Havoc Pennington 2014-01-06 06:59:26 -08:00
commit afe042b99b
11 changed files with 96 additions and 41 deletions

View File

@ -218,7 +218,7 @@ abstract class AbstractConfigObject extends AbstractConfigValue implements Confi
public abstract AbstractConfigValue get(Object key);
@Override
protected abstract void render(StringBuilder sb, int indent, ConfigRenderOptions options);
protected abstract void render(StringBuilder sb, int indent, boolean atRoot, ConfigRenderOptions options);
private static UnsupportedOperationException weAreImmutable(String method) {
return new UnsupportedOperationException("ConfigObject is immutable, you can't call Map."

View File

@ -279,7 +279,7 @@ abstract class AbstractConfigValue implements ConfigValue, MergeableValue {
@Override
public final String toString() {
StringBuilder sb = new StringBuilder();
render(sb, 0, null /* atKey */, ConfigRenderOptions.concise());
render(sb, 0, true /* atRoot */, null /* atKey */, ConfigRenderOptions.concise());
return getClass().getSimpleName() + "(" + sb.toString() + ")";
}
@ -293,7 +293,7 @@ abstract class AbstractConfigValue implements ConfigValue, MergeableValue {
}
}
protected void render(StringBuilder sb, int indent, String atKey, ConfigRenderOptions options) {
protected void render(StringBuilder sb, int indent, boolean atRoot, String atKey, ConfigRenderOptions options) {
if (atKey != null) {
String renderedKey;
if (options.getJson())
@ -318,10 +318,10 @@ abstract class AbstractConfigValue implements ConfigValue, MergeableValue {
}
}
}
render(sb, indent, options);
render(sb, indent, atRoot, options);
}
protected void render(StringBuilder sb, int indent, ConfigRenderOptions options) {
protected void render(StringBuilder sb, int indent, boolean atRoot, ConfigRenderOptions options) {
Object u = unwrapped();
sb.append(u.toString());
}
@ -334,7 +334,7 @@ abstract class AbstractConfigValue implements ConfigValue, MergeableValue {
@Override
public final String render(ConfigRenderOptions options) {
StringBuilder sb = new StringBuilder();
render(sb, 0, null, options);
render(sb, 0, true, null, options);
return sb.toString();
}

View File

@ -232,9 +232,9 @@ final class ConfigConcatenation extends AbstractConfigValue implements Unmergeab
}
@Override
protected void render(StringBuilder sb, int indent, ConfigRenderOptions options) {
protected void render(StringBuilder sb, int indent, boolean atRoot, ConfigRenderOptions options) {
for (AbstractConfigValue p : pieces) {
p.render(sb, indent, options);
p.render(sb, indent, atRoot, options);
}
}

View File

@ -216,12 +216,12 @@ final class ConfigDelayedMerge extends AbstractConfigValue implements Unmergeabl
}
@Override
protected void render(StringBuilder sb, int indent, String atKey, ConfigRenderOptions options) {
render(stack, sb, indent, atKey, options);
protected void render(StringBuilder sb, int indent, boolean atRoot, String atKey, ConfigRenderOptions options) {
render(stack, sb, indent, atRoot, atKey, options);
}
// static method also used by ConfigDelayedMergeObject.
static void render(List<AbstractConfigValue> stack, StringBuilder sb, int indent, String atKey,
static void render(List<AbstractConfigValue> stack, StringBuilder sb, int indent, boolean atRoot, String atKey,
ConfigRenderOptions options) {
boolean commentMerge = options.getComments();
if (commentMerge) {
@ -268,7 +268,7 @@ final class ConfigDelayedMerge extends AbstractConfigValue implements Unmergeabl
else
sb.append(":");
}
v.render(sb, indent, options);
v.render(sb, indent, atRoot, options);
sb.append(",");
if (options.getFormatted())
sb.append('\n');

View File

@ -179,13 +179,13 @@ final class ConfigDelayedMergeObject extends AbstractConfigObject implements Unm
}
@Override
protected void render(StringBuilder sb, int indent, String atKey, ConfigRenderOptions options) {
ConfigDelayedMerge.render(stack, sb, indent, atKey, options);
protected void render(StringBuilder sb, int indent, boolean atRoot, String atKey, ConfigRenderOptions options) {
ConfigDelayedMerge.render(stack, sb, indent, atRoot, atKey, options);
}
@Override
protected void render(StringBuilder sb, int indent, ConfigRenderOptions options) {
render(sb, indent, null, options);
protected void render(StringBuilder sb, int indent, boolean atRoot, ConfigRenderOptions options) {
render(sb, indent, atRoot, null, options);
}
private static ConfigException notResolved() {

View File

@ -42,7 +42,7 @@ final class ConfigNull extends AbstractConfigValue implements Serializable {
}
@Override
protected void render(StringBuilder sb, int indent, ConfigRenderOptions options) {
protected void render(StringBuilder sb, int indent, boolean atRoot, ConfigRenderOptions options) {
sb.append("null");
}

View File

@ -131,7 +131,7 @@ final class ConfigReference extends AbstractConfigValue implements Unmergeable {
}
@Override
protected void render(StringBuilder sb, int indent, ConfigRenderOptions options) {
protected void render(StringBuilder sb, int indent, boolean atRoot, ConfigRenderOptions options) {
sb.append(expr.toString());
}

View File

@ -37,7 +37,7 @@ final class ConfigString extends AbstractConfigValue implements Serializable {
}
@Override
protected void render(StringBuilder sb, int indent, ConfigRenderOptions options) {
protected void render(StringBuilder sb, int indent, boolean atRoot, ConfigRenderOptions options) {
String rendered;
if (options.getJson())
rendered = ConfigImplUtil.renderJsonString(value);

View File

@ -167,7 +167,7 @@ final class SimpleConfigList extends AbstractConfigValue implements ConfigList,
}
@Override
protected void render(StringBuilder sb, int indent, ConfigRenderOptions options) {
protected void render(StringBuilder sb, int indent, boolean atRoot, ConfigRenderOptions options) {
if (value.isEmpty()) {
sb.append("[]");
} else {
@ -191,7 +191,7 @@ final class SimpleConfigList extends AbstractConfigValue implements ConfigList,
}
indent(sb, indent + 1, options);
v.render(sb, indent + 1, options);
v.render(sb, indent + 1, atRoot, options);
sb.append(",");
if (options.getFormatted())
sb.append('\n');

View File

@ -364,17 +364,22 @@ final class SimpleConfigObject extends AbstractConfigObject implements Serializa
}
@Override
protected void render(StringBuilder sb, int indent, ConfigRenderOptions options) {
protected void render(StringBuilder sb, int indent, boolean atRoot, ConfigRenderOptions options) {
if (isEmpty()) {
sb.append("{}");
} else {
boolean outerBraces = indent > 0 || options.getJson();
boolean outerBraces = options.getJson() || !atRoot;
if (outerBraces)
int innerIndent;
if (outerBraces) {
innerIndent = indent + 1;
sb.append("{");
if (options.getFormatted())
sb.append('\n');
if (options.getFormatted())
sb.append('\n');
} else {
innerIndent = indent;
}
int separatorCount = 0;
for (String k : keySet()) {
@ -382,14 +387,14 @@ final class SimpleConfigObject extends AbstractConfigObject implements Serializa
v = value.get(k);
if (options.getOriginComments()) {
indent(sb, indent + 1, options);
indent(sb, innerIndent, options);
sb.append("# ");
sb.append(v.origin().description());
sb.append("\n");
}
if (options.getComments()) {
for (String comment : v.origin().comments()) {
indent(sb, indent + 1, options);
indent(sb, innerIndent, options);
sb.append("#");
if (!comment.startsWith(" "))
sb.append(' ');
@ -397,8 +402,8 @@ final class SimpleConfigObject extends AbstractConfigObject implements Serializa
sb.append("\n");
}
}
indent(sb, indent + 1, options);
v.render(sb, indent + 1, k, options);
indent(sb, innerIndent, options);
v.render(sb, innerIndent, false /* atRoot */, k, options);
if (options.getFormatted()) {
if (options.getJson()) {
@ -415,14 +420,18 @@ final class SimpleConfigObject extends AbstractConfigObject implements Serializa
}
// chop last commas/newlines
sb.setLength(sb.length() - separatorCount);
if (options.getFormatted()) {
sb.append("\n"); // put a newline back
indent(sb, indent, options);
}
if (outerBraces)
if (outerBraces) {
if (options.getFormatted()) {
sb.append('\n'); // put a newline back
if (outerBraces)
indent(sb, indent, options);
}
sb.append("}");
}
}
if (atRoot && options.getFormatted())
sb.append('\n');
}
@Override

View File

@ -17,20 +17,66 @@ object RenderExample extends App {
.withFallback(ConfigFactory.parseResourcesAnySyntax(classOf[ConfigFactory], "/" + what))
.withFallback(ConfigFactory.defaultReference())
println("=== BEGIN UNRESOLVED toString() " + what)
print(conf.root.toString())
println("=== END UNRESOLVED toString() " + what)
println("=== BEGIN UNRESOLVED " + what)
println(conf.root.render(options))
print(conf.root.render(options))
println("=== END UNRESOLVED " + what)
println("=== BEGIN RESOLVED " + what)
println(conf.resolve().root.render(options))
print(conf.resolve().root.render(options))
println("=== END RESOLVED " + what)
println("=== BEGIN UNRESOLVED toString() " + what)
println(conf.root.toString())
println("=== END UNRESOLVED toString() " + what)
}
render("test01")
render("test06")
render("test05")
}
object RenderOptions extends App {
val conf = ConfigFactory.parseString(
"""
foo=[1,2,3]
# comment1
bar {
a = 42
#comment2
b = { c = "hello", d = true }
# comment3
e = ${something}
f = {}
}
""")
// ah, efficiency
def allBooleanLists(length: Int): Seq[Seq[Boolean]] = {
if (length == 0) {
Seq(Nil)
} else {
val tails = allBooleanLists(length - 1)
(tails map { false +: _ }) ++ (tails map { true +: _ })
}
}
val rendered =
allBooleanLists(4).foldLeft(0) { (count, values) =>
val formatted = values(0)
val originComments = values(1)
val comments = values(2)
val json = values(3)
val options = ConfigRenderOptions.defaults()
.setFormatted(formatted)
.setOriginComments(originComments)
.setComments(comments)
.setJson(json)
val renderSpec = options.toString.replace("ConfigRenderOptions", "")
println("=== " + count + " RENDER WITH " + renderSpec + "===")
print(conf.root.render(options))
println("=== " + count + " END RENDER WITH " + renderSpec + "===")
count + 1
}
println("Rendered " + rendered + " option combinations")
}