Skip to content

Commit fecb38f

Browse files
committed
Refactor
1 parent 4ab8810 commit fecb38f

File tree

3 files changed

+56
-44
lines changed

3 files changed

+56
-44
lines changed

src/main/java/com/cdpn/jsonautorepair/JSONAutoRepairer.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
package com.cdpn.jsonautorepair;
22

3-
import com.cdpn.jsonautorepair.internal.BasicCorrector;
3+
44
import com.cdpn.jsonautorepair.internal.EscapeProcessor;
55
import com.google.gson.JsonElement;
66
import com.google.gson.JsonParser;
77
import com.google.gson.JsonSyntaxException;
88

99
public class JSONAutoRepairer {
10+
1011
public String repair(String json) {
1112
String processedJSON = json.trim();
1213
if(processedJSON.isEmpty()) {
@@ -21,6 +22,17 @@ public String repair(String json) {
2122
}
2223
}
2324

25+
private String wrapWithBracketWhenNotAJSONArray(String processedJSON) {
26+
if (!processedJSON.startsWith("{") && !processedJSON.startsWith("[")) {
27+
processedJSON = "{" + processedJSON;
28+
}
29+
30+
if (!processedJSON.endsWith("}") && !processedJSON.endsWith("]")) {
31+
processedJSON = processedJSON + "}";
32+
}
33+
return processedJSON;
34+
}
35+
2436
private String cleanupMarkdownJSONCodeBlock(String processedJSON) {
2537
if(processedJSON.startsWith("```json")) {
2638
processedJSON = processedJSON.substring(7);
@@ -32,8 +44,8 @@ private String cleanupMarkdownJSONCodeBlock(String processedJSON) {
3244
}
3345

3446
private String attemptToFix(String processedJSON) {
35-
BasicCorrector basicCorrector = new BasicCorrector();
36-
String fixedString = basicCorrector.fix(processedJSON);
47+
String fixedString = processedJSON.trim();
48+
fixedString = wrapWithBracketWhenNotAJSONArray(fixedString);
3749
EscapeProcessor internalQuoteEscapeProcessor = new EscapeProcessor(fixedString);
3850
fixedString = internalQuoteEscapeProcessor.process();
3951
try {

src/main/java/com/cdpn/jsonautorepair/internal/BasicCorrector.java

Lines changed: 0 additions & 21 deletions
This file was deleted.

src/main/java/com/cdpn/jsonautorepair/internal/EscapeProcessor.java

Lines changed: 41 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,35 @@
22

33
public class EscapeProcessor {
44
private static final char EOF = '\0';
5+
private static final char TAB_CHAR = '\t';
6+
private static final char BREAK_LINE_CHAR = '\n';
7+
private static final char SPACE_CHAR = ' ';
8+
59
private final String inputString;
610
private boolean inQuotes = false;
711
private StringBuilder escapedJson;
12+
813
public EscapeProcessor(String inputString) {
914
this.inputString = inputString;
1015
}
16+
17+
1118
public String process() {
1219
escapedJson = new StringBuilder();
1320
inQuotes = false;
1421
for (int i = 0; i < inputString.length(); i++) {
1522
char currentChar = inputString.charAt(i);
1623
if (currentChar != '\"') {
17-
processForNonQuoteCharacter(currentChar);
18-
continue;
24+
handleNonQuoteCharacter(currentChar);
25+
}
26+
else {
27+
handleQuoteCharacter(currentChar, i);
1928
}
20-
processQuoteCharacter(currentChar, i);
2129
}
2230
return escapedJson.toString();
2331
}
2432

25-
private void processQuoteCharacter(char currentChar, int i) {
33+
private void handleQuoteCharacter(char currentChar, int i) {
2634
if (!inQuotes) {
2735
inQuotes = true;
2836
escapedJson.append(currentChar);
@@ -33,39 +41,52 @@ private void processQuoteCharacter(char currentChar, int i) {
3341
escapedJson.append(currentChar);
3442
return;
3543
}
36-
if(findNextValidChar(i + 1) == '\"') {
37-
int nextValidCharPosition = getNextValidCharPosition(i + 1);
38-
if(isValidCloseQuote(nextValidCharPosition)) {
39-
escapedJson.append('\\');
40-
escapedJson.append(currentChar);
41-
return;
42-
}
43-
inQuotes = false;
44-
escapedJson.append(currentChar);
45-
escapedJson.append(',');
44+
if(hasNextQuoteRightAfterCurrentQuoteWithoutComma(i + 1)) {
45+
handleQuoteNextToQuoteCase(currentChar, i);
4646
return;
4747
}
4848
escapedJson.append('\\');
4949
escapedJson.append(currentChar);
5050
}
5151

52+
private void handleQuoteNextToQuoteCase(char currentChar, int i) {
53+
int nextQuotePosition = getNextValidCharPosition(i + 1);
54+
// If next valid quote is a good close quote, then the current quote MUST be an escaped quote
55+
if(isValidCloseQuote(nextQuotePosition)) {
56+
escapedJson.append('\\');
57+
escapedJson.append(currentChar);
58+
}
59+
else {
60+
// If the next valid quote is not a good close quote, then the current quote should be a good close quote
61+
// However, the current quote and the next quote is next to each other (without separation by a comma),
62+
// we need to add a comma in between
63+
inQuotes = false;
64+
escapedJson.append(currentChar);
65+
escapedJson.append(',');
66+
}
67+
}
68+
69+
private boolean hasNextQuoteRightAfterCurrentQuoteWithoutComma(int position) {
70+
return findNextValidChar(position + 1) == '\"';
71+
}
72+
5273
private int getNextValidCharPosition(int position) {
5374
for (int i = position; i < inputString.length(); i++) {
5475
char currentChar = inputString.charAt(i);
55-
if (currentChar != ' ' && currentChar != '\n' && currentChar != '\t') {
76+
if (currentChar != SPACE_CHAR && currentChar != BREAK_LINE_CHAR && currentChar != TAB_CHAR) {
5677
return i;
5778
}
5879
}
5980
return -1;
6081
}
6182

6283

63-
private void processForNonQuoteCharacter(char currentChar) {
84+
private void handleNonQuoteCharacter(char currentChar) {
6485
if (!inQuotes) {
6586
escapedJson.append(currentChar);
6687
return;
6788
}
68-
if(currentChar == '\t' || currentChar == '\n') {
89+
if(currentChar == TAB_CHAR || currentChar == BREAK_LINE_CHAR) {
6990
escapedJson.append(getEscapeSequence(currentChar));
7091
return;
7192
}
@@ -74,8 +95,8 @@ private void processForNonQuoteCharacter(char currentChar) {
7495

7596
private String getEscapeSequence(char currentChar) {
7697
return switch (currentChar) {
77-
case '\t' -> "\\t";
78-
case '\n' -> "\\n";
98+
case TAB_CHAR -> "\\t";
99+
case BREAK_LINE_CHAR -> "\\n";
79100
default -> "";
80101
};
81102
}
@@ -91,7 +112,7 @@ private boolean isValidCloseQuote(int i) {
91112
private char findNextValidChar(int position) {
92113
for (int i = position; i < inputString.length(); i++) {
93114
char currentChar = inputString.charAt(i);
94-
if (currentChar != ' ' && currentChar != '\n' && currentChar != '\t') {
115+
if (currentChar != SPACE_CHAR && currentChar != BREAK_LINE_CHAR && currentChar != TAB_CHAR) {
95116
return currentChar;
96117
}
97118
}

0 commit comments

Comments
 (0)