uk.co.techblue.docusign.resteasy.providers.DocumentFileProvider.java Source code

Java tutorial

Introduction

Here is the source code for uk.co.techblue.docusign.resteasy.providers.DocumentFileProvider.java

Source

/*******************************************************************************
 * Copyright 2012 Technology Blueprint Ltd
 * 
 * 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 uk.co.techblue.docusign.resteasy.providers;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

import javax.mail.internet.ContentDisposition;
import javax.mail.internet.ParseException;
import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.Provider;

import org.apache.commons.lang3.StringUtils;
import org.apache.james.mime4j.field.FieldName;
import org.jboss.resteasy.logging.Logger;
import org.jboss.resteasy.plugins.providers.ProviderHelper;

import uk.co.techblue.docusign.client.dto.DocumentFile;

@Provider
@Produces("*/*")
@Consumes("*/*")
public class DocumentFileProvider implements MessageBodyReader<DocumentFile> {

    private static final String PREFIX = "pfx";

    private static final String SUFFIX = "sfx";

    private static final String PARAM_FILENAME = "filename";
    private static final String PARAM_DOCUMENT_ID = "documentId";

    private String downloadDirectory = null; // by default temp dir, consider allowing it to be defined at runtime

    private final static Logger logger = Logger.getLogger(DocumentFileProvider.class);

    public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        return DocumentFile.class == type;
    }

    public DocumentFile readFrom(Class<DocumentFile> type, Type genericType, Annotation[] annotations,
            MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
            throws IOException {
        File downloadedFile = null;
        String dispositionHeader = httpHeaders.getFirst(FieldName.CONTENT_DISPOSITION);
        ContentDisposition contentDisposition = null;
        try {
            contentDisposition = getContentDisposition(dispositionHeader);
        } catch (ParseException pe) {
            throw new IOException("Error occurred while parsing header. " + FieldName.CONTENT_DISPOSITION + " : "
                    + dispositionHeader, pe);
        }
        DocumentFile documentFile = new DocumentFile();
        String prefix = null;
        String suffix = null;
        if (contentDisposition != null) {
            setDocumentAttributes(contentDisposition, documentFile);
            suffix = getFileSuffix(contentDisposition, mediaType);
            prefix = getFilePrefix(contentDisposition);
        } else {
            logger.warn(
                    "Content Disposition header not found in response. All the attributes DocumentFile instance won't be populated.");
            suffix = getFileSuffix(mediaType);
        }
        if (StringUtils.isBlank(prefix)) {
            prefix = PREFIX;
        }
        if (StringUtils.isBlank(suffix)) {
            suffix = SUFFIX;
        }
        if (downloadDirectory != null) {
            try {
                downloadedFile = File.createTempFile(prefix, suffix, new File(downloadDirectory));
            } catch (final IOException ex) {
                // could make this configurable, so we fail on fault rather than
                // default.
                logger.error("Could not bind to specified download directory " + downloadDirectory
                        + " so will use temp dir.");
            }
        }

        if (downloadedFile == null)
            downloadedFile = File.createTempFile(prefix, suffix);

        OutputStream output = new BufferedOutputStream(new FileOutputStream(downloadedFile));

        try {
            ProviderHelper.writeTo(entityStream, output);
        } finally {
            output.close();
        }
        documentFile.setDocFile(downloadedFile);

        return documentFile;
    }

    private String getFilePrefix(ContentDisposition contentDisposition) {
        String fileName = contentDisposition.getParameter(PARAM_FILENAME);
        return StringUtils.substringBeforeLast(fileName, ".");
    }

    private void setDocumentAttributes(ContentDisposition contentDisposition, DocumentFile documentFile) {
        documentFile.setDocumentId(contentDisposition.getParameter(PARAM_DOCUMENT_ID));
        documentFile.setName(contentDisposition.getParameter(PARAM_FILENAME));
    }

    private String getFileSuffix(ContentDisposition contentDisposition, MediaType mediaType) {
        String fileName = contentDisposition.getParameter(PARAM_FILENAME);
        return getFileSuffix(mediaType, fileName);
    }

    private String getFileSuffix(MediaType mediaType) {
        return getFileSuffix(mediaType, null);
    }

    private String getFileSuffix(MediaType mediaType, String fileName) {
        String suffix = StringUtils.substringAfterLast(fileName, ".");
        String mediaSubtype = StringUtils.defaultString(mediaType.getSubtype());
        boolean suffixBlank = StringUtils.isBlank(suffix);
        boolean mediaSubtypeBlank = StringUtils.isBlank(mediaSubtype);
        if (!suffixBlank && mediaSubtype.equalsIgnoreCase(suffix)) {
            suffix = "." + suffix;
        } else if (!suffixBlank && mediaSubtypeBlank) {
            suffix = "." + suffix;
        } else if (suffixBlank && !mediaSubtypeBlank) {
            suffix = "." + mediaSubtype;
        } else if (!suffixBlank && !mediaSubtypeBlank) {
            suffix = "." + suffix + "." + mediaSubtype;
        } else {
            suffix = ".pdf";
        }
        return suffix;
    }

    private ContentDisposition getContentDisposition(String dispositionHeader) throws ParseException {
        if (StringUtils.isBlank(dispositionHeader)) {
            return null;
        }
        return new ContentDisposition(dispositionHeader);
    }

    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        return File.class.isAssignableFrom(type); // catch subtypes
    }

    public long getSize(File o, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        return o.length();
    }

    public void writeTo(File uploadFile, Class<?> type, Type genericType, Annotation[] annotations,
            MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream)
            throws IOException {
        InputStream inputStream = new BufferedInputStream(new FileInputStream(uploadFile));

        try {
            ProviderHelper.writeTo(inputStream, entityStream);
        } finally {
            inputStream.close();
        }
    }

}