diff --git a/core/src/main/java/com/backblaze/b2/json/B2JsonHandlerMap.java b/core/src/main/java/com/backblaze/b2/json/B2JsonHandlerMap.java index 6657a52ab..3ccb2b1fc 100644 --- a/core/src/main/java/com/backblaze/b2/json/B2JsonHandlerMap.java +++ b/core/src/main/java/com/backblaze/b2/json/B2JsonHandlerMap.java @@ -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; @@ -258,6 +259,10 @@ public synchronized B2JsonTypeHandler 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()); } @@ -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. */ diff --git a/core/src/test/java/com/backblaze/b2/json/B2JsonTest.java b/core/src/test/java/com/backblaze/b2/json/B2JsonTest.java index 28020119f..07083619b 100644 --- a/core/src/test/java/com/backblaze/b2/json/B2JsonTest.java +++ b/core/src/test/java/com/backblaze/b2/json/B2JsonTest.java @@ -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 @@ -2559,4 +2587,30 @@ public T getValue() { return value; } } + + private static class ClassWithGenericArrays { + @B2Json.required + private final ItemArray intArray; + + @B2Json.required + private final ItemArray stringArray; + + + @B2Json.constructor(params = "intArray, stringArray") + public ClassWithGenericArrays(ItemArray intArray, ItemArray stringArray) { + this.intArray = intArray; + this.stringArray = stringArray; + } + } + + private static class ItemArray { + + @B2Json.required + private final T[] values; + + @B2Json.constructor(params = "values") + public ItemArray(T[] values) { + this.values = values; + } + } }