Skip to content

Commit

Permalink
Feature/1.0.1 (#3)
Browse files Browse the repository at this point in the history
* Added tests for JsonObject and fixed a couple bugs that the tests found.

* Added tests for JsonArray.
Improved error messaging for when JsonElement type is not of desired type.

* Small helpers added to JsonArray and JsonObject to convert to JsonElement.

* Added JsonMapper interface with some default methods implemented for converting between JsonObject or JsonArray into java objects

* SolaJson now has several methods that utilize new JsonMapper.
Fixed another bug in JsonElement.
  • Loading branch information
iamdudeman authored Jan 17, 2022
1 parent 8aa8882 commit fc4b74c
Show file tree
Hide file tree
Showing 13 changed files with 501 additions and 12 deletions.
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ plugins {
id("java-library")
}

version = "1.0.0"
version = "1.0.1"

java {
sourceCompatibility = JavaVersion.VERSION_16
Expand Down
8 changes: 6 additions & 2 deletions src/main/java/technology/sola/json/JsonArray.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ public JsonArray(int initialCapacity) {
super(initialCapacity);
}

public JsonElement asElement() {
return new JsonElement(this);
}

public JsonObject getObject(int index) {
return get(index).asObject();
}
Expand Down Expand Up @@ -49,13 +53,13 @@ public boolean isNull(int index) {
public boolean add(JsonObject value) {
if (value == null) return addNull();

return add(new JsonElement(value));
return add(value.asElement());
}

public boolean add(JsonArray value) {
if (value == null) return addNull();

return add(new JsonElement(value));
return add(value.asElement());
}

public boolean add(String value) {
Expand Down
10 changes: 7 additions & 3 deletions src/main/java/technology/sola/json/JsonElement.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package technology.sola.json;

import technology.sola.json.exception.JsonElementTypeException;

public class JsonElement {
private final JsonValueType type;
private Object value;
Expand Down Expand Up @@ -54,7 +56,8 @@ public boolean asBoolean() {
}

public int asInt() {
return (int) asLong();
assertType(JsonValueType.LONG);
return ((Number) this.value).intValue();
}

public long asLong() {
Expand All @@ -63,7 +66,8 @@ public long asLong() {
}

public float asFloat() {
return (float) asDouble();
assertType(JsonValueType.DOUBLE);
return ((Number) this.value).floatValue();
}

public double asDouble() {
Expand Down Expand Up @@ -101,7 +105,7 @@ public String toString() {

private void assertType(JsonValueType assertionType) {
if (type != assertionType) {
throw new RuntimeException("Json value is not of desired type");
throw new JsonElementTypeException(assertionType.name(), type.name());
}
}

Expand Down
46 changes: 46 additions & 0 deletions src/main/java/technology/sola/json/JsonMapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package technology.sola.json;

import java.util.List;

public interface JsonMapper<T> {
/**
* Converts object of type T into a {@link JsonObject}.
*
* @param object the object to convert
* @return the {@code JsonObject} representing the converted object
*/
JsonObject toJson(T object);

/**
* Converts a {@link List} of T into a {@link JsonArray}.
*
* @param list the {@code List} to convert
* @return the converted {@code JsonArray}
*/
default JsonArray toJson(List<T> list) {
JsonArray jsonArray = new JsonArray(list.size());

list.forEach(item -> jsonArray.add(toJson(item)));

return jsonArray;
}

/**
* Converts a {@link JsonObject} into an object of type T.
*
* @param jsonObject the {@code JsonObject} to convert
* @return the converted object of type T
*/
T toObject(JsonObject jsonObject);

/**
* Converts a {@link JsonArray} into a {@link List} of desired type T. This assumes that each child of {@code jsonArray}
* is a {@link JsonObject} and of type T.
*
* @param jsonArray the {@code JsonArray} to convert
* @return the converted {@code List<T>}
*/
default List<T> toList(JsonArray jsonArray) {
return jsonArray.stream().map(item -> toObject(item.asObject())).toList();
}
}
10 changes: 7 additions & 3 deletions src/main/java/technology/sola/json/JsonObject.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ public JsonObject(int initialCapacity) {
super(initialCapacity);
}

public JsonElement asElement() {
return new JsonElement(this);
}

public JsonObject getObject(String key) {
return get(key).asObject();
}
Expand All @@ -32,7 +36,7 @@ public float getFloat(String key) {
return get(key).asFloat();
}

public double getInt(String key) {
public int getInt(String key) {
return get(key).asInt();
}

Expand Down Expand Up @@ -61,13 +65,13 @@ public JsonElement get(String key) {
public JsonElement put(String key, JsonObject value) {
if (value == null) return putNull(key);

return put(key, new JsonElement(value));
return put(key, value.asElement());
}

public JsonElement put(String key, JsonArray value) {
if (value == null) return putNull(key);

return put(key, new JsonElement(value));
return put(key, value.asElement());
}

public JsonElement put(String key, String value) {
Expand Down
50 changes: 50 additions & 0 deletions src/main/java/technology/sola/json/SolaJson.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import technology.sola.json.parser.Parser;
import technology.sola.json.token.Tokenizer;

import java.util.List;

/**
* SolaJson contains methods for parsing strings into {@link JsonElement}s and serializing {@code JsonElement}s into strings.
*/
Expand All @@ -23,6 +25,30 @@ public JsonElement parse(String jsonString) {
return visit(root);
}

/**
* Parses a JSON string into an object of type T using a {@link JsonMapper}.
*
* @param jsonString the JSON string to parse
* @param jsonMapper the {@code JsonMapper} to use during conversion
* @param <T> the type of the object to convert to
* @return the converted Java object of type T
*/
public <T> T parse(String jsonString, JsonMapper<T> jsonMapper) {
return jsonMapper.toObject(parse(jsonString).asObject());
}

/**
* Parses a JSON string into a {@link List} of type T using a {@link JsonMapper}.
*
* @param jsonString the JSON string to parse
* @param jsonMapper the {@code JsonMapper} to use during conversion
* @param <T> the type of the object to convert to
* @return the converted List of Java object of type T
*/
public <T> List<T> parseList(String jsonString, JsonMapper<T> jsonMapper) {
return jsonMapper.toList(parse(jsonString).asArray());
}

/**
* Serializes as {@link JsonElement}.
*
Expand Down Expand Up @@ -53,6 +79,30 @@ public String serialize(JsonArray jsonArray) {
return jsonArray.toString();
}

/**
* Serializes an object of type T to a string using a {@link JsonMapper}.
*
* @param object the object to serialize
* @param jsonMapper the {@code JsonMapper} to use during conversion
* @param <T> the type of the object to serialize
* @return serialized JSON string
*/
public <T> String serialize(T object, JsonMapper<T> jsonMapper) {
return serialize(jsonMapper.toJson(object));
}

/**
* Serializes a list of objects of type T to a string using a {@link JsonMapper}.
*
* @param list the list of objects to serialize
* @param jsonMapper the {@code JsonMapper} to use during conversion
* @param <T> the type of the object to serialize
* @return serialized JSON string
*/
public <T> String serializeList(List<T> list, JsonMapper<T> jsonMapper) {
return serialize(jsonMapper.toJson(list));
}

private JsonElement visit(AstNode astNode) {
return switch (astNode.type()) {
case OBJECT -> visitObject(astNode);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package technology.sola.json.exception;

public class JsonElementTypeException extends RuntimeException {
public JsonElementTypeException(String desiredType, String actualType) {
super(String.format("JsonElement type is [%s] but attempted to use as [%s]", actualType, desiredType));
}
}
114 changes: 114 additions & 0 deletions src/test/java/technology/sola/json/JsonArrayTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package technology.sola.json;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

class JsonArrayTest {
private JsonArray root;

@BeforeEach
void setup() {
root = new JsonArray();
}

@Nested
class convenience {
@Test
void objectMethods() {
JsonObject expected = new JsonObject();

root.add(expected);
assertEquals(expected, root.getObject(0));

root.add((JsonObject) null);
assertTrue(root.isNull(1));
}

@Test
void arrayMethods() {
JsonArray expected = new JsonArray();

root.add(expected);
assertEquals(expected, root.getArray(0));

root.add((JsonArray) null);
assertTrue(root.isNull(1));
}

@Test
void stringMethods() {
String expected = "";

root.add(expected);
assertEquals(expected, root.getString(0));

root.add((String) null);
assertTrue(root.isNull(1));
}

@Test
void doubleMethods() {
double expected = 0.0;

root.add(expected);
assertEquals(expected, root.getDouble(0));

root.add((Double) null);
assertTrue(root.isNull(1));
}

@Test
void floatMethods() {
float expected = 0.0f;

root.add(expected);
assertEquals(expected, root.getFloat(0));

root.add((Float) null);
assertTrue(root.isNull(1));
}

@Test
void longMethods() {
long expected = 0L;

root.add(expected);
assertEquals(expected, root.getLong(0));

root.add((Long) null);
assertTrue(root.isNull(1));
}

@Test
void intMethods() {
int expected = 0;

root.add(expected);
assertEquals(expected, root.getInt(0));

root.add((Integer) null);
assertTrue(root.isNull(1));
}

@Test
void booleanMethods() {
boolean expected = true;

root.add(expected);
assertEquals(expected, root.getBoolean(0));

root.add((Boolean) null);
assertTrue(root.isNull(1));
}

@Test
void nullMethods() {
root.addNull();
assertTrue(root.isNull(0));
}
}
}
15 changes: 15 additions & 0 deletions src/test/java/technology/sola/json/JsonElementTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package technology.sola.json;

import org.junit.jupiter.api.Test;
import technology.sola.json.exception.JsonElementTypeException;

import static org.junit.jupiter.api.Assertions.assertThrows;

class JsonElementTest {
@Test
void whenAccessingIncorrectType_shouldThrowException() {
JsonElement jsonElement = new JsonElement();

assertThrows(JsonElementTypeException.class, jsonElement::asArray);
}
}
Loading

0 comments on commit fc4b74c

Please sign in to comment.