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