org.activityinfo.server.attachment.AppEngineAttachmentService.java Source code

Java tutorial

Introduction

Here is the source code for org.activityinfo.server.attachment.AppEngineAttachmentService.java

Source

package org.activityinfo.server.attachment;

/*
 * #%L
 * ActivityInfo Server
 * %%
 * Copyright (C) 2009 - 2013 UNICEF
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of the 
 * License, or (at your option) any later version.
 * 
 * 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 General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public 
 * License along with this program.  If not, see
 * <http://www.gnu.org/licenses/gpl-3.0.html>.
 * #L%
 */

import com.google.appengine.api.blobstore.BlobKey;
import com.google.appengine.api.blobstore.BlobstoreService;
import com.google.appengine.api.blobstore.BlobstoreServiceFactory;
import com.google.appengine.api.files.AppEngineFile;
import com.google.appengine.api.files.FileService;
import com.google.appengine.api.files.FileServiceFactory;
import com.google.appengine.api.files.FileWriteChannel;
import com.google.appengine.api.files.GSFileOptions.GSFileOptionsBuilder;
import com.google.common.io.ByteStreams;
import com.google.inject.Inject;
import org.activityinfo.server.util.blob.BlobService;
import org.activityinfo.service.DeploymentConfiguration;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.channels.Channels;
import java.nio.charset.Charset;

public class AppEngineAttachmentService implements AttachmentService {

    private BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();

    private final BlobService blobService;
    private final String attachmentRoot;

    @Inject
    public AppEngineAttachmentService(BlobService blobService, DeploymentConfiguration config) {
        this.blobService = blobService;
        this.attachmentRoot = config.getProperty("attachment.blob.root", "/gs/activityinfo-attachments");
    }

    @Override
    public void serveAttachment(String blobId, HttpServletResponse response) throws IOException {
        BlobKey blobKey = blobKey(blobId);
        blobstoreService.serve(blobKey, response);
    }

    private BlobKey blobKey(String blobId) {
        BlobKey blobKey = blobstoreService.createGsBlobKey("/gs/activityinfo-attachments/" + blobId);
        return blobKey;
    }

    @Override
    public void upload(String key, FileItem fileItem, InputStream uploadingStream) {
        try {

            GSFileOptionsBuilder builder = new GSFileOptionsBuilder().setBucket("activityinfo-attachments")
                    .setKey(key).setContentDisposition("attachment; filename=\"" + fileItem.getName() + "\"")
                    .setMimeType(fileItem.getContentType());

            FileService fileService = FileServiceFactory.getFileService();
            AppEngineFile writableFile = fileService.createNewGSFile(builder.build());
            boolean lock = true;
            FileWriteChannel writeChannel = fileService.openWriteChannel(writableFile, lock);
            OutputStream os = Channels.newOutputStream(writeChannel);
            ByteStreams.copy(fileItem.getInputStream(), os);
            os.flush();
            writeChannel.closeFinally();

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void delete(String key) {
        blobstoreService.delete(blobKey(key));
    }

    @Override
    public FileItemFactory createFileItemFactory() {
        return new FileItemFactory() {

            @Override
            public FileItem createItem(String fieldName, String contentType, boolean isFormField, String fileName) {
                return new InMemoryFileItem(fieldName, contentType, isFormField, fileName);
            }
        };
    }

    private static class InMemoryFileItem implements FileItem {

        private ByteArrayOutputStream baos = new ByteArrayOutputStream();
        private boolean formField;
        private String fieldName;
        private String contentType;
        private String fileName;

        public InMemoryFileItem(String fieldName, String contentType, boolean isFormField, String fileName) {
            this.fieldName = fieldName;
            this.contentType = contentType;
            this.formField = isFormField;
            this.fileName = fileName;
        }

        @Override
        public InputStream getInputStream() throws IOException {
            return new ByteArrayInputStream(baos.toByteArray());
        }

        @Override
        public String getContentType() {
            return contentType;
        }

        @Override
        public String getName() {
            return fileName;
        }

        @Override
        public boolean isInMemory() {
            return true;
        }

        @Override
        public long getSize() {
            return baos.size();
        }

        @Override
        public byte[] get() {
            return baos.toByteArray();
        }

        @Override
        public String getString(String encoding) throws UnsupportedEncodingException {
            return new String(baos.toByteArray(), Charset.forName(encoding));
        }

        @Override
        public String getString() {
            return new String(baos.toByteArray());
        }

        @Override
        public void write(File file) throws Exception {
            throw new UnsupportedOperationException();
        }

        @Override
        public void delete() {
            baos.reset();
        }

        @Override
        public String getFieldName() {
            return fieldName;
        }

        @Override
        public void setFieldName(String name) {
            this.fieldName = name;
        }

        @Override
        public boolean isFormField() {
            return formField;
        }

        @Override
        public void setFormField(boolean state) {
            this.formField = state;
        }

        @Override
        public OutputStream getOutputStream() throws IOException {
            return baos;
        }

    }
}