package misc;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.List;
import java.util.Map;
public class JsonWriter {
public static String toString(Object obj) {
StringWriter sw = new StringWriter();
try {
writeJSON(sw, obj);
sw.close();
} catch(IOException e) {
throw new AssertionError("this shouldn't happen", e);
}
return sw.toString();
}
public static void writeJSON(Writer w, Object obj) throws IOException {
if(obj instanceof Boolean) {
w.write((Boolean)obj ? "true" : "false");
} else if(obj instanceof Number) {
double d = ((Number)obj).doubleValue();
if(d == (double)(int)d)
w.write(String.valueOf((int)d));
else
w.write(String.valueOf(d));
} else if(obj == null) {
w.write("null");
} else if(obj instanceof String) {
w.write('"');
String s = (String)obj;
for(int k = 0; k < s.length(); k++) {
char c = s.charAt(k);
if(c == '\\' || c == '"') {
w.write('\\');
w.write(c);
} else if(c < 0x20) {
w.write("\\u00");
w.write(HEXDIGITS.charAt(c >> 4));
w.write(HEXDIGITS.charAt(c & 15));
} else
w.write(c);
}
w.write('"');
} else if(obj instanceof List<?>) {
w.write('[');
boolean first = true;
for(Object element : (List<?>)obj) {
if(first) first = false;
else w.write(',');
writeJSON(w, element);
}
w.write(']');
} else if(obj instanceof Map<?, ?>) {
w.write('{');
boolean first = true;
for(Map.Entry<?, ?> entry : ((Map<?,?>)obj).entrySet()) {
if(!(entry.getKey() instanceof String))
throw new IllegalArgumentException("Map keys must be strings. Found "+entry.getKey());
if(first) first = false;
else w.write(',');
writeJSON(w, entry.getKey());
w.write(':');
writeJSON(w, entry.getValue());
}
w.write('}');
} else {
throw new IllegalArgumentException("Not a valid JSON value: "+obj+" of type "+obj.getClass().getName());
}
}
private static final String HEXDIGITS = "0123456789ABCDEF";
}