org.linagora.linshare.webservice.utils.FlowUploaderUtils.java Source code

Java tutorial

Introduction

Here is the source code for org.linagora.linshare.webservice.utils.FlowUploaderUtils.java

Source

/*
 * LinShare is an open source filesharing software, part of the LinPKI software
 * suite, developed by Linagora.
 *
 * Copyright (C) 2015 LINAGORA
 *
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License as published by the Free
 * Software Foundation, either version 3 of the License, or (at your option) any
 * later version, provided you comply with the Additional Terms applicable for
 * LinShare software by Linagora pursuant to Section 7 of the GNU Affero General
 * Public License, subsections (b), (c), and (e), pursuant to which you must
 * notably (i) retain the display of the LinShare? trademark/logo at the top
 * of the interface window, the display of the You are using the Open Source
 * and free version of LinShare, powered by Linagora  20092015. Contribute to
 * Linshare R&D by subscribing to an Enterprise offer!? infobox and in the
 * e-mails sent with the Program, (ii) retain all hypertext links between
 * LinShare and linshare.org, between linagora.com and Linagora, and (iii)
 * refrain from infringing Linagora intellectual property rights over its
 * trademarks and commercial brands. Other Additional Terms apply, see
 * <http://www.linagora.com/licenses/> for more details.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License and
 * its applicable Additional Terms for LinShare along with this program. If not,
 * see <http://www.gnu.org/licenses/> for the GNU Affero General Public License
 * version 3 and <http://www.linagora.com/licenses/> for the Additional Terms
 * applicable to LinShare software.
 */
package org.linagora.linshare.webservice.utils;

import java.io.IOException;
import java.nio.file.Files;
import java.util.concurrent.ConcurrentMap;

import javax.ws.rs.core.CacheControl;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.Response.Status;

import org.apache.commons.lang.Validate;
import org.linagora.linshare.core.domain.objects.ChunkedFile;

public class FlowUploaderUtils {

    public static Response testChunk(long chunkNumber, long totalChunks, long chunkSize, long totalSize,
            String identifier, String filename, String relativePath,
            ConcurrentMap<String, ChunkedFile> chunkedFiles, boolean maintenance) {
        if (maintenance) {
            return buildReponse(Status.NO_CONTENT); // 204
            // https://github.com/flowjs/flow.js
            // If this request returns a 200, 201 or 202 HTTP code, the chunks is assumed to have been completed.
            // If request returns a permanent error status, upload is stopped.
            // If request returns anything else, the chunk will be uploaded in the standard fashion.
        }
        identifier = cleanIdentifier(identifier);
        boolean isValid = isValid(chunkNumber, chunkSize, totalSize, identifier, filename);
        // Throw HTTP 400 error code.
        Validate.isTrue(isValid);
        if (chunkedFiles.containsKey(identifier) && chunkedFiles.get(identifier).hasChunk(chunkNumber)) {
            // HTTP 200 : ok, we already get this chunk.
            return buildReponse(Status.ACCEPTED);
        }
        // HTTP 204 We did not have this chunk
        return buildReponse(Status.NO_CONTENT);
    }

    private static Response buildReponse(Status status) {
        ResponseBuilder builder = Response.status(status);
        // Fixing IE cache issue.
        CacheControl cc = new CacheControl();
        cc.setNoCache(true);
        builder.cacheControl(cc);
        return builder.build();
    }

    private static String cleanIdentifier(String identifier) {
        return identifier.replaceAll("[^0-9A-Za-z_-]", "");
    }

    public static boolean isValid(long chunkNumber, long chunkSize, long totalSize, String identifier,
            String filename) {
        // Check if the request is sane
        if (chunkNumber == 0 || chunkSize == 0 || totalSize == 0 || identifier.length() == 0
                || filename.length() == 0) {
            return false;
        }
        double numberOfChunks = computeNumberOfChunks(chunkSize, totalSize);
        if (chunkNumber > numberOfChunks) {
            return false;
        }
        return true;
    }

    private static double computeNumberOfChunks(long chunkSize, long totalSize) {
        return Math.max(Math.floor(totalSize / chunkSize), 1);
    }

    public static boolean isUploadFinished(String identifier, long chunkSize, long totalSize,
            ConcurrentMap<String, ChunkedFile> chunkedFiles) {
        double numberOfChunks = computeNumberOfChunks(chunkSize, totalSize);
        return chunkedFiles.get(identifier).getChunks().size() == numberOfChunks;
    }

    public static java.nio.file.Path getTempFile(String identifier, ConcurrentMap<String, ChunkedFile> chunkedFiles)
            throws IOException {
        ChunkedFile chunkedFile = chunkedFiles.get(identifier);
        if (chunkedFile == null) {
            java.nio.file.Path path = Files.createTempFile("ls-chunks-" + identifier, ".temp");
            chunkedFiles.putIfAbsent(identifier, new ChunkedFile(path));
            chunkedFile = chunkedFiles.get(identifier);
        }
        return chunkedFile.getPath();
    }
}