/* * (C) Copyright 2006-2007 Nuxeo SAS (http://nuxeo.com/) and contributors. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Lesser General Public License * (LGPL) version 2.1 which accompanies this distribution, and is available at * http://www.gnu.org/licenses/lgpl.html * * This library 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 * Lesser General Public License for more details. * * Contributors: * Nuxeo - initial API and implementation * * $Id$ */ package org.nuxeo.ecm.platform.ui.web.util.files; import java.io.File; import java.io.IOException; import java.io.InputStream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.nuxeo.ecm.core.api.Blob; import org.nuxeo.ecm.core.api.impl.blob.StreamingBlob; import org.nuxeo.ecm.platform.mimetype.MimetypeDetectionException; import org.nuxeo.ecm.platform.mimetype.interfaces.MimetypeRegistry; import org.nuxeo.runtime.api.Framework; import org.nuxeo.runtime.services.streaming.FileSource; public class FileUtils { private static final Log log = LogFactory.getLog(FileUtils.class); private FileUtils() { } /** * Creates a serializable blob from a stream, with filename and mimetype * detection. * <p> * Creates an in-memory blob if data is under 64K, otherwise constructs a * serializable FileBlob which stores data in a temporary file on the hard * disk. * * @param file the input stream holding data * @param filename the file name. Will be set on the blob and will used for * mimetype detection. * @param mimeType the detected mimetype at upload. Can be null. Will be * verified by the mimetype service. */ public static Blob createSerializableBlob(InputStream file, String filename, String mimeType) { Blob blob = null; try { // persisting the blob makes it possible to read the binary content // of the request stream several times (mimetype sniffing, digest // computation, core binary storage) blob = StreamingBlob.createFromStream(file, mimeType).persist(); // filename if (filename != null) { filename = getCleanFileName(filename); } blob.setFilename(filename); // mimetype detection MimetypeRegistry mimeService = Framework.getService(MimetypeRegistry.class); String detectedMimeType = mimeService.getMimetypeFromFilenameAndBlobWithDefault( filename, blob, null); if (detectedMimeType == null) { if (mimeType != null) { detectedMimeType = mimeType; } else { // default detectedMimeType = "application/octet-stream"; } } blob.setMimeType(detectedMimeType); } catch (MimetypeDetectionException e) { log.error(String.format("could not fetch mimetype for file %s", filename), e); } catch (IOException e) { log.error(e); } catch (Exception e) { log.error(e); } return blob; } /** * Returns a clean filename, stripping upload path on client side. * <p> * Fixes NXP-544 */ public static String getCleanFileName(String filename) { String res = null; int lastWinSeparator = filename.lastIndexOf('\\'); int lastUnixSeparator = filename.lastIndexOf('/'); int lastSeparator = Math.max(lastWinSeparator, lastUnixSeparator); if (lastSeparator != -1) { res = filename.substring(lastSeparator + 1, filename.length()); } else { res = filename; } return res; } /** * A Blob based on a File but whose contract says that the file is allowed * to be moved to another filesystem location if needed. * <p> * The move is done by getting the StreamSource from the Blob, casting to * FileSource. * * @since 5.7.2 */ public static class TemporaryFileBlob extends StreamingBlob { private static final long serialVersionUID = 1L; public TemporaryFileBlob(File file, String mimeType, String encoding, String filename, String digest) { super(new FileSource(file), mimeType, encoding, filename, digest); } @Override public boolean isTemporary() { return true; // for SQLSession#getBinary } @Override public FileSource getStreamSource() { return (FileSource) src; } } /** * Creates a TemporaryFileBlob. Similar to * FileUtils.createSerializableBlob. * * @since 5.7.2 */ public static Blob createTemporaryFileBlob(File file, String filename, String mimeType) { if (filename != null) { filename = FileUtils.getCleanFileName(filename); } Blob blob = new TemporaryFileBlob(file, mimeType, null, filename, null); return configureFileBlob(blob, filename, mimeType); } protected static Blob configureFileBlob(Blob blob, String filename, String mimeType) { try { // mimetype detection MimetypeRegistry mimeService = Framework.getLocalService(MimetypeRegistry.class); String detectedMimeType = mimeService.getMimetypeFromFilenameAndBlobWithDefault( filename, blob, null); if (detectedMimeType == null) { if (mimeType != null) { detectedMimeType = mimeType; } else { // default detectedMimeType = "application/octet-stream"; } } blob.setMimeType(detectedMimeType); } catch (MimetypeDetectionException e) { log.error(String.format("could not fetch mimetype for file %s", filename), e); } return blob; } }