org.chimi.s4s.fileservice.FileLockBasedThumbnailCreator.java Source code

Java tutorial

Introduction

Here is the source code for org.chimi.s4s.fileservice.FileLockBasedThumbnailCreator.java

Source

/*
 * Copyright 2002-2011 the original author or authors.
 *
 * 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 org.chimi.s4s.fileservice;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.channels.OverlappingFileLockException;
import java.util.Random;

import org.chimi.s4s.imageprocessor.ImageProcessor;
import org.chimi.s4s.storage.FileData;
import org.chimi.s4s.storage.FileId;
import org.chimi.s4s.util.Util;
import org.springframework.beans.factory.InitializingBean;

/**
 * ?? ??  ?? ? ?   ? ??  ?? ?
 * 
 *  ?  ImageProcessor? .
 * 
 * @author Choi Beom Kyun
 */
public class FileLockBasedThumbnailCreator implements ThumbnailCreator, InitializingBean {

    private ImageProcessor imageProcessor;
    private String tempStoragePath = Util.getS4STempDir();

    public void setImageProcessor(ImageProcessor imageProcessor) {
        this.imageProcessor = imageProcessor;
    }

    public void setTempStoragePath(String tempStoragePath) {
        this.tempStoragePath = tempStoragePath;
    }

    /**
     * tempStoragePath   ?.
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        File tempFolder = new File(tempStoragePath);
        tempFolder.mkdirs();
    }

    @Override
    public File create(FileData fileData, Size newSize) throws IOException {
        String thumbnailPath = getThumbnailPath(fileData.getFileId(), newSize);
        File thumbnailFile = new File(thumbnailPath);
        if (thumbnailFile.exists()) {
            // ? ?? 
            return thumbnailFile;
        }
        File lockFile = getLockFile(thumbnailPath);
        FileChannel channel = new RandomAccessFile(lockFile, "rw").getChannel();
        FileLock lock = null;
        try {
            lock = channel.tryLock();
        } catch (OverlappingFileLockException ex) {
        }

        if (lock == null) {
            // ??  , 1  ?? ?? ? ? 
            return createTemporaryThumbnail(thumbnailPath, fileData, newSize);
        }
        try {
            createThumbnail(thumbnailPath, fileData, newSize);
            return thumbnailFile;
        } finally {
            lock.release();
            channel.close();

            // TODO ? ?   
        }
    }

    private File getLockFile(String thumbnailPath) {
        return new File(thumbnailPath + ".lock");
    }

    private String getThumbnailPath(FileId fileId, Size size) {
        String filename = fileId.toString() + ".w" + size.getWidth() + "h" + size.getHeight() + ".jpg";
        return tempStoragePath + Util.getFileSeparator() + filename;
    }

    private File createThumbnail(String thumbnailPath, FileData fileData, Size newSize) throws IOException {
        File thumbnailFile = new File(thumbnailPath);
        if (thumbnailFile.exists()) {
            return thumbnailFile;
        }
        return imageProcessor.resize(fileData.getInputStream(), thumbnailFile, newSize);
    }

    private Random random = new Random();

    private File createTemporaryThumbnail(String thumbnailPath, FileData fileData, Size newSize)
            throws IOException {
        int tempId = random.nextInt(10000);
        String tempThumbnailPath = thumbnailPath + ".temp" + tempId + ".jpg";
        return imageProcessor.resize(fileData.getInputStream(), new File(tempThumbnailPath), newSize);
    }

}