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 * @deprecated since 8.3, use
051 *             {@link org.nuxeo.ecm.core.io.registry.Writer#write(Object, Class, java.lang.reflect.Type, javax.ws.rs.core.MediaType, java.io.OutputStream)}
052 *             instead. See how
053 *             {@link org.nuxeo.ecm.platform.routing.core.io.DocumentRouteWriter#writeVariables(org.nuxeo.ecm.platform.routing.api.DocumentRoute, JsonGenerator, org.nuxeo.ecm.core.io.registry.MarshallerRegistry, org.nuxeo.ecm.core.io.registry.context.RenderingContext, SchemaManager)}
054 *             uses it.
055 */
056@Deprecated
057public class JsonEncodeDecodeUtils {
058
059    public static void encodeBlob(DocumentModel doc, String propVariableFacet, String variableName, Blob blob,
060            JsonGenerator jg, ServletRequest request) throws JsonGenerationException, IOException {
061        if (blob == null) {
062            jg.writeNull();
063            return;
064        }
065        jg.writeStartObject();
066        String filename = blob.getFilename();
067        if (filename == null) {
068            jg.writeNullField("name");
069        } else {
070            jg.writeStringField("name", filename);
071        }
072        String v = blob.getMimeType();
073        if (v == null) {
074            jg.writeNullField("mime-type");
075        } else {
076            jg.writeStringField("mime-type", v);
077        }
078        v = blob.getEncoding();
079        if (v == null) {
080            jg.writeNullField("encoding");
081        } else {
082            jg.writeStringField("encoding", v);
083        }
084        v = blob.getDigest();
085        if (v == null) {
086            jg.writeNullField("digest");
087        } else {
088            jg.writeStringField("digest", v);
089        }
090        jg.writeStringField("length", Long.toString(blob.getLength()));
091
092        String facet = null;
093        try {
094            facet = (String) doc.getPropertyValue(propVariableFacet);
095        } catch (PropertyNotFoundException e) {
096            facet = propVariableFacet;
097        }
098        if (StringUtils.isBlank(facet)) {
099            return;
100        }
101        CompositeType type = Framework.getLocalService(SchemaManager.class).getFacet(facet);
102
103        DownloadService downloadService = Framework.getService(DownloadService.class);
104        String xpath = type.getField(variableName).getName().getPrefixedName();
105        String blobUrl = VirtualHostHelper.getBaseURL(request) + downloadService.getDownloadUrl(doc, xpath, filename);
106        jg.writeStringField("url", blobUrl);
107
108        jg.writeEndObject();
109    }
110
111    public static Map<String, Serializable> decodeVariables(JsonNode jsnode,
112            Map<String, Serializable> originalVariables, CoreSession session) throws ClassNotFoundException,
113            IOException {
114        Map<String, Serializable> variables = new HashMap<String, Serializable>();
115        Iterator<Entry<String, JsonNode>> it = jsnode.getFields();
116        while (it.hasNext()) {
117            Entry<String, JsonNode> variable = it.next();
118            String key = variable.getKey();
119            JsonNode value = variable.getValue();
120            if (value.isNumber()) {
121                // We are working with String which will be correctly decoded by
122                // org.nuxeo.ecm.platform.routing.core.impl.GraphVariablesUtil.setJSONVariables(DocumentModel, String,
123                // Map<String, String>, boolean)
124                // But we'll definitely need to convert submitted json variable to proper typed objects
125                variables.put(key, value.getNumberValue().toString());
126            } else if (value.isObject()) {
127                if (value.has("upload-batch")) {
128                    // Decoding of the blob will be handled in ComplexTypeJSONDecoder.decode
129                    ObjectNode upload = (ObjectNode) value;
130                    upload.put("type", "blob");
131                    variables.put(key, upload.toString());
132                }
133            } else {
134                variables.put(key, value.getTextValue());
135            }
136
137        }
138        return variables;
139    }
140
141    public static void encodeVariableEntry(DocumentModel doc, String propVariableFacet, Entry<String, Serializable> e, JsonGenerator jg,
142            HttpServletRequest request) throws JsonGenerationException, IOException {
143        if (e.getValue() instanceof Blob) {
144            jg.writeFieldName(e.getKey());
145            JsonEncodeDecodeUtils.encodeBlob(doc, propVariableFacet, e.getKey(), (Blob) e.getValue(), jg,
146                    request);
147        } else {
148            jg.writeObjectField(e.getKey(), e.getValue());
149        }
150    }
151}