001/* 002 * (C) Copyright 2015 Nuxeo SA (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl-2.1.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * Nicolas Chapurlat <nchapurlat@nuxeo.com> 016 */ 017 018package org.nuxeo.ecm.core.io.marshallers.json; 019 020import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE; 021 022import java.io.IOException; 023import java.lang.reflect.Type; 024import java.util.ArrayList; 025import java.util.Iterator; 026import java.util.List; 027 028import org.apache.commons.lang3.reflect.TypeUtils; 029import org.codehaus.jackson.JsonNode; 030import org.nuxeo.ecm.core.io.registry.MarshallerRegistry; 031import org.nuxeo.ecm.core.io.registry.Reader; 032 033/** 034 * Base class to convert json as {@link List}. 035 * <p> 036 * It follow the classic Nuxeo list format : 037 * 038 * <pre> 039 * { 040 * "entity-type": "GIVEN_ENTITY_TYPE", 041 * "entries": [ 042 * {...}, <-- A {@link Reader} must be able to manage this format. 043 * {...}, 044 * ... 045 * {...} 046 * ] 047 * } 048 * </pre> 049 * 050 * </p> 051 * <p> 052 * This reader delegates the unmarshalling of entries to the {@link MarshallerRegistry}. A Json {@link Reader} 053 * compatible with the required type and the json format must be registered. 054 * </p> 055 * 056 * @param <EntityType> The type of the element of this list. 057 * @since 7.2 058 */ 059public abstract class DefaultListJsonReader<EntityType> extends EntityJsonReader<List<EntityType>> { 060 061 /** 062 * The Java type of the element of this list. 063 */ 064 private final Class<EntityType> elClazz; 065 066 /** 067 * The generic type of the element of this list. 068 */ 069 private final Type elGenericType; 070 071 /** 072 * Use this constructor if the element of the list are not based on Java generic type. 073 * 074 * @param entityType The list "entity-type". 075 * @param elClazz The class of the element of the list. 076 */ 077 public DefaultListJsonReader(String entityType, Class<EntityType> elClazz) { 078 super(entityType); 079 this.elClazz = elClazz; 080 elGenericType = elClazz; 081 } 082 083 /** 084 * Use this constructor if the element of the list are based on Java generic type. 085 * 086 * @param entityType The list "entity-type". 087 * @param elClazz The class of the element of the list. 088 * @param elGenericType The generic type of the list (you can use {@link TypeUtils#parameterize(Class, Type...) to 089 * generate it} 090 */ 091 public DefaultListJsonReader(String entityType, Class<EntityType> elClazz, Type elGenericType) { 092 super(entityType); 093 this.elClazz = elClazz; 094 this.elGenericType = elGenericType; 095 } 096 097 @Override 098 protected List<EntityType> readEntity(JsonNode jn) throws IOException { 099 Reader<EntityType> entryReader = registry.getReader(ctx, elClazz, elGenericType, APPLICATION_JSON_TYPE); 100 List<EntityType> result = new ArrayList<EntityType>(); 101 JsonNode entriesNode = jn.get("entries"); 102 if (entriesNode != null && !entriesNode.isNull() && entriesNode.isArray()) { 103 JsonNode entryNode = null; 104 Iterator<JsonNode> it = entriesNode.getElements(); 105 while (it.hasNext()) { 106 entryNode = it.next(); 107 InputStreamWithJsonNode in = new InputStreamWithJsonNode(entryNode); 108 EntityType doc = entryReader.read(elClazz, elClazz, APPLICATION_JSON_TYPE, in); 109 result.add(doc); 110 } 111 } 112 return result; 113 } 114 115}