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.InvocationTargetException;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
|
@ -52,7 +53,7 @@ public class JavaObjectReaderFactory {
|
|||
private static CtMethod createReadJsonMethod(CtClass serializerClass, Class<?> type) {
|
||||
try {
|
||||
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);
|
||||
} catch (CannotCompileException e) {
|
||||
throw new ClassCreationException(e);
|
||||
|
|
@ -99,12 +100,23 @@ public class JavaObjectReaderFactory {
|
|||
return "getFloat(\"" + fieldName + "\",object)";
|
||||
} else if (fieldType == double.class) {
|
||||
return "getDouble(\"" + fieldName + "\",object)";
|
||||
} else if (Set.class.isAssignableFrom(fieldType)) {
|
||||
return "getSet(\"" + fieldName + "\",object)";
|
||||
} 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
|
||||
private static String genericType(CtField field) {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
package nl.sander.jsontoy2;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Base class for generated readers
|
||||
|
|
@ -49,9 +49,64 @@ public abstract class JsonValueReader<T> {
|
|||
return value == null ? 0D : (Double) value;
|
||||
}
|
||||
|
||||
protected Set<?> getSet(String fieldName, Map<String, ?> values) {
|
||||
Object value = values.get(fieldName);
|
||||
return value == null ? null : new HashSet<>((List<?>) value);
|
||||
/*
|
||||
* Creates a Set 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 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();
|
||||
final Maybe<Object> maybeValue;
|
||||
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));
|
||||
} catch (NoSuchFieldException e) {
|
||||
throw new JsonParseException(e);
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ public class ReaderFactory {
|
|||
static <T> JsonValueReader<?> getReader(Class<T> type) {
|
||||
if (Map.class.isAssignableFrom(type)) {
|
||||
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;
|
||||
} else {
|
||||
return readers.computeIfAbsent(type, k -> {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ import org.junit.jupiter.api.Test;
|
|||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
|
|
@ -89,23 +91,23 @@ public class WrapperObjectTests {
|
|||
assertEquals(new HashSet<>(Arrays.asList("a", "b")), listBean.getValue());
|
||||
}
|
||||
|
||||
// @Test
|
||||
// public void testIntegerList() {
|
||||
// IntegerListBean listBean = JsonReader.read(IntegerListBean.class, "{\"value\": [1,22]}");
|
||||
// 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
|
||||
public void testIntegerList() {
|
||||
IntegerListBean listBean = JsonReader.read(IntegerListBean.class, "{\"value\": [1,22]}");
|
||||
assertEquals(Arrays.asList(1, 22), 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
|
||||
public void testCharacterList() {
|
||||
CharacterListBean listBean = JsonReader.read(CharacterListBean.class, "{\"value\": [\"a\", \"[\", \"^\"]}");
|
||||
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
|
||||
public void testBooleanList() {
|
||||
|
|
@ -113,7 +115,7 @@ public class WrapperObjectTests {
|
|||
assertEquals(Arrays.asList(true, false), listBean.getValue());
|
||||
}
|
||||
|
||||
// @Test
|
||||
// @Test
|
||||
// public void testFloatList() {
|
||||
// FloatListBean listBean = JsonReader.read(FloatListBean.class, "{\"value\": [-100.156,78.0]}");
|
||||
// assertEquals(Arrays.asList(-100.156F, 78.0F), listBean.getValue());
|
||||
|
|
@ -125,11 +127,11 @@ public class WrapperObjectTests {
|
|||
// assertEquals(Arrays.asList((byte) -100, (byte) 78), listBean.getValue());
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testDoubleList() {
|
||||
// DoubleListBean listBean = JsonReader.read(DoubleListBean.class, "{\"value\": [-100.156,78.0]}");
|
||||
// assertEquals(Arrays.asList(-100.156D, 78.0D), listBean.getValue());
|
||||
// }
|
||||
@Test
|
||||
public void testDoubleList() {
|
||||
DoubleListBean listBean = JsonReader.read(DoubleListBean.class, "{\"value\": [-100.156,78.0]}");
|
||||
assertEquals(Arrays.asList(-100.156D, 78.0D), listBean.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNestedBean() {
|
||||
|
|
@ -143,4 +145,20 @@ public class WrapperObjectTests {
|
|||
StringMapBean expected = new StringMapBean("a:", "b", "c:", "d");
|
||||
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