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; 021import static org.nuxeo.ecm.core.io.marshallers.json.enrichers.AbstractJsonEnricher.ENTITY_ENRICHER_NAME; 022import static org.nuxeo.ecm.core.io.registry.MarshallingConstants.ENTITY_FIELD_NAME; 023 024import java.io.Closeable; 025import java.io.IOException; 026import java.lang.reflect.Type; 027import java.util.Collection; 028import java.util.Set; 029 030import org.apache.commons.lang3.reflect.TypeUtils; 031import org.codehaus.jackson.JsonGenerator; 032import org.nuxeo.ecm.core.io.marshallers.json.enrichers.Enriched; 033import org.nuxeo.ecm.core.io.registry.MarshallerRegistry; 034import org.nuxeo.ecm.core.io.registry.Writer; 035import org.nuxeo.ecm.core.io.registry.context.MaxDepthReachedException; 036import org.nuxeo.ecm.core.io.registry.context.WrappedContext; 037 038/** 039 * Base class to write Nuxeo Json entity. This class write the json object, the json "entity-type" property and enable 040 * all activated enrichers registered in the {@link MarshallerRegistry} and compatible with the marshalled Java type. 041 * 042 * @param <EntityType> The managed Java type. 043 * @since 7.2 044 */ 045public abstract class ExtensibleEntityJsonWriter<EntityType> extends AbstractJsonWriter<EntityType> { 046 047 /** 048 * The "entity-type" Json property value. 049 */ 050 private final String entityType; 051 052 /** 053 * The {@link Enriched} generic type parametrized with the given EntityType. 054 */ 055 private final Type genericType; 056 057 /** 058 * @param entityType The "entity-type" Json property value. 059 * @param entityClass The entity type. 060 */ 061 public ExtensibleEntityJsonWriter(String entityType, Class<EntityType> entityClass) { 062 super(); 063 this.entityType = entityType; 064 genericType = TypeUtils.parameterize(Enriched.class, entityClass); 065 } 066 067 @Override 068 public void write(EntityType entity, JsonGenerator jg) throws IOException { 069 jg.writeStartObject(); 070 jg.writeStringField(ENTITY_FIELD_NAME, entityType); 071 writeEntityBody(entity, jg); 072 try { 073 WrappedContext wrappedCtx = ctx.wrap().controlDepth(); 074 Set<String> enrichers = ctx.getEnrichers(entityType); 075 if (enrichers.size() > 0) { 076 boolean hasEnrichers = false; 077 Enriched<EntityType> enriched = null; 078 for (String enricherName : enrichers) { 079 try (Closeable resource = wrappedCtx.with(ENTITY_ENRICHER_NAME, enricherName).open()) { 080 @SuppressWarnings("rawtypes") 081 Collection<Writer<Enriched>> writers = registry.getAllWriters(ctx, Enriched.class, 082 this.genericType, APPLICATION_JSON_TYPE); 083 for (@SuppressWarnings("rawtypes") 084 Writer<Enriched> writer : writers) { 085 if (!hasEnrichers) { 086 hasEnrichers = true; 087 jg.writeObjectFieldStart("contextParameters"); 088 enriched = new Enriched<EntityType>(entity); 089 } 090 OutputStreamWithJsonWriter out = new OutputStreamWithJsonWriter(jg); 091 writer.write(enriched, Enriched.class, this.genericType, APPLICATION_JSON_TYPE, out); 092 } 093 } 094 } 095 if (hasEnrichers) { 096 jg.writeEndObject(); 097 } 098 } 099 } catch (MaxDepthReachedException e) { 100 // do nothing, do not call enrichers 101 } 102 extend(entity, jg); 103 jg.writeEndObject(); 104 } 105 106 /** 107 * Implement this method to write the entity body. 108 * 109 * @param entity The Java entity. 110 * @param jg A {@link JsonGenerator} ready to write your entity as Json. 111 * @since 7.2 112 */ 113 protected abstract void writeEntityBody(EntityType entity, JsonGenerator jg) throws IOException; 114 115 /** 116 * Override this method to add additional property in the entity. This method is useful to override a marshaller 117 * implementing this class. 118 * 119 * @param entity The Java entity. 120 * @param jg A {@link JsonGenerator} ready to write your entity as Json. 121 * @since 7.2 122 */ 123 protected void extend(EntityType entity, JsonGenerator jg) throws IOException { 124 } 125 126}