package org.json.simple.parser;
import org.json.simple.JSONObject;
import java.io.*;
/**
* @author karl.wettin@kodapan.se
* @since 2012-04-06 00:55
*/
public class JSONFormatter {
public String format(String input) throws Exception {
StringWriter buffer = new StringWriter((int) (input.length() * 1.1));
format(new StringReader(input), buffer);
return buffer.toString();
}
public JSONFormatter() {
}
public JSONFormatter(String indentationValue) {
this.indentationValue = indentationValue;
}
/**
* Two spaces
*/
public static String DEFAULT_INDENTATION_VALUE = " ";
private String indentationValue = DEFAULT_INDENTATION_VALUE;
public String getIndentationValue() {
return indentationValue;
}
public void setIndentationValue(String indentationValue) {
this.indentationValue = indentationValue;
}
public void format(Reader inputReader, Writer output) throws Exception {
BufferedJSONStreamReader input = new BufferedJSONStreamReader(inputReader);
int indentation = 0;
JSONStreamReader.Event event;
while ((event = input.next()) != null) {
if (event == JSONStreamReader.Event.START_DOCUMENT) {
} else if (event == JSONStreamReader.Event.START_OBJECT) {
JSONStreamReader.Event previous = input.back();
if (previous == JSONStreamReader.Event.NEXT_VALUE
|| previous == JSONStreamReader.Event.START_ELEMENT_KEY) {
// spacer already set
} else {
addIndentation(output, indentation);
}
input.next(); // reset
output.write('{');
output.write('\n');
indentation++;
} else if (event == JSONStreamReader.Event.END_OBJECT) {
indentation--;
addIndentation(output, indentation);
output.write('}');
if (input.next() != JSONStreamReader.Event.NEXT_VALUE) {
output.write('\n');
}
input.back(); // reset
} else if (event == JSONStreamReader.Event.START_ARRAY) {
JSONStreamReader.Event previous = input.back();
if (previous == JSONStreamReader.Event.NEXT_VALUE
|| previous == JSONStreamReader.Event.START_ELEMENT_KEY) {
// spacer already set
} else {
addIndentation(output, indentation);
}
input.next(); // reset
output.write('[');
output.write('\n');
indentation++;
} else if (event == JSONStreamReader.Event.END_ARRAY) {
indentation--;
addIndentation(output, indentation);
output.write(']');
if (input.next() != JSONStreamReader.Event.NEXT_VALUE) {
output.write('\n');
}
input.back(); // reset
} else if (event == JSONStreamReader.Event.NEXT_VALUE) {
JSONStreamReader.Event next = input.next();
if (next == JSONStreamReader.Event.END_ARRAY
|| next == JSONStreamReader.Event.END_OBJECT) {
// no need for this comma
output.write('\n');
} else {
output.write(',');
if (next == JSONStreamReader.Event.START_ELEMENT_KEY) {
output.write('\n');
} else {
output.write(' ');
}
}
input.back(); // reset
} else if (event == JSONStreamReader.Event.START_ELEMENT_KEY) {
addIndentation(output, indentation);
output.write('"');
output.write(JSONObject.escape(input.getStringValue()));
output.write('"');
output.write(" : ");
} else if (event == JSONStreamReader.Event.START_ELEMENT_VALUE) {
JSONStreamReader.Event previous = input.back();
if (previous == JSONStreamReader.Event.START_ARRAY
|| previous == JSONStreamReader.Event.NEXT_VALUE) {
addIndentation(output, indentation);
}
input.next(); // reset
if (input.getObjectValue() == null) {
output.write("null");
} else if (Boolean.class.equals(input.getObjectValue().getClass())) {
output.write(String.valueOf(input.getBooleanValue()));
} else if (String.class.equals(input.getObjectValue().getClass())) {
output.write('"');
output.write(JSONObject.escape(input.getStringValue()));
output.write('"');
} else if (Double.class.equals(input.getObjectValue().getClass())) {
output.write(input.getDoubleValue().toString());
} else if (Long.class.equals(input.getObjectValue().getClass())) {
output.write(input.getLongValue().toString());
} else {
throw new RuntimeException("Unsupported class: " + input.getObjectValue().getClass());
}
if (input.next() != JSONStreamReader.Event.NEXT_VALUE) {
output.write("\n");
}
input.back(); // reset
} else if (event == JSONStreamReader.Event.END_DOCUMENT) {
break;
} else {
throw new RuntimeException("Unexpected event " + event);
}
}
}
public void addIndentation(Writer output, int indentation) throws IOException {
for (int i = 0; i < indentation; i++) {
output.append(getIndentationValue());
}
}
}