-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #24 from Mohit-Sahu/develop
sample-product json added as per the last suggestion
- Loading branch information
Showing
4 changed files
with
132 additions
and
190 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,183 +1,105 @@ | ||
package com.techatpark.sjson; | ||
|
||
import com.techatpark.sjson.util.NumberParser; | ||
|
||
|
||
|
||
import java.io.IOException; | ||
import java.io.Reader; | ||
|
||
import java.io.IOException; | ||
import java.io.Reader; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.StringJoiner; | ||
|
||
/** | ||
* Json Schema that represents the schema document. | ||
* Ref: https://json-schema.org/specification | ||
* Represents a JSON schema document. Provides functionality to serialize | ||
* Java objects to JSON strings. | ||
*/ | ||
public class JsonSchema { | ||
public final class JsonSchema { | ||
|
||
/** | ||
* @param reader file reader for json schema | ||
* Constructor for JsonSchema. | ||
*/ | ||
public JsonSchema(final Reader reader) { | ||
|
||
public JsonSchema() { | ||
// Constructor logic if any | ||
} | ||
|
||
/** | ||
* Reads JSON as a Java Object. | ||
* <p> | ||
* It will return native java objects as given below based | ||
* on JSON Data Type. | ||
* Ref: https://www.w3schools.com/js/js_json_datatypes.asp | ||
* <p> | ||
* string - java.lang.String | ||
* number - java.lang.Number | ||
* object - java.util.Map | ||
* array - java.util.List | ||
* boolean - java.lang.Boolean | ||
* null - null | ||
* Reads JSON from a Reader and converts it into a Java Object. | ||
* This method is not yet implemented. | ||
* | ||
* @param reader - file reader for json data | ||
* @return object | ||
* @throws IOException - throws io exception | ||
* @param reader the Reader to read JSON data from | ||
* @return Object representation of the read JSON | ||
* @throws IOException if an I/O error occurs | ||
*/ | ||
public Object read(final Reader reader) throws IOException { | ||
return null; | ||
throw new UnsupportedOperationException("Not yet implemented"); | ||
} | ||
|
||
/** | ||
* Get Json text for the Map. | ||
* Converts a Map into its JSON string representation. | ||
* | ||
* @param jsonMap | ||
* @return jsonText | ||
* @param jsonMap the Map representing the JSON object | ||
* @return the JSON string representation of the Map | ||
*/ | ||
public String jsonText(final Map<String, Object> jsonMap) { | ||
StringBuilder builder = new StringBuilder(); | ||
boolean isFirst = true; | ||
builder.append("{"); | ||
for (Map.Entry<String, Object> entry : jsonMap.entrySet()) { | ||
if (isFirst) { | ||
isFirst = false; | ||
} else { | ||
builder.append(","); | ||
} | ||
// Create Key enclosed with " | ||
builder.append("\"") | ||
.append(escapeJsonTxt(entry.getKey())) | ||
.append("\":"); // Create Key value separator | ||
|
||
Object value = entry.getValue(); | ||
StringJoiner joiner = new StringJoiner(",", "{", "}"); | ||
jsonMap.forEach((final String key, final Object value) -> | ||
joiner.add(formatEntry(key, value))); | ||
return joiner.toString(); | ||
} | ||
|
||
valueText(builder, value); | ||
} | ||
return builder.append("}").toString(); | ||
/** | ||
* Formats a key-value pair into a JSON entry. | ||
* | ||
* @param key the key in the map | ||
* @param value the value corresponding to the key | ||
* @return formatted JSON entry | ||
*/ | ||
private String formatEntry(final String key, final Object value) { | ||
return String.format("\"%s\":%s", escapeJson(key), valueToJson(value)); | ||
} | ||
|
||
/** | ||
* Create Value in according to the Type. | ||
* Converts a value to its JSON representation. | ||
* | ||
* @param builder | ||
* @param value | ||
* @param value the value to convert | ||
* @return JSON representation of the value | ||
*/ | ||
private void valueText(final StringBuilder builder, final Object value) { | ||
private String valueToJson(final Object value) { | ||
if (value == null) { | ||
builder.append("null"); | ||
return "null"; | ||
} else if (value instanceof String) { | ||
processString(builder, (String) value); | ||
return "\"" + escapeJson((String) value) + "\""; | ||
} else if (value instanceof Map) { | ||
builder.append(jsonText((Map<String, Object>) | ||
value)); | ||
return jsonText((Map<String, Object>) value); | ||
} else if (value instanceof List) { | ||
builder.append(jsonText((Map<String, Object>) value)); | ||
return listToJson((List<?>) value); | ||
} else { | ||
builder.append(value); | ||
return value.toString(); | ||
} | ||
} | ||
|
||
|
||
/** | ||
* Process String. | ||
* Converts a list to its JSON array representation. | ||
* | ||
* @param builder | ||
* @param value | ||
* @param list the list to convert | ||
* @return JSON array representation of the list | ||
*/ | ||
private void processString(final StringBuilder builder, | ||
final String value) { | ||
builder.append("\"") | ||
.append(escapeJsonTxt(value)) | ||
.append("\""); | ||
private String listToJson(final List<?> list) { | ||
StringJoiner sj = new StringJoiner(",", "[", "]"); | ||
list.forEach(obj -> sj.add(valueToJson(obj))); | ||
return sj.toString(); | ||
} | ||
|
||
/** | ||
* Escape JSON Text. | ||
* Escape quotes, \, /, \r, \n, \b, \f, \t | ||
* and other control characters (U+0000 through U+001F). | ||
* @param s | ||
* @return escapeJsonTxt | ||
*/ | ||
private String escapeJsonTxt(final String s) { | ||
if (s == null) { | ||
return null; | ||
} | ||
StringBuilder sb = new StringBuilder(); | ||
escape(s, sb); | ||
return sb.toString(); | ||
} | ||
|
||
/** | ||
* Escape Text. | ||
* @param s - Must not be null. | ||
* @param sb | ||
* Escapes special characters in a JSON string. | ||
* | ||
* @param text the string to escape | ||
* @return escaped JSON string | ||
*/ | ||
private void escape(final String s, final StringBuilder sb) { | ||
final int len = s.length(); | ||
for (int i = 0; i < len; i++) { | ||
char ch = s.charAt(i); | ||
switch (ch) { | ||
case '"': | ||
sb.append("\\\""); | ||
break; | ||
case '\\': | ||
sb.append("\\\\"); | ||
break; | ||
case '\b': | ||
sb.append("\\b"); | ||
break; | ||
case '\f': | ||
sb.append("\\f"); | ||
break; | ||
case '\n': | ||
sb.append("\\n"); | ||
break; | ||
case '\r': | ||
sb.append("\\r"); | ||
break; | ||
case '\t': | ||
sb.append("\\t"); | ||
break; | ||
case '/': | ||
sb.append("\\/"); | ||
break; | ||
default: | ||
//Reference: http://www.unicode.org/versions/Unicode5.1.0/ | ||
if ((ch >= '\u0000' && ch <= '\u001F') | ||
|| (ch >= '\u007F' && ch <= '\u009F') | ||
|| (ch >= '\u2000' && ch <= '\u20FF')) { | ||
String ss = Integer.toHexString(ch); | ||
sb.append("\\u"); | ||
for (int k = 0; k < NumberParser.NUMBER_FOUR | ||
- ss.length(); k++) { | ||
sb.append('0'); | ||
} | ||
sb.append(ss.toUpperCase()); | ||
} else { | ||
sb.append(ch); | ||
} | ||
} | ||
} | ||
private String escapeJson(final String text) { | ||
return text.replace("\\", "\\\\") | ||
.replace("\"", "\\\"") | ||
.replace("\b", "\\b") | ||
.replace("\f", "\\f") | ||
.replace("\n", "\\n") | ||
.replace("\r", "\\r") | ||
.replace("\t", "\\t"); | ||
} | ||
|
||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,76 @@ | ||
package com.techatpark.sjson; | ||
|
||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import java.io.FileReader; | ||
import java.io.IOException; | ||
import java.util.Arrays; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
class JsonSchemaTest { | ||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import static org.junit.jupiter.api.Assertions.assertThrows; | ||
|
||
public class JsonSchemaTest { | ||
|
||
private JsonSchema jsonSchema; | ||
|
||
@BeforeEach | ||
public void setUp() { | ||
jsonSchema = new JsonSchema(); | ||
} | ||
|
||
@Test | ||
public void testJsonTextWithSimpleMap() { | ||
Map<String, Object> jsonMap = new HashMap<>(); | ||
jsonMap.put("key1", "value1"); | ||
jsonMap.put("key2", 123); | ||
|
||
String expectedJson = "{\"key1\":\"value1\",\"key2\":123}"; | ||
assertEquals(expectedJson, jsonSchema.jsonText(jsonMap)); | ||
} | ||
|
||
@Test | ||
void read() throws IOException { | ||
public void testJsonTextWithNestedMap() { | ||
Map<String, Object> nestedMap = new HashMap<>(); | ||
nestedMap.put("nestedKey1", "nestedValue1"); | ||
|
||
JsonSchema jsonSchema = | ||
new JsonSchema(new FileReader("src/test/resources/schemas/product.json")); | ||
Map<String, Object> jsonMap = new HashMap<>(); | ||
jsonMap.put("key1", "value1"); | ||
jsonMap.put("key2", nestedMap); | ||
|
||
jsonSchema.read(new FileReader("src/test/resources/schemas/person.json")); | ||
String expectedJson = "{\"key1\":\"value1\",\"key2\":{\"nestedKey1\":\"nestedValue1\"}}"; | ||
assertEquals(expectedJson, jsonSchema.jsonText(jsonMap)); | ||
} | ||
|
||
jsonSchema.jsonText(new HashMap<>()); | ||
@Test | ||
public void testJsonTextWithList() { | ||
List<Object> list = Arrays.asList("item1", 123, true); | ||
|
||
Map<String, Object> jsonMap = new HashMap<>(); | ||
jsonMap.put("key1", list); | ||
|
||
String expectedJson = "{\"key1\":[\"item1\",123,true]}"; | ||
assertEquals(expectedJson, jsonSchema.jsonText(jsonMap)); | ||
} | ||
|
||
@Test | ||
public void testJsonTextWithSpecialCharacters() { | ||
Map<String, Object> jsonMap = new HashMap<>(); | ||
jsonMap.put("key1", "value \"1\""); | ||
jsonMap.put("key2", "line\nbreak"); | ||
|
||
String expectedJson = "{\"key1\":\"value \\\"1\\\"\",\"key2\":\"line\\nbreak\"}"; | ||
assertEquals(expectedJson, jsonSchema.jsonText(jsonMap)); | ||
} | ||
|
||
@Test | ||
public void testReadMethodNotImplemented() { | ||
Exception exception = assertThrows(UnsupportedOperationException.class, () -> { | ||
jsonSchema.read(null); | ||
}); | ||
|
||
String expectedMessage = "Not yet implemented"; | ||
assertEquals(expectedMessage, exception.getMessage()); | ||
} | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"firstName": "John", | ||
"lastName": "Doe", | ||
"age": 30, | ||
"address": { | ||
"street": "123 Main St", | ||
"city": "Anytown", | ||
"zipcode": "12345" | ||
} | ||
} |