Skip to content

Commit

Permalink
Add support for parameterized classes that contain generic arrays. (#118
Browse files Browse the repository at this point in the history
)

Co-authored-by: Tim Johnson <[email protected]>
  • Loading branch information
Tim Johnson and twjbz authored May 11, 2020
1 parent 490a198 commit 800c295
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 0 deletions.
16 changes: 16 additions & 0 deletions core/src/main/java/com/backblaze/b2/json/B2JsonHandlerMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.backblaze.b2.util.B2Preconditions;

import java.lang.reflect.Field;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
Expand Down Expand Up @@ -258,6 +259,10 @@ public synchronized <T> B2JsonTypeHandler<T> getHandler(Type type) throws B2Json
//noinspection unchecked
handler = getUninitializedHandlerForParameterizedType(parameterizedType);

} else if (type instanceof GenericArrayType) {
final GenericArrayType genericArrayType = (GenericArrayType) type;
handler = getUninitializedHandlerForGenericArrayType(genericArrayType);

} else {
throw new B2JsonException("do not know how to get handler for type " + type.getTypeName());
}
Expand Down Expand Up @@ -344,6 +349,17 @@ private synchronized B2JsonTypeHandler getUninitializedHandlerForParameterizedTy
return new B2JsonObjectHandler(resolvedRawTypeClass, parameterizedType.getActualTypeArguments());
}

private synchronized B2JsonTypeHandler getUninitializedHandlerForGenericArrayType(
GenericArrayType genericArrayType) throws B2JsonException {

// Java does not allow the component type to be a parameterized type. Therefore,
// we can get the Class of the generic component Type without losing information.
return new B2JsonObjectArrayHandler(
genericArrayType.getClass(),
genericArrayType.getGenericComponentType().getClass(),
getUninitializedHandler(genericArrayType.getGenericComponentType()));
}

/**
* Returns a list of all of the fields in a class that should be included in JSON.
*/
Expand Down
54 changes: 54 additions & 0 deletions core/src/test/java/com/backblaze/b2/json/B2JsonTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2517,6 +2517,34 @@ public void testGenerics() throws B2JsonException {

}

@Test
public void testGenericArraySupport() throws B2JsonException {
final ClassWithGenericArrays objectWithGenericArrays =
new ClassWithGenericArrays(
new ItemArray<>(new Integer[] {0, 1, 2, 3}),
new ItemArray<>(new String[] {"a", "b"}));
final String expected = "" +
"{\n" +
" \"intArray\": {\n" +
" \"values\": [\n" +
" 0,\n" +
" 1,\n" +
" 2,\n" +
" 3\n" +
" ]\n" +
" },\n" +
" \"stringArray\": {\n" +
" \"values\": [\n" +
" \"a\",\n" +
" \"b\"\n" +
" ]\n" +
" }\n" +
"}";

assertEquals(expected, b2Json.toJson(objectWithGenericArrays));
}


private static class ClassThatUsesGenerics {

@B2Json.required
Expand Down Expand Up @@ -2559,4 +2587,30 @@ public T getValue() {
return value;
}
}

private static class ClassWithGenericArrays {
@B2Json.required
private final ItemArray<Integer> intArray;

@B2Json.required
private final ItemArray<String> stringArray;


@B2Json.constructor(params = "intArray, stringArray")
public ClassWithGenericArrays(ItemArray<Integer> intArray, ItemArray<String> stringArray) {
this.intArray = intArray;
this.stringArray = stringArray;
}
}

private static class ItemArray<T> {

@B2Json.required
private final T[] values;

@B2Json.constructor(params = "values")
public ItemArray(T[] values) {
this.values = values;
}
}
}

0 comments on commit 800c295

Please sign in to comment.