Skip to content

Commit

Permalink
Merge pull request #20 from Mohit-Sahu/develop
Browse files Browse the repository at this point in the history
Added Json-Schema   issue#15
  • Loading branch information
sathishk committed Jan 18, 2024
2 parents b2065ab + 6f9267e commit 6c2fa6b
Show file tree
Hide file tree
Showing 4 changed files with 308 additions and 0 deletions.
183 changes: 183 additions & 0 deletions src/main/java/com/techatpark/sjson/JsonSchema.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
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;

/**
* Json Schema that represents the schema document.
* Ref: https://json-schema.org/specification
*/
public class JsonSchema {

/**
* @param reader file reader for json schema
*/
public JsonSchema(final Reader reader) {

}

/**
* 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
*
* @param reader - file reader for json data
* @return object
* @throws IOException - throws io exception
*/
public Object read(final Reader reader) throws IOException {
return null;
}

/**
* Get Json text for the Map.
*
* @param jsonMap
* @return jsonText
*/
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();

valueText(builder, value);
}
return builder.append("}").toString();
}

/**
* Create Value in according to the Type.
*
* @param builder
* @param value
*/
private void valueText(final StringBuilder builder, final Object value) {
if (value == null) {
builder.append("null");
} else if (value instanceof String) {
processString(builder, (String) value);
} else if (value instanceof Map) {
builder.append(jsonText((Map<String, Object>)
value));
} else if (value instanceof List) {
builder.append(jsonText((Map<String, Object>) value));
} else {
builder.append(value);
}
}


/**
* Process String.
*
* @param builder
* @param value
*/
private void processString(final StringBuilder builder,
final String value) {
builder.append("\"")
.append(escapeJsonTxt(value))
.append("\"");
}

/**
* 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
*/
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);
}
}
}
}


}
22 changes: 22 additions & 0 deletions src/test/java/com/techatpark/sjson/JsonSchemaTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.techatpark.sjson;

import org.junit.jupiter.api.Test;

import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;

class JsonSchemaTest {

@Test
void read() throws IOException {

JsonSchema jsonSchema =
new JsonSchema(new FileReader("src/test/resources/schemas/product.json"));

jsonSchema.read(new FileReader("src/test/resources/schemas/person.json"));

jsonSchema.jsonText(new HashMap<>());

}
}
44 changes: 44 additions & 0 deletions src/test/resources/schemas/person.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://example.com/person.schema.json",
"title": "Person",
"type": "object",
"properties": {
"firstName": {
"type": "string",
"description": "The first name of the person."
},
"lastName": {
"type": "string",
"description": "The last name of the person."
},
"age": {
"type": "integer",
"minimum": 0,
"description": "The age of the person."
},
"address": {
"type": "object",
"properties": {
"street": {
"type": "string",
"description": "The street name of the address."
},
"city": {
"type": "string",
"description": "The city of the address."
},
"zipcode": {
"type": "string",
"pattern": "\\d{5}",
"description": "The ZIP code of the address (5 digits)."
}
},
"required": ["street", "city", "zipcode"],
"additionalProperties": false,
"description": "The address of the person."
}
},
"required": ["firstName", "lastName"],
"additionalProperties": false
}
59 changes: 59 additions & 0 deletions src/test/resources/schemas/product.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
{
"$schema": "https://json-schema.org/draft/-/schema",
"$id": "https://example.com/product.schema.json",
"title": "Product",
"description": "A product from Acme's catalog",
"type": "object",
"properties": {
"productId": {
"description": "The unique identifier for a product",
"type": "integer"
},
"productName": {
"description": "Name of the product",
"type": "string"
},
"price": {
"description": "The price of the product",
"type": "number",
"exclusiveMinimum":
},
"tags": {
"description": "Tags for the product",
"type": "array",
"items": {
"type": "string"
},
"minItems":,
"uniqueItems": true
},
"dimensions": {
"type": "object",
"properties": {
"length": {
"type": "number"
},
"width": {
"type": "number"
},
"height": {
"type": "number"
}
},
"required": [
"length",
"width",
"height"
]
},
"warehouseLocation": {
"description": "Coordinates of the warehouse where the product is located.",
"$ref": "https://example.com/geographical-location.schema.json"
}
},
"required": [
"productId",
"productName",
"price"
]
}

0 comments on commit 6c2fa6b

Please sign in to comment.