Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
.idea
.qodana
build
.intellijPlatform/
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.godwin.jsonparser.ui.IParserWidget;
import com.godwin.jsonparser.ui.dialog.OptionDialog;
import com.godwin.jsonparser.util.JsonDownloader;
import com.godwin.jsonparser.util.JsonUtils;
import com.godwin.jsonparser.util.NotificationUtil;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
Expand Down Expand Up @@ -120,6 +121,8 @@ private void setEventListeners() {
});
parseButton.addActionListener(e -> {
String jsonString = mInputEditor.getDocument().getText();
jsonString = JsonUtils.cleanUpJsonString(jsonString);

showBody(jsonString);
NotificationUtil.showDonateNotification();
});
Expand Down
88 changes: 88 additions & 0 deletions src/main/java/com/godwin/jsonparser/util/JsonUtils.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.godwin.jsonparser.util;

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.util.DefaultIndenter;
Expand Down Expand Up @@ -63,6 +64,93 @@ public static Object parseJson(String json, ObjectMapper objectMapper) throws Ex
}
}

/**
* Cleans up the JSON string by applying various cleanup methods.
* For now, it only ensures missing opening and closing braces are fixed.
* Other future methods that can be added are:
* 1. Missing only opening brace
* 2. Missing only closing brace
* 2. Missing comma
* 3. missing '"'
*/
public static String cleanUpJsonString(String jsonString) {
jsonString = jsonString.trim();

// If it's already valid, return as is.
if (isValidJson(jsonString)) {
return jsonString;
}

//attempt to fix json

// Check if the start or end braces is missing
if (!jsonString.startsWith("{") || !jsonString.endsWith("}")) {
String fixedJsonString = fixMissingBraces(jsonString);

// Validate after adding missing braces
if (isValidJson(fixedJsonString)) {
return fixedJsonString;
}
}

//Return the JSON in the original form
return jsonString;
}

/**
* Checks if the given JSON string is valid.
* @param jsonString The JSON string to validate.
* @return true if the JSON is valid, false otherwise.
*/
private static boolean isValidJson(String jsonString) {
try (JsonParser parser = new JsonFactory().createParser(jsonString)) {
//noinspection StatementWithEmptyBody
while (parser.nextToken() != null) {
// If we can iterate through tokens then it's valid JSON
}
return true;
} catch (Exception e) {
return false; // Invalid JSON
}
}

/**
* Fixes missing opening and closing braces in the JSON string.
* @param jsonString The JSON string to fix.
* @return A properly wrapped JSON string.
*/
private static String fixMissingBraces(String jsonString) {
jsonString = jsonString.trim();

int openBracesCount = 0;
int closeBracesCount = 0;
boolean inString = false;

// Count `{` and `}` braces outside of string values
for (int i = 0; i < jsonString.length(); i++) {
char ch = jsonString.charAt(i);

if (ch == '"') {
// Toggle inString when encountering an unescaped quote
boolean isEscaped = i > 0 && jsonString.charAt(i - 1) == '\\';
if (!isEscaped) {
inString = !inString;
}
}

if (!inString) {
if (ch == '{') openBracesCount++;
if (ch == '}') closeBracesCount++;
}
}

if (openBracesCount == closeBracesCount && !jsonString.startsWith("{")) {
jsonString = "{" + jsonString + "}";
}

return jsonString;
}

/* public static String minifyJson(String jsonStr) throws JsonProcessingException {
Object jsonObject = Holder.MAPPER.readValue(jsonStr, Object.class);
return Holder.MAPPER.writeValueAsString(jsonObject);
Expand Down
52 changes: 52 additions & 0 deletions src/test/java/jsonparser/util/JsonUtilsTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package jsonparser.util;

import com.godwin.jsonparser.util.JsonUtils;
import org.junit.Test;

import static org.junit.Assert.assertEquals;

public class JsonUtilsTest {

@Test
public void testValidJson_remainsUnchanged() {
String json = "{\"first_Name\": \"John\", \"last_Name\": \"Doe\",\"Age\": 20}";
assertEquals(json, JsonUtils.cleanUpJsonString(json));
}

@Test
public void testValidJson_containsBraceInElement_remainsUnchanged() {
String json = "{\"first_Name\": \"Joh}}n\", \"last{_Name\": \"Doe\",\"Age\": 20}";
assertEquals(json, JsonUtils.cleanUpJsonString(json));
}

@Test
public void testMissingBothBraces() {
String json = "\"first_Name\": \"John\", \"last_Name\": \"Doe\",\"Age\": 20";
String expected = "{\"first_Name\": \"John\", \"last_Name\": \"Doe\",\"Age\": 20}";
assertEquals(expected, JsonUtils.cleanUpJsonString(json));
}

@Test
public void testMissingBothBraces_containsBraceInElement() {
String json = "\"first_N{ame\": \"John\", \"last_N{{ame\": \"Do}e\",\"Age\": 20";
String expected = "{\"first_N{ame\": \"John\", \"last_N{{ame\": \"Do}e\",\"Age\": 20}";
assertEquals(expected, JsonUtils.cleanUpJsonString(json));
}

// A Brace is present at the closing, but it's not the closing brace
@Test
public void testMissingBothBraces_where_aClosingBraceIsPresent() {
String json = "\"first_Name\":\"John\",\"last_Name\":\"Doe\",\"Age\":20,\"department\":{\"name\":\"sales\"}";
String expected = "{\"first_Name\":\"John\",\"last_Name\":\"Doe\",\"Age\":20,\"department\":{\"name\":\"sales\"}}";
assertEquals(expected, JsonUtils.cleanUpJsonString(json));
}

// A Brace is present at the closing, but it's not the closing brace
@Test
public void testMissingBothBraces_containsBraceInElement_where_aClosingBraceIsPresent() {
String json = "\"first_Name\":\"John\",\"last_Name\":\"Doe}}\",\"Age{\":20,\"department\":{\"name\":\"sales\"}";
String expected = "{\"first_Name\":\"John\",\"last_Name\":\"Doe}}\",\"Age{\":20,\"department\":{\"name\":\"sales\"}}";
assertEquals(expected, JsonUtils.cleanUpJsonString(json));
}

}