ObjectBuilder { @SuppressWarnings("unchecked") public static <T extends Collection<?>> T createCollection(Class<T> collectionClass, Type genericType, JsonValue jsonArray) throws JsonException { if (jsonArray == null || jsonArray.isNull()) { return null; } Class elementClass; Type elementType; if (genericType instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType)genericType; elementType = parameterizedType.getActualTypeArguments()[0]; if (elementType instanceof Class) { elementClass = (Class)elementType; } else if (elementType instanceof ParameterizedType) { elementClass = (Class)((ParameterizedType)elementType).getRawType(); } else { throw new JsonException(String.format( "This type of Collection can't be restored from JSON source.\nCollection is parameterized by wrong Type: %s", parameterizedType)); } } else { throw new JsonException("Collection is not parameterized. Collection<?> is not supported"); } Constructor<? extends T> constructor; if (collectionClass.isInterface() || Modifier.isAbstract(collectionClass.getModifiers())) { constructor = getConstructor(findAcceptableCollectionImplementation(collectionClass), Collection.class); } else { constructor = getConstructor(collectionClass, Collection.class); } ArrayList<Object> sourceCollection = new ArrayList<>(jsonArray.size()); Iterator<JsonValue> values = jsonArray.getElements(); Types jsonElementType = getType(elementClass); while (values.hasNext()) { JsonValue value = values.next(); if (jsonElementType == null) { sourceCollection.add(createObject(elementClass, value)); } else { switch (jsonElementType) { case BYTE: case SHORT: case INT: case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case CHAR: case STRING: case NULL: case ARRAY_BYTE: case ARRAY_SHORT: case ARRAY_INT: case ARRAY_LONG: case ARRAY_FLOAT: case ARRAY_DOUBLE: case ARRAY_BOOLEAN: case ARRAY_CHAR: case ARRAY_STRING: case CLASS: sourceCollection.add(createObjectKnownTypes(elementClass, value)); break; case ARRAY_OBJECT: sourceCollection.add(createArray(elementClass, value)); break; case COLLECTION: sourceCollection.add(createCollection(elementClass, elementType, value)); break; case MAP: sourceCollection.add(createObject(elementClass, elementType, value)); break; case ENUM: sourceCollection.add(createEnum(elementClass, value)); break; } } } try { return constructor.newInstance(sourceCollection); } catch (Exception e) { throw new JsonException(e.getMessage(), e); } } private  ObjectBuilder(); static Object createArray(Class<?> aClass, JsonValue jsonArray); @SuppressWarnings("unchecked") static T createCollection(Class<T> collectionClass, Type genericType, JsonValue jsonArray); @SuppressWarnings("unchecked") static T createObject(Class<T> mapClass, Type genericType, JsonValue jsonObject); @SuppressWarnings({"unchecked"}) static T createObject(Class<T> aClass, JsonValue jsonValue);  }
@Test public void returnsNullWhenCreateCollectionFromNull() throws Exception { Object array = ObjectBuilder.createCollection(List.class, newParameterizedType(List.class, String.class), null); assertNull(array); }
@Test public void returnsNullWhenCreateCollectionFromNullValue() throws Exception { Object array = ObjectBuilder.createCollection(List.class, newParameterizedType(List.class, String.class), new NullValue()); assertNull(array); }
@Test public void createsListOfStrings() throws Exception { ArrayValue jsonArray = createJsonArray("to", "be", "or", "not", "to", "be"); List list = ObjectBuilder.createCollection(List.class, newParameterizedType(List.class, String.class), jsonArray); assertEquals(newArrayList("to", "be", "or", "not", "to", "be"), list); }
@Test public void createsListOfObjects() throws Exception { ArrayValue jsonArray = createJsonArray(createJsonBook(createJunitBook()), createJsonBook(createCSharpBook()) ); List list = ObjectBuilder.createCollection(List.class, newParameterizedType(List.class, Book.class), jsonArray); assertEquals(newArrayList(createJunitBook(), createCSharpBook()), list); }
@Test public void createsSetOfStrings() throws Exception { ArrayValue jsonArray = createJsonArray("to", "be", "or", "not", "to", "be"); Set set = ObjectBuilder.createCollection(Set.class, newParameterizedType(Set.class, String.class), jsonArray); assertEquals(newHashSet("to", "be", "or", "not", "to", "be"), set); }
@Test public void createsSetOfObjects() throws Exception { ArrayValue jsonArray = createJsonArray(createJsonBook(createJunitBook()), createJsonBook(createCSharpBook()) ); Set set = ObjectBuilder.createCollection(Set.class, newParameterizedType(Set.class, Book.class), jsonArray); assertEquals(newHashSet(createJunitBook(), createCSharpBook()), set); }
@Test public void createsArrayListOfStrings() throws Exception { ArrayValue jsonArray = createJsonArray("to", "be", "or", "not", "to", "be"); ArrayList arrayList = ObjectBuilder.createCollection(ArrayList.class, newParameterizedType(ArrayList.class, String.class), jsonArray); assertEquals(newArrayList("to", "be", "or", "not", "to", "be"), arrayList); }
@Test public void createsListOfListOfStrings() throws Exception { ArrayValue jsonArray = new ArrayValue(); jsonArray.addElement(createJsonArray("to", "be", "or")); jsonArray.addElement(createJsonArray("not", "to", "be")); List listOfList = ObjectBuilder.createCollection(List.class, newParameterizedType(List.class, newParameterizedType(List.class, String.class)), jsonArray); assertEquals(newArrayList(newArrayList("to", "be", "or"), newArrayList("not", "to", "be")), listOfList); }
@Test public void failsCreateCollectionOfRawType() throws Exception { ArrayValue jsonArray = createJsonArray("to", "be", "or", "not", "to", "be"); thrown.expect(JsonException.class); ObjectBuilder.createCollection(List.class, List.class, jsonArray); }
@Test public void createsSetOfEnums() throws Exception { ArrayValue jsonArray = createJsonArray(JUNIT_IN_ACTION.name(), BEGINNING_C.name()); Set set = ObjectBuilder.createCollection(Set.class, newParameterizedType(Set.class, BookEnum.class), jsonArray); assertEquals(newHashSet(JUNIT_IN_ACTION, BEGINNING_C), set); }
@Test public void createsListOfMaps() throws Exception { ObjectValue jsonObject1 = createJsonObject("1", createJsonBook(createJavaScriptBook())); ObjectValue jsonObject2 = createJsonObject("1", createJsonBook(createJunitBook()), "2", createJsonBook(createCSharpBook()) ); ArrayValue jsonArray = createJsonArray(jsonObject1, jsonObject2); List list = ObjectBuilder.createCollection(List.class, newParameterizedType(List.class, newParameterizedType(Map.class, String.class, Book.class)), jsonArray); assertEquals(newArrayList(ImmutableMap.of("1", createJavaScriptBook()), ImmutableMap.of("1", createJunitBook(), "2", createCSharpBook())), list); }
@Test public void createsListOfArrays() throws Exception { ArrayValue childArray1 = createJsonArray(createJsonBook(createJavaScriptBook())); ArrayValue childArray2 = createJsonArray(createJsonBook(createJunitBook()), createJsonBook(createCSharpBook())); ArrayValue jsonArray = createJsonArray(childArray1, childArray2); List list = ObjectBuilder.createCollection(List.class, newParameterizedType(List.class, Book[].class), jsonArray); assertEquals(2, list.size()); assertArrayEquals(new Book[]{createJavaScriptBook()}, (Object[])list.get(0)); assertArrayEquals(new Book[]{createJunitBook(), createCSharpBook()}, (Object[])list.get(1)); }