001/* 002 * Copyright (c) 2006-2012 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 * Nuxeo 011 */ 012 013package org.nuxeo.ecm.automation.jaxrs.io; 014 015import java.io.IOException; 016import java.io.OutputStream; 017import java.io.Serializable; 018import java.lang.annotation.Annotation; 019import java.lang.reflect.Type; 020import java.util.Map; 021 022import javax.ws.rs.Produces; 023import javax.ws.rs.WebApplicationException; 024import javax.ws.rs.core.Context; 025import javax.ws.rs.core.MediaType; 026import javax.ws.rs.core.MultivaluedMap; 027import javax.ws.rs.ext.MessageBodyWriter; 028import javax.ws.rs.ext.Provider; 029 030import org.apache.commons.logging.Log; 031import org.apache.commons.logging.LogFactory; 032import org.codehaus.jackson.JsonEncoding; 033import org.codehaus.jackson.JsonFactory; 034import org.codehaus.jackson.JsonGenerator; 035import org.nuxeo.ecm.automation.core.util.PaginableRecordSet; 036import org.nuxeo.ecm.automation.core.util.RecordSet; 037 038/** 039 * Manage JSON Marshalling for {@link RecordSet} objects 040 * 041 * @author <a href="mailto:tdelprat@nuxeo.com">Tiry</a> 042 * @since 5.7 043 */ 044@Provider 045@Produces({ "application/json+nxentity", "application/json" }) 046public class JsonRecordSetWriter implements MessageBodyWriter<RecordSet> { 047 048 protected static Log log = LogFactory.getLog(JsonRecordSetWriter.class); 049 050 @Context 051 JsonFactory factory; 052 053 @Override 054 public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { 055 boolean canUse = RecordSet.class.isAssignableFrom(type); 056 return canUse; 057 } 058 059 @Override 060 public long getSize(RecordSet t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { 061 return -1L; 062 } 063 064 @Override 065 public void writeTo(RecordSet records, Class<?> type, Type genericType, Annotation[] annotations, 066 MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream out) throws IOException, 067 WebApplicationException { 068 try { 069 writeRecords(out, records); 070 } catch (IOException e) { 071 log.error("Failed to serialize recordset", e); 072 throw new WebApplicationException(500); 073 } 074 075 } 076 077 protected void writeRecords(OutputStream out, RecordSet records) throws IOException { 078 079 JsonGenerator jg = factory.createJsonGenerator(out, JsonEncoding.UTF8); 080 081 jg.writeStartObject(); 082 jg.writeStringField("entity-type", "recordSet"); 083 084 if (records instanceof PaginableRecordSet) { 085 PaginableRecordSet pRecord = (PaginableRecordSet) records; 086 jg.writeBooleanField("isPaginable", true); 087 jg.writeNumberField("resultsCount", pRecord.getResultsCount()); 088 jg.writeNumberField("pageSize", pRecord.getPageSize()); 089 jg.writeNumberField("maxPageSize", pRecord.getMaxPageSize()); 090 jg.writeNumberField("currentPageSize", pRecord.getCurrentPageSize()); 091 jg.writeNumberField("currentPageIndex", pRecord.getCurrentPageIndex()); 092 jg.writeNumberField("numberOfPages", pRecord.getNumberOfPages()); 093 jg.writeBooleanField("isPreviousPageAvailable", pRecord.isPreviousPageAvailable()); 094 jg.writeBooleanField("isNextPageAvailable", pRecord.isNextPageAvailable()); 095 jg.writeBooleanField("isLastPageAvailable", pRecord.isLastPageAvailable()); 096 jg.writeBooleanField("isSortable", pRecord.isSortable()); 097 jg.writeBooleanField("hasError", pRecord.hasError()); 098 jg.writeStringField("errorMessage", pRecord.getErrorMessage()); 099 } 100 101 jg.writeArrayFieldStart("entries"); 102 for (Map<String, Serializable> entry : records) { 103 jg.writeObject(entry); 104 } 105 106 if (records instanceof PaginableRecordSet) { 107 PaginableRecordSet pRecord = (PaginableRecordSet) records; 108 if (pRecord.hasAggregateSupport() && pRecord.getAggregates() != null && !pRecord.getAggregates().isEmpty()) { 109 jg.writeObjectField("aggregations", pRecord.getAggregates()); 110 } 111 } 112 113 jg.writeEndArray(); 114 jg.writeEndObject(); 115 jg.flush(); 116 } 117 118}