got arrays working
This commit is contained in:
parent
c650834d3b
commit
59fbbe904a
7 changed files with 148 additions and 35 deletions
|
|
@ -7,6 +7,7 @@ import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
@ -52,7 +53,7 @@ public class JavaObjectReaderFactory {
|
||||||
private static CtMethod createReadJsonMethod(CtClass serializerClass, Class<?> type) {
|
private static CtMethod createReadJsonMethod(CtClass serializerClass, Class<?> type) {
|
||||||
try {
|
try {
|
||||||
String readMethodBodySource = createReadMethodBodySource(type);
|
String readMethodBodySource = createReadMethodBodySource(type);
|
||||||
// System.out.println(readMethodBodySource);
|
System.out.println(readMethodBodySource);
|
||||||
return CtNewMethod.make(Modifier.PUBLIC, OBJECT_CLASS, "read", PARSER_PARAM, NO_EXCEPTIONS, readMethodBodySource, serializerClass);
|
return CtNewMethod.make(Modifier.PUBLIC, OBJECT_CLASS, "read", PARSER_PARAM, NO_EXCEPTIONS, readMethodBodySource, serializerClass);
|
||||||
} catch (CannotCompileException e) {
|
} catch (CannotCompileException e) {
|
||||||
throw new ClassCreationException(e);
|
throw new ClassCreationException(e);
|
||||||
|
|
@ -99,12 +100,23 @@ public class JavaObjectReaderFactory {
|
||||||
return "getFloat(\"" + fieldName + "\",object)";
|
return "getFloat(\"" + fieldName + "\",object)";
|
||||||
} else if (fieldType == double.class) {
|
} else if (fieldType == double.class) {
|
||||||
return "getDouble(\"" + fieldName + "\",object)";
|
return "getDouble(\"" + fieldName + "\",object)";
|
||||||
} else if (Set.class.isAssignableFrom(fieldType)) {
|
|
||||||
return "getSet(\"" + fieldName + "\",object)";
|
|
||||||
} else {
|
} else {
|
||||||
return "(" + fieldType.getName() + ")(object.get(\"" + fieldName + "\"))";
|
String fieldTypeName = field.getType().getName();
|
||||||
|
if (Set.class.isAssignableFrom(fieldType)) {
|
||||||
|
return "(" + fieldTypeName + ")getSet(\"" + fieldName + "\"," + fieldTypeName + ".class,object)";
|
||||||
|
} else if (List.class.isAssignableFrom(fieldType)) {
|
||||||
|
return "(" + fieldTypeName + ")getList(\"" + fieldName + "\"," + fieldTypeName + ".class,object)";
|
||||||
|
} else if (fieldType.isArray()) {
|
||||||
|
return "(" + format(fieldTypeName) + "[])getArray(\"" + fieldName + "\"," + format(fieldTypeName) + ".class,object)";
|
||||||
|
} else {
|
||||||
|
return "(" + fieldTypeName + ")(object.get(\"" + fieldName + "\"))";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String format(String arrayTypeExpr) {
|
||||||
|
return arrayTypeExpr.substring(2).substring(0, arrayTypeExpr.length() - 3);
|
||||||
|
}
|
||||||
|
|
||||||
//should be reinstated
|
//should be reinstated
|
||||||
private static String genericType(CtField field) {
|
private static String genericType(CtField field) {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
package nl.sander.jsontoy2;
|
package nl.sander.jsontoy2;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.lang.reflect.Array;
|
||||||
import java.util.List;
|
import java.lang.reflect.Constructor;
|
||||||
import java.util.Map;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.util.Set;
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for generated readers
|
* Base class for generated readers
|
||||||
|
|
@ -49,9 +49,64 @@ public abstract class JsonValueReader<T> {
|
||||||
return value == null ? 0D : (Double) value;
|
return value == null ? 0D : (Double) value;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Set<?> getSet(String fieldName, Map<String, ?> values) {
|
/*
|
||||||
Object value = values.get(fieldName);
|
* Creates a Set type for any implementation of it (that the containing bean needs),
|
||||||
return value == null ? null : new HashSet<>((List<?>) value);
|
* unless it has no constructor using a java.util.Collection as single parameter.
|
||||||
|
*
|
||||||
|
* returntype is generic Set, object needs cast afterwards in generated code
|
||||||
|
*/
|
||||||
|
protected Set<?> getSet(String fieldName, Class<? extends Set<?>> type, Map<String, ?> values) {
|
||||||
|
List<?> value = (List<?>) values.get(fieldName);
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
if (type.equals(Set.class)) {
|
||||||
|
return new HashSet<>(value);
|
||||||
|
} else {
|
||||||
|
Constructor<? extends Set<?>> constructor = type.getConstructor(Collection.class);
|
||||||
|
return constructor.newInstance(value);
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||||
|
throw new JsonParseException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Creates a List type for any implementation of it (that the containing bean needs),
|
||||||
|
* unless it has no constructor using a java.util.Collection as single parameter.
|
||||||
|
*
|
||||||
|
* returntype is generic List, needs cast afterwards in generated code
|
||||||
|
*/
|
||||||
|
protected List<?> getList(String fieldName, Class<?> listImplType, Map<String, ?> values) {
|
||||||
|
List<?> value = (List<?>) values.get(fieldName);
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
} else if (listImplType == ArrayList.class || listImplType.equals(List.class)) {
|
||||||
|
return value;
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
Constructor<?> constructor = listImplType.getConstructor(Collection.class);
|
||||||
|
return (List<?>) constructor.newInstance(value);
|
||||||
|
} catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||||
|
throw new JsonParseException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Object getArray(String fieldName, Class<?> arrayType, Map<String, ?> values) {
|
||||||
|
List<?> value = (List<?>) values.get(fieldName);
|
||||||
|
if (value == null) {
|
||||||
|
return new Object[]{};
|
||||||
|
} else {
|
||||||
|
Object[] array = (Object[]) Array.newInstance(arrayType, value.size());
|
||||||
|
int index = 0;
|
||||||
|
for (Object element : value) {
|
||||||
|
array[index] = value.get(index++);
|
||||||
|
}
|
||||||
|
//TODO this can probably be done smarter
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -148,7 +148,7 @@ public class Parser extends Lexer {
|
||||||
skipWhitespace();
|
skipWhitespace();
|
||||||
final Maybe<Object> maybeValue;
|
final Maybe<Object> maybeValue;
|
||||||
try {
|
try {
|
||||||
maybeValue = type == null ? parseValue() : parseValue(type.getDeclaredField(key).getType());
|
maybeValue = type == null ? parseValue() : Maybe.of(JsonReader.read(type.getDeclaredField(key).getType(), this));
|
||||||
maybeValue.ifPresent(value -> map.put(key, value));
|
maybeValue.ifPresent(value -> map.put(key, value));
|
||||||
} catch (NoSuchFieldException e) {
|
} catch (NoSuchFieldException e) {
|
||||||
throw new JsonParseException(e);
|
throw new JsonParseException(e);
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ public class ReaderFactory {
|
||||||
static <T> JsonValueReader<?> getReader(Class<T> type) {
|
static <T> JsonValueReader<?> getReader(Class<T> type) {
|
||||||
if (Map.class.isAssignableFrom(type)) {
|
if (Map.class.isAssignableFrom(type)) {
|
||||||
return MAPREADER;
|
return MAPREADER;
|
||||||
} else if (List.class.isAssignableFrom(type) || Set.class.isAssignableFrom(type)) {
|
} else if (List.class.isAssignableFrom(type) || Set.class.isAssignableFrom(type) || type.isArray()) {
|
||||||
return LISTREADER;
|
return LISTREADER;
|
||||||
} else {
|
} else {
|
||||||
return readers.computeIfAbsent(type, k -> {
|
return readers.computeIfAbsent(type, k -> {
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@ import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
|
@ -89,23 +91,23 @@ public class WrapperObjectTests {
|
||||||
assertEquals(new HashSet<>(Arrays.asList("a", "b")), listBean.getValue());
|
assertEquals(new HashSet<>(Arrays.asList("a", "b")), listBean.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Test
|
@Test
|
||||||
// public void testIntegerList() {
|
public void testIntegerList() {
|
||||||
// IntegerListBean listBean = JsonReader.read(IntegerListBean.class, "{\"value\": [1,22]}");
|
IntegerListBean listBean = JsonReader.read(IntegerListBean.class, "{\"value\": [1,22]}");
|
||||||
// assertEquals(Arrays.asList(1, 22), listBean.getValue());
|
assertEquals(Arrays.asList(1, 22), listBean.getValue());
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// @Test
|
|
||||||
// public void testCharacterList() {
|
|
||||||
// CharacterListBean listBean = JsonReader.read(CharacterListBean.class, "{\"value\": [\"a\", \"[\", \"^\"]}");
|
|
||||||
// assertEquals(Arrays.asList('a', '[', '^'), listBean.getValue());
|
|
||||||
// }
|
|
||||||
|
|
||||||
// @Test
|
@Test
|
||||||
// public void testShortList() {
|
public void testCharacterList() {
|
||||||
// ShortListBean listBean = JsonReader.read(ShortListBean.class, "{\"value\": [-1,0,1]}");
|
CharacterListBean listBean = JsonReader.read(CharacterListBean.class, "{\"value\": [\"a\", \"[\", \"^\"]}");
|
||||||
// assertEquals(Arrays.asList((short) -1, (short) 0, (short) 1), listBean.getValue());
|
assertEquals(Arrays.asList('a', '[', '^'), listBean.getValue());
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testShortList() {
|
||||||
|
ShortListBean listBean = JsonReader.read(ShortListBean.class, "{\"value\": [-1,0,1]}");
|
||||||
|
assertEquals(Arrays.asList((short) -1, (short) 0, (short) 1), listBean.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBooleanList() {
|
public void testBooleanList() {
|
||||||
|
|
@ -125,11 +127,11 @@ public class WrapperObjectTests {
|
||||||
// assertEquals(Arrays.asList((byte) -100, (byte) 78), listBean.getValue());
|
// assertEquals(Arrays.asList((byte) -100, (byte) 78), listBean.getValue());
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// @Test
|
@Test
|
||||||
// public void testDoubleList() {
|
public void testDoubleList() {
|
||||||
// DoubleListBean listBean = JsonReader.read(DoubleListBean.class, "{\"value\": [-100.156,78.0]}");
|
DoubleListBean listBean = JsonReader.read(DoubleListBean.class, "{\"value\": [-100.156,78.0]}");
|
||||||
// assertEquals(Arrays.asList(-100.156D, 78.0D), listBean.getValue());
|
assertEquals(Arrays.asList(-100.156D, 78.0D), listBean.getValue());
|
||||||
// }
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNestedBean() {
|
public void testNestedBean() {
|
||||||
|
|
@ -143,4 +145,20 @@ public class WrapperObjectTests {
|
||||||
StringMapBean expected = new StringMapBean("a:", "b", "c:", "d");
|
StringMapBean expected = new StringMapBean("a:", "b", "c:", "d");
|
||||||
assertEquals(expected, actual);
|
assertEquals(expected, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLinkedList() {
|
||||||
|
LinkedListBean actual = JsonReader.read(LinkedListBean.class, "{\"list\": [\"a\"]}");
|
||||||
|
LinkedList<String> actualList = actual.getList();
|
||||||
|
|
||||||
|
assertEquals(List.of("a"), actualList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testArray() {
|
||||||
|
ArrayBean actual = JsonReader.read(ArrayBean.class, "{\"array\": [\"a\"]}");
|
||||||
|
|
||||||
|
assertEquals(1, actual.getArray().length);
|
||||||
|
assertEquals("a", actual.getArray()[0]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
13
src/test/java/nl/sander/jsontoy2/beans/ArrayBean.java
Normal file
13
src/test/java/nl/sander/jsontoy2/beans/ArrayBean.java
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
package nl.sander.jsontoy2.beans;
|
||||||
|
|
||||||
|
public class ArrayBean {
|
||||||
|
private String[] array;
|
||||||
|
|
||||||
|
public void setArray(String[] array) {
|
||||||
|
this.array = array;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getArray() {
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
}
|
||||||
15
src/test/java/nl/sander/jsontoy2/beans/LinkedListBean.java
Normal file
15
src/test/java/nl/sander/jsontoy2/beans/LinkedListBean.java
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
package nl.sander.jsontoy2.beans;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
public class LinkedListBean {
|
||||||
|
private LinkedList<String> list;
|
||||||
|
|
||||||
|
public LinkedList<String> getList() {
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setList(LinkedList<String> list) {
|
||||||
|
this.list = list;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue