001/* 002 * (C) Copyright 2015 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Nicolas Chapurlat <nchapurlat@nuxeo.com> 018 */ 019 020package org.nuxeo.ecm.core.io.marshallers.json; 021 022import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE; 023 024import java.io.IOException; 025import java.lang.reflect.Type; 026import java.util.ArrayList; 027import java.util.Iterator; 028import java.util.List; 029 030import org.apache.commons.lang3.reflect.TypeUtils; 031import org.nuxeo.ecm.core.io.registry.MarshallerRegistry; 032import org.nuxeo.ecm.core.io.registry.Reader; 033 034import com.fasterxml.jackson.databind.JsonNode; 035 036/** 037 * Base class to convert json as {@link List}. 038 * <p> 039 * It follow the classic Nuxeo list format : 040 * 041 * <pre> 042 * { 043 * "entity-type": "GIVEN_ENTITY_TYPE", 044 * "entries": [ 045 * {...}, <-- A {@link Reader} must be able to manage this format. 046 * {...}, 047 * ... 048 * {...} 049 * ] 050 * } 051 * </pre> 052 * 053 * </p> 054 * <p> 055 * This reader delegates the unmarshalling of entries to the {@link MarshallerRegistry}. A Json {@link Reader} 056 * compatible with the required type and the json format must be registered. 057 * </p> 058 * 059 * @param <EntityType> The type of the element of this list. 060 * @since 7.2 061 */ 062public abstract class DefaultListJsonReader<EntityType> extends EntityJsonReader<List<EntityType>> { 063 064 /** 065 * The Java type of the element of this list. 066 */ 067 private final Class<EntityType> elClazz; 068 069 /** 070 * The generic type of the element of this list. 071 */ 072 private final Type elGenericType; 073 074 /** 075 * Use this constructor if the element of the list are not based on Java generic type. 076 * 077 * @param entityType The list "entity-type". 078 * @param elClazz The class of the element of the list. 079 */ 080 public DefaultListJsonReader(String entityType, Class<EntityType> elClazz) { 081 super(entityType); 082 this.elClazz = elClazz; 083 elGenericType = elClazz; 084 } 085 086 /** 087 * Use this constructor if the element of the list are based on Java generic type. 088 * 089 * @param entityType The list "entity-type". 090 * @param elClazz The class of the element of the list. 091 * @param elGenericType The generic type of the list (you can use {@link TypeUtils#parameterize(Class, Type...) to 092 * generate it} 093 */ 094 public DefaultListJsonReader(String entityType, Class<EntityType> elClazz, Type elGenericType) { 095 super(entityType); 096 this.elClazz = elClazz; 097 this.elGenericType = elGenericType; 098 } 099 100 @Override 101 protected List<EntityType> readEntity(JsonNode jn) throws IOException { 102 Reader<EntityType> entryReader = registry.getReader(ctx, elClazz, elGenericType, APPLICATION_JSON_TYPE); 103 List<EntityType> result = new ArrayList<EntityType>(); 104 JsonNode entriesNode = jn.get("entries"); 105 if (entriesNode != null && !entriesNode.isNull() && entriesNode.isArray()) { 106 JsonNode entryNode = null; 107 Iterator<JsonNode> it = entriesNode.elements(); 108 while (it.hasNext()) { 109 entryNode = it.next(); 110 InputStreamWithJsonNode in = new InputStreamWithJsonNode(entryNode); 111 EntityType doc = entryReader.read(elClazz, elClazz, APPLICATION_JSON_TYPE, in); 112 result.add(doc); 113 } 114 } 115 return result; 116 } 117 118}