Skip to content

Commit

Permalink
BugFix: TeenyJson now can parse formatted jsons, TeenyApplicationTest…
Browse files Browse the repository at this point in the history
…s now uses TeenyJson instead of Gson
  • Loading branch information
alex-cova committed Feb 29, 2024
1 parent e48dadd commit 35a59ce
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,18 @@ synchronized Object read() {
return readBoolean(current);
}

if (current == ' ') {
if (shouldSkip(current)) {
buffer.advanceSpaces();
return read();
}

return null;
}

private static boolean shouldSkip(char current) {
return current == ' ' || current == '\n' || current == '\t' || current == '\r';
}

private Object readBoolean(char current) {

if (current == 't' || current == 'T') {
Expand Down Expand Up @@ -223,7 +227,7 @@ boolean next() {
}

void advanceSpaces() {
while (json.charAt(index) == ' ') {
while (shouldSkip(json.charAt(index))) {
index++;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,15 @@ public <T, K> K readCollection(String json, Class<? extends Collection> collecti
* @param type the type of the object to parse
*
*/
@SuppressWarnings("unchecked")
public <T> T readValue(String json, Class<T> type) {

if (json == null) return null;

if (type == String.class) {
return (T) json;
}

Object result = new JsonDecoder(json).read();

if (result == null) {
Expand All @@ -97,6 +102,29 @@ public <T> T readValue(String json, Class<T> type) {
return parseObject(result, type);
}

@SuppressWarnings("unchecked")
public <T> T readValue(String json, Type type) {

if (json == null) return null;

if (type == String.class) {
return (T) json;
}

Object result = new JsonDecoder(json).read();

if (result == null) {
return null;
}

if (type instanceof Class<?>) {
return (T) parse(result, type);
}

throw new IllegalStateException("Unsupported type: " + type.getTypeName() + " " + type.getClass().getName());
}


/**
* Register a custom serializer for the given class.
*
Expand Down Expand Up @@ -210,41 +238,45 @@ private Object parse(Object value, Type target) {
throw new IllegalStateException("Unsupported type: " + target.getTypeName() + " " + target.getClass().getName());
}

private String trim(Object value) {
return value.toString().trim();
}

private Object parsePrimitive(Object value, Class<?> target) {

if (target == int.class) {

if (value == null) return 0;

return Integer.parseInt(value.toString());
return Integer.parseInt(trim(value));
}

if (target == long.class) {

if (value == null) return 0L;

return Long.parseLong(value.toString());
return Long.parseLong(trim(value));
}

if (target == double.class) {

if (value == null) return 0.0;

return Double.parseDouble(value.toString());
return Double.parseDouble(trim(value));
}

if (target == float.class) {

if (value == null) return 0.0f;

return Float.parseFloat(value.toString());
return Float.parseFloat(trim(value));
}

if (target == boolean.class) {

if (value == null) return false;

return Boolean.parseBoolean(value.toString());
return Boolean.parseBoolean(trim(value));
}

throw new IllegalStateException("Unsupported primitive type: " + target.getName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ public class TeenyApplicationTest {
private static final int TEST_PORT = 8080;



private static class ProtocolBufferMessageConverter implements MessageConverter {

@Override
Expand All @@ -52,7 +51,7 @@ public void setup() {
System.setProperty("banner", "false");

TeenyApplication.start()
.registerMessageConverter(new GsonMessageConverter())
.registerMessageConverter(new TeenyJsonConverter())
.registerMessageConverter(new ProtocolBufferMessageConverter())
.register(new StoreController());

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package net.jonathangiles.tools.teenyhttpd;

import net.jonathangiles.tools.teenyhttpd.json.TeenyJson;
import net.jonathangiles.tools.teenyhttpd.model.MessageConverter;

import java.io.BufferedOutputStream;
import java.io.IOException;
import java.lang.reflect.Type;

public class TeenyJsonConverter implements MessageConverter {

final TeenyJson teenyJson = new TeenyJson();

@Override
public String getContentType() {
return "application/json";
}

@Override
public void write(Object value, BufferedOutputStream dataOut) throws IOException {


if (value instanceof String) {
dataOut.write(((String) value).getBytes());
return;
}

dataOut.write(teenyJson.writeValueAsString(value).getBytes());
}

@Override
public Object read(String value, Type type) {
return teenyJson.readValue(value, type);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,46 @@ void parseDeepObjectTeenyJson() {
new ObjectB("Jonathan", 30,
new ObjectC("John Doe", 23))));

System.out.println(json);

ObjectA objectA = new TeenyJson()
.readValue(json, ObjectA.class);

System.out.println(objectA);

Assertions.assertEquals("Alex", objectA.getName());
Assertions.assertEquals(25, objectA.getAge());
Assertions.assertTrue(objectA.isDeveloper());

ObjectB objectB = objectA.getObjectB();

Assertions.assertEquals("Jonathan", objectB.getName());
Assertions.assertEquals(30, objectB.getAge());

ObjectC objectC = objectB.getObjectC();

Assertions.assertEquals("John Doe", objectC.getName());
Assertions.assertEquals(23, objectC.getAge());

}

@Test
void testParseFormattedJson() {

String json = "{\n" +
" \"objectB\": {\n" +
" \"objectC\": {\n" +
" \"name\": \"John Doe\",\n" +
" \"age\": 23\n" +
" },\n" +
" \"name\": \"Jonathan\",\n" +
" \"age\": 30\n" +
" },\n" +
" \"name\": \"Alex\",\n" +
" \"developer\": true,\n" +
" \"age\": 25\n" +
"}";

ObjectA objectA = new TeenyJson()
.readValue(json, ObjectA.class);

Expand Down

0 comments on commit 35a59ce

Please sign in to comment.