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.core.io.registry.MarshallerHelper; 049import org.nuxeo.ecm.core.io.registry.MarshallerRegistry; 050import org.nuxeo.ecm.platform.types.adapter.TypeInfo; 051import org.nuxeo.ecm.platform.url.DocumentViewImpl; 052import org.nuxeo.ecm.platform.url.api.DocumentView; 053import org.nuxeo.ecm.platform.url.api.DocumentViewCodecManager; 054import org.nuxeo.ecm.platform.web.common.vh.VirtualHostHelper; 055import org.nuxeo.ecm.webengine.jaxrs.coreiodelegate.JsonCoreIODelegate; 056import org.nuxeo.runtime.api.Framework; 057 058/** 059 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> 060 * @deprecated this JAX-RS marshaller was migrated to {@link DocumentModelListJsonWriter}. To use it in JAX-RS, use 061 * {@link JsonCoreIODelegate} to forward JAX-RS marshalling to core io. To use it your code, please refer to 062 * {@link MarshallerRegistry} service or use {@link MarshallerHelper}. 063 */ 064@Deprecated 065@Provider 066@Produces({ "application/json+nxentity", "application/json" }) 067public class JsonDocumentListWriter extends EntityListWriter<DocumentModel> { 068 069 private static final Log log = LogFactory.getLog(JsonDocumentListWriter.class); 070 071 @Context 072 JsonFactory factory; 073 074 @Context 075 protected HttpHeaders headers; 076 077 @Context 078 protected HttpServletRequest request; 079 080 @Override 081 protected String getEntityType() { 082 return "documents"; 083 } 084 085 @Override 086 protected void writeItem(JsonGenerator jg, DocumentModel item) throws IOException { 087 // do nothing, everything is done in #writeTo 088 } 089 090 @Override 091 public boolean isWriteable(Class<?> arg0, Type arg1, Annotation[] arg2, MediaType arg3) { 092 return DocumentModelList.class.isAssignableFrom(arg0); 093 } 094 095 @Override 096 public void writeTo(List<DocumentModel> docs, Class<?> type, Type genericType, Annotation[] annotations, 097 MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) 098 throws IOException, WebApplicationException { 099 try { 100 List<String> props = headers.getRequestHeader(JsonDocumentWriter.DOCUMENT_PROPERTIES_HEADER); 101 String[] schemas = null; 102 if (props != null && !props.isEmpty()) { 103 schemas = StringUtils.split(props.get(0), ',', true); 104 } 105 writeDocuments(entityStream, docs, schemas, headers); 106 } catch (IOException e) { 107 log.error("Failed to serialize document list", e); 108 throw new WebApplicationException(500); 109 } 110 } 111 112 public void writeDocuments(OutputStream out, List<DocumentModel> docs, String[] schemas) throws IOException { 113 writeDocuments(factory.createJsonGenerator(out, JsonEncoding.UTF8), docs, schemas, request); 114 } 115 116 /** 117 * @since 5.9.5 118 */ 119 public void writeDocuments(OutputStream out, List<DocumentModel> docs, String[] schemas, HttpHeaders headers) 120 throws IOException { 121 writeDocuments(factory.createJsonGenerator(out, JsonEncoding.UTF8), docs, schemas, headers, request); 122 } 123 124 public static void writeDocuments(JsonGenerator jg, List<DocumentModel> docs, String[] schemas, 125 ServletRequest request) throws IOException { 126 writeDocuments(jg, docs, schemas, null, request); 127 } 128 129 /** 130 * @since 5.9.5 131 */ 132 public static void writeDocuments(JsonGenerator jg, List<DocumentModel> docs, String[] schemas, 133 HttpHeaders headers, ServletRequest request) throws IOException { 134 jg.writeStartObject(); 135 jg.writeStringField("entity-type", "documents"); 136 137 if (docs instanceof PaginableDocumentModelList) { 138 PaginableDocumentModelList provider = (PaginableDocumentModelList) docs; 139 jg.writeBooleanField("isPaginable", true); 140 jg.writeNumberField("resultsCount", provider.getResultsCount()); 141 jg.writeNumberField("pageSize", provider.getPageSize()); 142 jg.writeNumberField("maxPageSize", provider.getMaxPageSize()); 143 jg.writeNumberField("currentPageSize", provider.getCurrentPageSize()); 144 jg.writeNumberField("currentPageIndex", provider.getCurrentPageIndex()); 145 jg.writeNumberField("numberOfPages", provider.getNumberOfPages()); 146 jg.writeBooleanField("isPreviousPageAvailable", provider.isPreviousPageAvailable()); 147 jg.writeBooleanField("isNextPageAvailable", provider.isNextPageAvailable()); 148 jg.writeBooleanField("isLastPageAvailable", provider.isLastPageAvailable()); 149 jg.writeBooleanField("isSortable", provider.isSortable()); 150 jg.writeBooleanField("hasError", provider.hasError()); 151 jg.writeStringField("errorMessage", provider.getErrorMessage()); 152 153 // compat fields 154 jg.writeNumberField("totalSize", provider.totalSize()); 155 jg.writeNumberField("pageIndex", provider.getCurrentPageIndex()); 156 jg.writeNumberField("pageCount", provider.getNumberOfPages()); 157 158 DocumentViewCodecManager documentViewCodecManager = Framework.getLocalService(DocumentViewCodecManager.class); 159 String codecName = null; 160 if (documentViewCodecManager == null) { 161 log.warn("Service 'DocumentViewCodecManager' not available : documentUrl won't be generated"); 162 } else { 163 String documentLinkBuilder = provider.getDocumentLinkBuilder(); 164 codecName = isBlank(documentLinkBuilder) ? documentViewCodecManager.getDefaultCodecName() 165 : documentLinkBuilder; 166 } 167 168 jg.writeArrayFieldStart("entries"); 169 for (DocumentModel doc : docs) { 170 DocumentLocation docLoc = new DocumentLocationImpl(doc); 171 Map<String, String> contextParameters = new HashMap<String, String>(); 172 if (documentViewCodecManager != null) { 173 DocumentView docView = new DocumentViewImpl(docLoc, doc.getAdapter(TypeInfo.class).getDefaultView()); 174 String documentURL = VirtualHostHelper.getContextPathProperty() + "/" 175 + documentViewCodecManager.getUrlFromDocumentView(codecName, docView, false, null); 176 contextParameters.put("documentURL", documentURL); 177 } 178 JsonDocumentWriter.writeDocument(jg, doc, schemas, contextParameters, headers, request); 179 } 180 jg.writeEndArray(); 181 if (provider.hasAggregateSupport() && provider.getAggregates() != null 182 && !provider.getAggregates().isEmpty()) { 183 jg.writeObjectField("aggregations", provider.getAggregates()); 184 } 185 } else { 186 jg.writeArrayFieldStart("entries"); 187 for (DocumentModel doc : docs) { 188 JsonDocumentWriter.writeDocument(jg, doc, schemas, new HashMap<String, String>(), headers, request); 189 } 190 jg.writeEndArray(); 191 } 192 193 jg.writeEndObject(); 194 jg.flush(); 195 } 196 197}