io.personium.core.model.file.StreamingOutputForDavFile.java Source code

Java tutorial

Introduction

Here is the source code for io.personium.core.model.file.StreamingOutputForDavFile.java

Source

/**
 * personium.io
 * Copyright 2014 FUJITSU LIMITED
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.personium.core.model.file;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.StreamingOutput;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.personium.core.PersoniumUnitConfig;

/**
 * Dav? Response????? StreamingOutput. ????????????
 */
public class StreamingOutputForDavFile implements StreamingOutput {

    private static Logger logger = LoggerFactory.getLogger(StreamingOutputForDavFile.class);

    /**
     * Dav???????/???.
     */
    private static int maxRetryCount = PersoniumUnitConfig.getDavFileOperationRetryCount();

    /**
     * Dav???????/???(msec).
     */
    private static long retryInterval = PersoniumUnitConfig.getDavFileOperationRetryInterval();

    /**
     * ?????.
     */
    Path hardLinkPath = null;

    /**
     * ??????.
     */
    InputStream hardLinkInput = null;

    /**
     * Constructor.
     * @param fileFullPath Full path of the file to be read
     * @param cellId Cell ID
     * @param encryptionType encryption type
     * @throws BinaryDataNotFoundException Error when file does not exist.
     */
    public StreamingOutputForDavFile(String fileFullPath, String cellId, String encryptionType)
            throws BinaryDataNotFoundException {
        if (!Files.exists(Paths.get(fileFullPath))) {
            throw new BinaryDataNotFoundException(fileFullPath);
        }

        // ????????????
        String hardLinkName = UniqueNameComposer.compose(fileFullPath);

        for (int i = 0; i < maxRetryCount; i++) {
            try {
                synchronized (fileFullPath) {
                    // ??.
                    hardLinkPath = Files.createLink(Paths.get(hardLinkName), Paths.get(fileFullPath));
                }
                // ????
                InputStream inputStream;
                if (DataCryptor.ENCRYPTION_TYPE_AES.equals(encryptionType)) {
                    // Perform decryption.
                    DataCryptor cryptor = new DataCryptor(cellId);
                    inputStream = cryptor.decode(new FileInputStream(hardLinkPath.toFile()));
                } else {
                    inputStream = new FileInputStream(hardLinkPath.toFile());
                }
                hardLinkInput = new BufferedInputStream(inputStream);
                // ???
                return;
            } catch (IOException e) {
                // ????
                logger.debug(String.format("Creating hard link %s failed. Will try again.", hardLinkName));
                try {
                    Thread.sleep(retryInterval);
                } catch (InterruptedException e1) {
                    logger.debug("Thread interrupted.");
                }
            }
        }

        throw new BinaryDataNotFoundException("Unable to create hard link for DAV file: " + hardLinkName);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void write(OutputStream output) throws IOException, WebApplicationException {
        if (null == hardLinkInput) {
            throw new WebApplicationException(new BinaryDataNotFoundException(hardLinkPath.toString()));
        }
        try {
            IOUtils.copy(hardLinkInput, output);
        } finally {
            IOUtils.closeQuietly(hardLinkInput);
            // ?????
            Files.delete(hardLinkPath);
        }
    }

}