/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * 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. */ package com.liferay.portal.upload; import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayInputStream; import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayOutputStream; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.servlet.HttpHeaders; import com.liferay.portal.kernel.servlet.ServletInputStreamAdapter; import com.liferay.portal.kernel.util.FileUtil; import com.liferay.portal.kernel.util.GetterUtil; import com.liferay.portal.kernel.util.ProgressTracker; import com.liferay.portal.kernel.util.StringPool; import com.liferay.portal.servlet.filters.uploadservletrequest.UploadServletRequestFilter; import com.liferay.portal.util.PropsUtil; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; /** * @author Brian Myunghun Kim * @author Brian Wing Shun Chan * @author Harry Mark */ public class LiferayInputStream extends ServletInputStreamAdapter { public static final long THRESHOLD_SIZE = GetterUtil.getLong( PropsUtil.get(LiferayInputStream.class.getName() + ".threshold.size")); public LiferayInputStream(HttpServletRequest request) throws IOException { super(request.getInputStream()); _session = request.getSession(); long totalSize = request.getContentLength(); if (totalSize < 0) { totalSize = GetterUtil.getLong( request.getHeader(HttpHeaders.CONTENT_LENGTH), totalSize); } _totalSize = totalSize; boolean createTempFile = GetterUtil.getBoolean( request.getAttribute( UploadServletRequestFilter.COPY_MULTIPART_STREAM_TO_FILE), Boolean.TRUE); if ((_totalSize >= THRESHOLD_SIZE) && createTempFile) { _tempFile = FileUtil.createTempFile(); } else { _tempFile = null; request.removeAttribute( UploadServletRequestFilter.COPY_MULTIPART_STREAM_TO_FILE); } } public void cleanUp() { if (_tempFile != null) { if (_tempFileOutputStream != null) { try { _tempFileOutputStream.close(); } catch (IOException ioe) { if (_log.isWarnEnabled()) { _log.warn(ioe, ioe); } } } _tempFile.delete(); } } @Override public void close() throws IOException { super.close(); if (_tempFileOutputStream != null) { _tempFileOutputStream.close(); } } public ServletInputStream getCachedInputStream() throws IOException { if (_totalSize < THRESHOLD_SIZE) { return new ServletInputStreamAdapter( new UnsyncByteArrayInputStream( _cachedBytes.unsafeGetByteArray(), 0, _cachedBytes.size())); } else if (_tempFile != null) { return new ServletInputStreamAdapter( new FileInputStream(_tempFile)); } else { return this; } } @Override public int read(byte[] b, int off, int len) throws IOException { int bytesRead = super.read(b, off, len); if (bytesRead > 0) { _totalRead += bytesRead; } else { return bytesRead; } int percent = (int)((_totalRead * 100L) / _totalSize); if (_log.isDebugEnabled()) { _log.debug(bytesRead + "/" + _totalRead + "=" + percent); } if (_totalSize > 0) { if (_totalSize < THRESHOLD_SIZE) { _cachedBytes.write(b, off, bytesRead); } else { _writeToTempFile(b, off, bytesRead); } } ProgressTracker progressTracker = (ProgressTracker)_session.getAttribute(ProgressTracker.PERCENT); Integer curPercent = null; if (progressTracker != null) { curPercent = progressTracker.getPercent(); } if ((curPercent == null) || ((percent - curPercent.intValue()) >= 1)) { if (progressTracker == null) { progressTracker = new ProgressTracker(StringPool.BLANK); progressTracker.initialize(_session); } progressTracker.setPercent(percent); } return bytesRead; } private void _writeToTempFile(byte[] b, int off, int bytesRead) throws IOException { if ((_tempFile != null) && (bytesRead > 0)) { if (_tempFileOutputStream == null) { _tempFileOutputStream = new FileOutputStream(_tempFile, true); } _tempFileOutputStream.write(b, off, bytesRead); } } private static final Log _log = LogFactoryUtil.getLog( LiferayInputStream.class); private final UnsyncByteArrayOutputStream _cachedBytes = new UnsyncByteArrayOutputStream(); private final HttpSession _session; private final File _tempFile; private OutputStream _tempFileOutputStream; private long _totalRead; private final long _totalSize; }