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