001/*
002 * (C) Copyright 2006-2008 Nuxeo SAS (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     bstefanescu
016 *
017 * $Id$
018 */
019
020package org.nuxeo.ecm.webengine.model.io;
021
022import java.io.File;
023import java.io.FileInputStream;
024import java.io.IOException;
025import java.io.OutputStream;
026import java.lang.annotation.Annotation;
027import java.lang.reflect.Type;
028
029import javax.ws.rs.Produces;
030import javax.ws.rs.core.MediaType;
031import javax.ws.rs.core.MultivaluedMap;
032import javax.ws.rs.ext.MessageBodyWriter;
033import javax.ws.rs.ext.Provider;
034
035import org.apache.commons.logging.Log;
036import org.apache.commons.logging.LogFactory;
037import org.nuxeo.common.utils.FileUtils;
038import org.nuxeo.ecm.core.io.download.DownloadHelper;
039import org.nuxeo.ecm.webengine.WebException;
040
041/**
042 * text/plain is needed otherwise resteasy will use its default text plain (@see DefaultTextPlain) writer to write
043 * text/plain objects and the file is not written correctly.
044 *
045 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
046 */
047@Provider
048@Produces({ "*/*", "text/plain" })
049public class FileWriter implements MessageBodyWriter<File> {
050
051    private static final Log log = LogFactory.getLog(FileWriter.class);
052
053    public void writeTo(File t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType,
054            MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException {
055        FileInputStream in = null;
056        try {
057            in = new FileInputStream(t);
058            FileUtils.copy(in, entityStream);
059            entityStream.flush();
060        } catch (RuntimeException | IOException e) {
061            if (DownloadHelper.isClientAbortError(e)) {
062                DownloadHelper.logClientAbort(e);
063            } else {
064                throw WebException.wrap("Failed to render resource", e);
065            }
066        } finally {
067            if (in != null) {
068                in.close();
069            }
070        }
071    }
072
073    public long getSize(File arg0, Class<?> arg1, Type arg2, Annotation[] arg3, MediaType arg4) {
074        long n = arg0.length();
075        return n <= 0 ? -1 : n;
076    }
077
078    public boolean isWriteable(Class<?> arg0, Type type, Annotation[] arg2, MediaType arg3) {
079        return File.class.isAssignableFrom(arg0);
080    }
081
082}