|
|
|
@ -25,77 +25,96 @@ public class JsonFormatter {
|
|
|
|
|
|
|
|
|
|
private static final String NEW_LINE = System.getProperty("line.separator"); |
|
|
|
|
|
|
|
|
|
private static final int MODE_SINGLE = 100; |
|
|
|
|
private static final int MODE_DOUBLE = 101; |
|
|
|
|
private static final int MODE_ESCAPE_SINGLE = 102; |
|
|
|
|
private static final int MODE_ESCAPE_DOUBLE = 103; |
|
|
|
|
private static final int MODE_BETWEEN = 104; |
|
|
|
|
|
|
|
|
|
private static void appendIndent(StringBuilder sb, int count) { |
|
|
|
|
for (; count > 0; --count) sb.append(INDENT); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static boolean isEscaped(StringBuilder sb, int index) { |
|
|
|
|
boolean escaped = false; |
|
|
|
|
int idx = Math.min(index, sb.length()); |
|
|
|
|
try { |
|
|
|
|
while (idx > 0 && sb.charAt(--idx) == '\\') { |
|
|
|
|
escaped = !escaped; |
|
|
|
|
} |
|
|
|
|
} catch (Exception e){ |
|
|
|
|
logger.warn("Failed to check escaped ", e); |
|
|
|
|
} |
|
|
|
|
return escaped; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static String prettyPrint(String input) { |
|
|
|
|
|
|
|
|
|
input = input.replaceAll("[\\r\\n]", ""); |
|
|
|
|
|
|
|
|
|
StringBuilder output = new StringBuilder(input.length() * 2); |
|
|
|
|
boolean quoteOpened = false; |
|
|
|
|
int mode = MODE_BETWEEN; |
|
|
|
|
int depth = 0; |
|
|
|
|
|
|
|
|
|
for (int i = 0; i < input.length(); ++i) { |
|
|
|
|
char ch = input.charAt(i); |
|
|
|
|
|
|
|
|
|
switch (mode) { |
|
|
|
|
case MODE_BETWEEN: |
|
|
|
|
switch (ch) { |
|
|
|
|
case '{': |
|
|
|
|
case '[': |
|
|
|
|
output.append(ch); |
|
|
|
|
if (!quoteOpened) { |
|
|
|
|
output.append(NEW_LINE); |
|
|
|
|
appendIndent(output, ++depth); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case '}': |
|
|
|
|
case ']': |
|
|
|
|
if (quoteOpened) |
|
|
|
|
output.append(ch); |
|
|
|
|
else { |
|
|
|
|
output.append(NEW_LINE); |
|
|
|
|
appendIndent(output, --depth); |
|
|
|
|
output.append(ch); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case '"': |
|
|
|
|
case '\'': |
|
|
|
|
output.append(ch); |
|
|
|
|
if (quoteOpened) { |
|
|
|
|
if (!isEscaped(output, i)) |
|
|
|
|
quoteOpened = false; |
|
|
|
|
} else quoteOpened = true; |
|
|
|
|
break; |
|
|
|
|
case ',': |
|
|
|
|
output.append(ch); |
|
|
|
|
if (!quoteOpened) { |
|
|
|
|
output.append(NEW_LINE); |
|
|
|
|
appendIndent(output, depth); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case ':': |
|
|
|
|
if (quoteOpened) output.append(ch); |
|
|
|
|
else output.append(" : "); |
|
|
|
|
output.append(" : "); |
|
|
|
|
break; |
|
|
|
|
case '\'': |
|
|
|
|
output.append(ch); |
|
|
|
|
mode = MODE_SINGLE; |
|
|
|
|
break; |
|
|
|
|
case '"': |
|
|
|
|
output.append(ch); |
|
|
|
|
mode = MODE_DOUBLE; |
|
|
|
|
break; |
|
|
|
|
case ' ': |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
if (quoteOpened || !(ch == ' ')) |
|
|
|
|
output.append(ch); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case MODE_ESCAPE_SINGLE: |
|
|
|
|
output.append(ch); |
|
|
|
|
mode = MODE_SINGLE; |
|
|
|
|
break; |
|
|
|
|
case MODE_ESCAPE_DOUBLE: |
|
|
|
|
output.append(ch); |
|
|
|
|
mode = MODE_DOUBLE; |
|
|
|
|
break; |
|
|
|
|
case MODE_SINGLE: |
|
|
|
|
output.append(ch); |
|
|
|
|
switch (ch) { |
|
|
|
|
case '\'': |
|
|
|
|
mode = MODE_BETWEEN; |
|
|
|
|
break; |
|
|
|
|
case '\\': |
|
|
|
|
mode = MODE_ESCAPE_SINGLE; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case MODE_DOUBLE: |
|
|
|
|
output.append(ch); |
|
|
|
|
switch (ch) { |
|
|
|
|
case '"': |
|
|
|
|
mode = MODE_BETWEEN; |
|
|
|
|
break; |
|
|
|
|
case '\\': |
|
|
|
|
mode = MODE_ESCAPE_DOUBLE; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return output.toString(); |
|
|
|
|
} |
|
|
|
|