001/* 002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the Eclipse Public License v1.0 006 * which accompanies this distribution, and is available at 007 * http://www.eclipse.org/legal/epl-v10.html 008 * 009 * Contributors: 010 * bstefanescu 011 * Thierry Delprat 012 */ 013package org.nuxeo.ecm.automation.jaxrs.io.documents; 014 015import static org.apache.commons.lang.StringUtils.isBlank; 016 017import java.io.IOException; 018import java.io.OutputStream; 019import java.lang.annotation.Annotation; 020import java.lang.reflect.Type; 021import java.util.HashMap; 022import java.util.List; 023import java.util.Map; 024 025import javax.servlet.ServletRequest; 026import javax.servlet.http.HttpServletRequest; 027import javax.ws.rs.Produces; 028import javax.ws.rs.WebApplicationException; 029import javax.ws.rs.core.Context; 030import javax.ws.rs.core.HttpHeaders; 031import javax.ws.rs.core.MediaType; 032import javax.ws.rs.core.MultivaluedMap; 033import javax.ws.rs.ext.Provider; 034 035import org.apache.commons.logging.Log; 036import org.apache.commons.logging.LogFactory; 037import org.codehaus.jackson.JsonEncoding; 038import org.codehaus.jackson.JsonFactory; 039import org.codehaus.jackson.JsonGenerator; 040import org.nuxeo.common.utils.StringUtils; 041import org.nuxeo.ecm.automation.core.util.PaginableDocumentModelList; 042import org.nuxeo.ecm.automation.jaxrs.io.EntityListWriter; 043import org.nuxeo.ecm.core.api.DocumentLocation; 044import org.nuxeo.ecm.core.api.DocumentModel; 045import org.nuxeo.ecm.core.api.DocumentModelList; 046import org.nuxeo.ecm.core.api.impl.DocumentLocationImpl; 047import org.nuxeo.ecm.core.io.marshallers.json.document.DocumentModelListJsonWriter; 048import org.nuxeo.ecm.directory.api.DirectoryEntry; 049import org.nuxeo.ecm.platform.types.adapter.TypeInfo; 050import org.nuxeo.ecm.platform.url.DocumentViewImpl; 051import org.nuxeo.ecm.platform.url.api.DocumentView; 052import org.nuxeo.ecm.platform.url.api.DocumentViewCodecManager; 053import org.nuxeo.ecm.platform.web.common.vh.VirtualHostHelper; 054import org.nuxeo.ecm.webengine.jaxrs.coreiodelegate.JsonCoreIODelegate; 055import org.nuxeo.runtime.api.Framework; 056 057/** 058 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> 059 * @deprecated since 7.10 The Nuxeo JSON marshalling was migrated to nuxeo-core-io. This class is replaced by 060 * {@link DocumentModelListJsonWriter} which is registered by default and available to marshal 061 * {@link DirectoryEntry} from the Nuxeo Rest API thanks to the JAX-RS marshaller {@link JsonCoreIODelegate} 062 */ 063@Deprecated 064@Provider 065@Produces({ "application/json+nxentity", "application/json" }) 066public class JsonDocumentListWriter extends EntityListWriter<DocumentModel> { 067 068 private static final Log log = LogFactory.getLog(JsonDocumentListWriter.class); 069 070 @Context 071 JsonFactory factory; 072 073 @Context 074 protected HttpHeaders headers; 075 076 @Context 077 protected HttpServletRequest request; 078 079 @Override 080 protected String getEntityType() { 081 return "documents"; 082 } 083 084 @Override 085 protected void writeItem(JsonGenerator jg, DocumentModel item) throws IOException { 086 // do nothing, everything is done in #writeTo 087 } 088 089 @Override 090 public boolean isWriteable(Class<?> arg0, Type arg1, Annotation[] arg2, MediaType arg3) { 091 return DocumentModelList.class.isAssignableFrom(arg0); 092 } 093 094 @Override 095 public void writeTo(List<DocumentModel> docs, Class<?> type, Type genericType, Annotation[] annotations, 096 MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) 097 throws IOException, WebApplicationException { 098 try { 099 List<String> props = headers.getRequestHeader(JsonDocumentWriter.DOCUMENT_PROPERTIES_HEADER); 100 String[] schemas = null; 101 if (props != null && !props.isEmpty()) { 102 schemas = StringUtils.split(props.get(0), ',', true); 103 } 104 writeDocuments(entityStream, docs, schemas, headers); 105 } catch (IOException e) { 106 log.error("Failed to serialize document list", e); 107 throw new WebApplicationException(500); 108 } 109 } 110 111 public void writeDocuments(OutputStream out, List<DocumentModel> docs, String[] schemas) throws IOException { 112 writeDocuments(factory.createJsonGenerator(out, JsonEncoding.UTF8), docs, schemas, request); 113 } 114 115 /** 116 * @since 5.9.5 117 */ 118 public void writeDocuments(OutputStream out, List<DocumentModel> docs, String[] schemas, HttpHeaders headers) 119 throws IOException { 120 writeDocuments(factory.createJsonGenerator(out, JsonEncoding.UTF8), docs, schemas, headers, request); 121 } 122 123 public static void writeDocuments(JsonGenerator jg, List<DocumentModel> docs, String[] schemas, 124 ServletRequest request) throws IOException { 125 writeDocuments(jg, docs, schemas, null, request); 126 } 127 128 /** 129 * @since 5.9.5 130 */ 131 public static void writeDocuments(JsonGenerator jg, List<DocumentModel> docs, String[] schemas, 132 HttpHeaders headers, ServletRequest request) throws IOException { 133 jg.writeStartObject(); 134 jg.writeStringField("entity-type", "documents"); 135 136 if (docs instanceof PaginableDocumentModelList) { 137 PaginableDocumentModelList provider = (PaginableDocumentModelList) docs; 138 jg.writeBooleanField("isPaginable", true); 139 jg.writeNumberField("resultsCount", provider.getResultsCount()); 140 jg.writeNumberField("pageSize", provider.getPageSize()); 141 jg.writeNumberField("maxPageSize", provider.getMaxPageSize()); 142 jg.writeNumberField("currentPageSize", provider.getCurrentPageSize()); 143 jg.writeNumberField("currentPageIndex", provider.getCurrentPageIndex()); 144 jg.writeNumberField("numberOfPages", provider.getNumberOfPages()); 145 jg.writeBooleanField("isPreviousPageAvailable", provider.isPreviousPageAvailable()); 146 jg.writeBooleanField("isNextPageAvailable", provider.isNextPageAvailable()); 147 jg.writeBooleanField("isLastPageAvailable", provider.isLastPageAvailable()); 148 jg.writeBooleanField("isSortable", provider.isSortable()); 149 jg.writeBooleanField("hasError", provider.hasError()); 150 jg.writeStringField("errorMessage", provider.getErrorMessage()); 151 152 // compat fields 153 jg.writeNumberField("totalSize", provider.totalSize()); 154 jg.writeNumberField("pageIndex", provider.getCurrentPageIndex()); 155 jg.writeNumberField("pageCount", provider.getNumberOfPages()); 156 157 DocumentViewCodecManager documentViewCodecManager = Framework.getLocalService(DocumentViewCodecManager.class); 158 String codecName = null; 159 if (documentViewCodecManager == null) { 160 log.warn("Service 'DocumentViewCodecManager' not available : documentUrl won't be generated"); 161 } else { 162 String documentLinkBuilder = provider.getDocumentLinkBuilder(); 163 codecName = isBlank(documentLinkBuilder) ? documentViewCodecManager.getDefaultCodecName() 164 : documentLinkBuilder; 165 } 166 167 jg.writeArrayFieldStart("entries"); 168 for (DocumentModel doc : docs) { 169 DocumentLocation docLoc = new DocumentLocationImpl(doc); 170 Map<String, String> contextParameters = new HashMap<String, String>(); 171 if (documentViewCodecManager != null) { 172 DocumentView docView = new DocumentViewImpl(docLoc, doc.getAdapter(TypeInfo.class).getDefaultView()); 173 String documentURL = VirtualHostHelper.getContextPathProperty() + "/" 174 + documentViewCodecManager.getUrlFromDocumentView(codecName, docView, false, null); 175 contextParameters.put("documentURL", documentURL); 176 } 177 JsonDocumentWriter.writeDocument(jg, doc, schemas, contextParameters, headers, request); 178 } 179 jg.writeEndArray(); 180 if (provider.hasAggregateSupport() && provider.getAggregates() != null 181 && !provider.getAggregates().isEmpty()) { 182 jg.writeObjectField("aggregations", provider.getAggregates()); 183 } 184 } else { 185 jg.writeArrayFieldStart("entries"); 186 for (DocumentModel doc : docs) { 187 JsonDocumentWriter.writeDocument(jg, doc, schemas, new HashMap<String, String>(), headers, request); 188 } 189 jg.writeEndArray(); 190 } 191 192 jg.writeEndObject(); 193 jg.flush(); 194 } 195 196}