-
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 #20 from Mohit-Sahu/develop
Added Json-Schema issue#15
- Loading branch information
Showing
4 changed files
with
308 additions
and
0 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 |
---|---|---|
@@ -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); | ||
} | ||
} | ||
} | ||
} | ||
|
||
|
||
} |
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,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<>()); | ||
|
||
} | ||
} |
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,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 | ||
} |
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,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" | ||
] | ||
} |