001/* 002 * (C) Copyright 2014 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 * <a href="mailto:grenard@nuxeo.com">Guillaume Renard</a> 016 * 017 */ 018 019package org.nuxeo.ecm.restapi.server.jaxrs.routing.io.util; 020 021import java.io.IOException; 022import java.io.Serializable; 023import java.util.HashMap; 024import java.util.Iterator; 025import java.util.Map; 026import java.util.Map.Entry; 027 028import javax.servlet.ServletRequest; 029import javax.servlet.http.HttpServletRequest; 030 031import org.apache.commons.lang.StringUtils; 032import org.codehaus.jackson.JsonGenerationException; 033import org.codehaus.jackson.JsonGenerator; 034import org.codehaus.jackson.JsonNode; 035import org.codehaus.jackson.node.ObjectNode; 036import org.nuxeo.ecm.core.api.Blob; 037import org.nuxeo.ecm.core.api.CoreSession; 038import org.nuxeo.ecm.core.api.DocumentModel; 039import org.nuxeo.ecm.core.api.model.PropertyNotFoundException; 040import org.nuxeo.ecm.core.io.download.DownloadService; 041import org.nuxeo.ecm.core.schema.SchemaManager; 042import org.nuxeo.ecm.core.schema.types.CompositeType; 043import org.nuxeo.ecm.platform.web.common.vh.VirtualHostHelper; 044import org.nuxeo.runtime.api.Framework; 045 046/** 047 * @since 7.2 048 */ 049public class JsonEncodeDecodeUtils { 050 051 public static void encodeBlob(DocumentModel doc, String propVariableFacet, String variableName, Blob blob, 052 JsonGenerator jg, ServletRequest request) throws JsonGenerationException, IOException { 053 if (blob == null) { 054 jg.writeNull(); 055 return; 056 } 057 jg.writeStartObject(); 058 String filename = blob.getFilename(); 059 if (filename == null) { 060 jg.writeNullField("name"); 061 } else { 062 jg.writeStringField("name", filename); 063 } 064 String v = blob.getMimeType(); 065 if (v == null) { 066 jg.writeNullField("mime-type"); 067 } else { 068 jg.writeStringField("mime-type", v); 069 } 070 v = blob.getEncoding(); 071 if (v == null) { 072 jg.writeNullField("encoding"); 073 } else { 074 jg.writeStringField("encoding", v); 075 } 076 v = blob.getDigest(); 077 if (v == null) { 078 jg.writeNullField("digest"); 079 } else { 080 jg.writeStringField("digest", v); 081 } 082 jg.writeStringField("length", Long.toString(blob.getLength())); 083 084 String facet = null; 085 try { 086 facet = (String) doc.getPropertyValue(propVariableFacet); 087 } catch (PropertyNotFoundException e) { 088 facet = propVariableFacet; 089 } 090 if (StringUtils.isBlank(facet)) { 091 return; 092 } 093 CompositeType type = Framework.getLocalService(SchemaManager.class).getFacet(facet); 094 095 DownloadService downloadService = Framework.getService(DownloadService.class); 096 String xpath = type.getField(variableName).getName().getPrefixedName(); 097 String blobUrl = VirtualHostHelper.getBaseURL(request) + downloadService.getDownloadUrl(doc, xpath, filename); 098 jg.writeStringField("url", blobUrl); 099 100 jg.writeEndObject(); 101 } 102 103 public static Map<String, Serializable> decodeVariables(JsonNode jsnode, 104 Map<String, Serializable> originalVariables, CoreSession session) throws ClassNotFoundException, 105 IOException { 106 Map<String, Serializable> variables = new HashMap<String, Serializable>(); 107 Iterator<Entry<String, JsonNode>> it = jsnode.getFields(); 108 while (it.hasNext()) { 109 Entry<String, JsonNode> variable = it.next(); 110 String key = variable.getKey(); 111 JsonNode value = variable.getValue(); 112 if (value.isNumber()) { 113 // We are working with String which will be correctly decoded by 114 // org.nuxeo.ecm.platform.routing.core.impl.GraphVariablesUtil.setJSONVariables(DocumentModel, String, 115 // Map<String, String>, boolean) 116 // But we'll definitely need to convert submitted json variable to proper typed objects 117 variables.put(key, value.getNumberValue().toString()); 118 } else if (value.isObject()) { 119 if (value.has("upload-batch")) { 120 // Decoding of the blob will be handled in ComplexTypeJSONDecoder.decode 121 ObjectNode upload = (ObjectNode) value; 122 upload.put("type", "blob"); 123 variables.put(key, upload.toString()); 124 } 125 } else { 126 variables.put(key, value.getTextValue()); 127 } 128 129 } 130 return variables; 131 } 132 133 public static void encodeVariableEntry(DocumentModel doc, String propVariableFacet, Entry<String, Serializable> e, JsonGenerator jg, 134 HttpServletRequest request) throws JsonGenerationException, IOException { 135 if (e.getValue() instanceof Blob) { 136 jg.writeFieldName(e.getKey()); 137 JsonEncodeDecodeUtils.encodeBlob(doc, propVariableFacet, e.getKey(), (Blob) e.getValue(), jg, 138 request); 139 } else { 140 jg.writeObjectField(e.getKey(), e.getValue()); 141 } 142 } 143}