Fixed Issue 153 by using a stack to keep track of first elements at any level.

This commit is contained in:
Inderjeet Singh 2009-09-29 17:52:49 +00:00
parent 3e7ebf8556
commit e9a2a1d0f7
2 changed files with 33 additions and 18 deletions

View File

@ -19,6 +19,7 @@ package com.google.gson;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
/**
* Formats Json in a nicely indented way with a specified print margin.
@ -143,67 +144,66 @@ final class JsonPrintFormatter implements JsonFormatter {
}
private class PrintFormattingVisitor implements JsonElementVisitor {
private final Map<Integer, Boolean> firstArrayElement;
private final Map<Integer, Boolean> firstObjectMember;
private final Stack<Boolean> firstElementInLevel;
private final JsonWriter writer;
private final Escaper escaper;
private final boolean serializeNulls;
private int level = 0;
PrintFormattingVisitor(JsonWriter writer, Escaper escaper, boolean serializeNulls) {
this.writer = writer;
this.escaper = escaper;
this.serializeNulls = serializeNulls;
this.firstArrayElement = new HashMap<Integer, Boolean>();
this.firstObjectMember = new HashMap<Integer, Boolean>();
this.firstElementInLevel = new Stack<Boolean>();
}
private void addCommaCheckingFirst(Map<Integer, Boolean> first) throws IOException {
if (first.get(level) != Boolean.FALSE) {
first.put(level, false);
private void addCommaCheckingFirst() throws IOException {
if (firstElementInLevel.peek()) {
// No longer first
firstElementInLevel.pop();
firstElementInLevel.push(false);
} else {
writer.elementSeparator();
}
}
public void startArray(JsonArray array) throws IOException {
firstArrayElement.put(++level, true);
firstElementInLevel.push(true);
writer.beginArray();
}
public void visitArrayMember(JsonArray parent, JsonPrimitive member,
boolean isFirst) throws IOException {
addCommaCheckingFirst(firstArrayElement);
addCommaCheckingFirst();
writer.value(escapeJsonPrimitive(member));
}
public void visitArrayMember(JsonArray parent, JsonArray member,
boolean first) throws IOException {
addCommaCheckingFirst(firstArrayElement);
addCommaCheckingFirst();
}
public void visitArrayMember(JsonArray parent, JsonObject member,
boolean first) throws IOException {
addCommaCheckingFirst(firstArrayElement);
addCommaCheckingFirst();
}
public void visitNullArrayMember(JsonArray parent, boolean isFirst) throws IOException {
addCommaCheckingFirst(firstArrayElement);
addCommaCheckingFirst();
}
public void endArray(JsonArray array) {
level--;
writer.endArray();
firstElementInLevel.pop();
}
public void startObject(JsonObject object) throws IOException {
firstObjectMember.put(level, true);
firstElementInLevel.push(true);
writer.beginObject();
}
public void visitObjectMember(JsonObject parent, String memberName, JsonPrimitive member,
boolean isFirst) throws IOException {
addCommaCheckingFirst(firstObjectMember);
addCommaCheckingFirst();
writer.key(memberName);
writer.fieldSeparator();
writer.value(escapeJsonPrimitive(member));
@ -211,14 +211,14 @@ final class JsonPrintFormatter implements JsonFormatter {
public void visitObjectMember(JsonObject parent, String memberName, JsonArray member,
boolean isFirst) throws IOException {
addCommaCheckingFirst(firstObjectMember);
addCommaCheckingFirst();
writer.key(memberName);
writer.fieldSeparator();
}
public void visitObjectMember(JsonObject parent, String memberName, JsonObject member,
boolean isFirst) throws IOException {
addCommaCheckingFirst(firstObjectMember);
addCommaCheckingFirst();
writer.key(memberName);
writer.fieldSeparator();
}
@ -232,6 +232,7 @@ final class JsonPrintFormatter implements JsonFormatter {
public void endObject(JsonObject object) {
writer.endObject();
firstElementInLevel.pop();
}
public void visitPrimitive(JsonPrimitive primitive) throws IOException {

View File

@ -97,6 +97,20 @@ public class PrettyPrintingTest extends TestCase {
assertEquals("{\"abc\":1,\"def\":5}\n", json);
}
// In response to bug 153
public void testEmptyMapField() {
ClassWithMap obj = new ClassWithMap();
obj.map = new LinkedHashMap<String, Integer>();
String json = gson.toJson(obj);
assertTrue(json.contains("{\"map\":{},\"value\":2}"));
}
@SuppressWarnings("unused")
private static class ClassWithMap {
Map<String, Integer> map;
int value = 2;
}
public void testMultipleArrays() {
int[][][] ints = new int[][][] { { { 1 }, { 2 } } };
String json = gson.toJson(ints);