001/*
002 * (C) Copyright 2006-2007 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 *     Nuxeo - initial API and implementation
018 *
019 * $Id: JOOoConvertPluginImpl.java 18651 2007-05-13 20:28:53Z sfermigier $
020 */
021
022package org.nuxeo.ecm.platform.ui.web.restAPI;
023
024import java.io.IOException;
025import java.io.InputStream;
026import java.io.Serializable;
027import java.io.UnsupportedEncodingException;
028import java.net.URLDecoder;
029
030import org.nuxeo.ecm.core.api.Blob;
031import org.nuxeo.ecm.core.api.Blobs;
032import org.nuxeo.ecm.core.api.CloseableCoreSession;
033import org.nuxeo.ecm.core.api.CoreInstance;
034import org.nuxeo.ecm.core.api.CoreSession;
035import org.nuxeo.ecm.core.api.DocumentModel;
036import org.nuxeo.ecm.core.api.IdRef;
037import org.nuxeo.ecm.core.api.NuxeoException;
038import org.nuxeo.ecm.core.api.PropertyException;
039import org.nuxeo.ecm.core.api.VersioningOption;
040import org.nuxeo.ecm.platform.ui.web.tag.fn.LiveEditConstants;
041import org.nuxeo.ecm.platform.util.RepositoryLocation;
042import org.nuxeo.runtime.api.Framework;
043import org.restlet.Request;
044import org.restlet.Response;
045
046/**
047 * Restlet to help LiveEdit clients update the blob content of a document
048 *
049 * @author Sun Tan <stan@nuxeo.com>
050 * @author Olivier Grisel <ogrisel@nuxeo.com>
051 */
052public class UploadFileRestlet extends BaseNuxeoRestlet implements LiveEditConstants, Serializable {
053
054    public static final String LIVED_AUTOVERSIONING_PROP = "org.nuxeo.ecm.platform.liveedit.autoversioning";
055
056    public static final String POLICY_MINOR_INCR = "minor";
057
058    private static final long serialVersionUID = -6167207806181917456L;
059
060    @SuppressWarnings("deprecation")
061    @Override
062    public void handle(Request req, Response res) {
063        logDeprecation();
064        String repo = (String) req.getAttributes().get("repo");
065        String docid = (String) req.getAttributes().get("docid");
066        String filename = (String) req.getAttributes().get("filename");
067        try {
068            filename = URLDecoder.decode(filename, URL_ENCODE_CHARSET);
069        } catch (UnsupportedEncodingException e) {
070            handleError(res, e);
071            return;
072        }
073
074        if (repo == null || repo.equals("*")) {
075            handleError(res, "you must specify a repository");
076            return;
077        }
078
079        DocumentModel dm = null;
080        try (CloseableCoreSession documentManager = CoreInstance.openCoreSession(repo)) {
081            if (docid != null) {
082                dm = documentManager.getDocument(new IdRef(docid));
083            }
084
085            String blobPropertyName = getQueryParamValue(req, BLOB_PROPERTY_NAME, null);
086
087            if (blobPropertyName == null) {
088                // find the names of the fields from the optional request
089                // parameters with fallback to defaults if none is provided
090                String schemaName = getQueryParamValue(req, SCHEMA, DEFAULT_SCHEMA);
091                String blobFieldName = getQueryParamValue(req, BLOB_FIELD, DEFAULT_BLOB_FIELD);
092                blobPropertyName = schemaName + ":" + blobFieldName;
093            }
094
095            try (InputStream is = req.getEntity().getStream()) {
096                saveFileToDocument(filename, dm, blobPropertyName, is);
097            }
098        } catch (NuxeoException | IOException e) {
099            handleError(res, e);
100        }
101    }
102
103    /**
104     * Save the file into the document.
105     *
106     * @deprecated since 9.1 filename is now stored in blob
107     */
108    @Deprecated
109    protected void saveFileToDocument(String filename, DocumentModel dm, String blobPropertyName,
110            String filenamePropertyName, InputStream is) throws IOException, PropertyException {
111        saveFileToDocument(filename, dm, blobPropertyName, is);
112    }
113
114    /**
115     * Save the file into the document.
116     */
117    protected void saveFileToDocument(String filename, DocumentModel dm, String blobPropertyName,
118            InputStream is) throws IOException, PropertyException {
119        // persisting the blob makes it possible to read the binary content
120        // of the request stream several times (mimetype sniffing, digest
121        // computation, core binary storage)
122        Blob blob = Blobs.createBlob(is);
123        blob.setFilename(filename);
124
125        dm.setPropertyValue(blobPropertyName, (Serializable) blob);
126
127        dm.getCoreSession().saveDocument(dm);
128        // autoversioning see https://jira.nuxeo.org/browse/NXP-5849 for more
129        // details
130        String versioningPolicy = Framework.getProperty(LIVED_AUTOVERSIONING_PROP);
131        if (doAutoMinorIncrement(versioningPolicy, dm)) {
132            if (dm.isCheckedOut()) {
133                dm.checkIn(VersioningOption.MINOR, "Live edit (UploadFileRestlet) autoversioning");
134            }
135        }
136
137        dm.getCoreSession().save();
138    }
139
140    /**
141     * According to the policy, decide to auto minor increment or not
142     *
143     * @param policy
144     * @return return true if the the version should be minor increment
145     */
146    protected boolean doAutoMinorIncrement(String policy, DocumentModel doc) {
147        if (POLICY_MINOR_INCR.equals(policy)) {
148            return true;
149        }
150        return false;
151
152    }
153}