/*
* This library is part of OpenCms -
* the Open Source Content Management System
*
* Copyright (c) Alkacon Software GmbH (http://www.alkacon.com)
*
* 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.
*
* For further information about Alkacon Software, please see the
* company website: http://www.alkacon.com
*
* For further information about OpenCms, please see the
* project website: http://www.opencms.org
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.opencms.ade.upload;
import org.opencms.ade.upload.shared.CmsUploadProgessInfo;
import org.opencms.ade.upload.shared.CmsUploadProgessInfo.UPLOAD_STATE;
import org.opencms.main.CmsLog;
import org.opencms.util.CmsUUID;
import java.io.Serializable;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.logging.Log;
/**
* Provides the upload listener for the upload widget.<p>
*
* @since 8.0.0
*/
public class CmsUploadListener implements ProgressListener, Serializable {
/** The log object for this class. */
private static final Log LOG = CmsLog.getLog(CmsUploadListener.class);
/** The serial version id. */
private static final long serialVersionUID = -6431275569719042836L;
/** The content length of the request (larger than the sum of file sizes). */
protected long m_contentLength;
/** Stores the exception if one has been occurred. */
protected RuntimeException m_exception;
/** Signals that there occurred an exception before. */
protected boolean m_exceptionTrhown;
/** The bytes read so far. */
private long m_bytesRead;
/** The upload delay. */
private int m_delay;
/** A flag that signals if the upload is finished. */
private boolean m_finished;
/** The UUID for this listener. */
private CmsUUID m_id;
/** Stores the current item. */
private int m_item;
/** The timeout watch dog for this listener. */
private CmsUploadTimeoutWatcher m_watcher;
/**
* The public constructor for the listener.<p>
*
* @param requestSize content length of the request (larger than the sum of file sizes)
*/
public CmsUploadListener(int requestSize) {
m_id = new CmsUUID();
m_contentLength = new Long(requestSize).longValue();
startWatcher();
}
/**
* Sets the exception that should cancel the upload on the next update.<p>
*
* @param e the exception
*/
public void cancelUpload(CmsUploadException e) {
m_exception = e;
}
/**
* Returns the bytes transfered so far.<p>
*
* @return the bytes transfered so far
*/
public long getBytesRead() {
return m_bytesRead;
}
/**
* Returns the content length of the request (larger than the sum of file sizes).<p>
*
* @return the content length of the request (larger than the sum of file sizes)
*/
public long getContentLength() {
return m_contentLength;
}
/**
* Returns the exception.<p>
*
* @return the exception
*/
public RuntimeException getException() {
return m_exception;
}
/**
* Returns the listeners UUID.<p>
*
* @return the listeners UUID
*/
public CmsUUID getId() {
return m_id;
}
/**
* Returns the current progress info of the upload.<p>
*
* @return the progress info
*/
public CmsUploadProgessInfo getInfo() {
if (m_finished) {
return new CmsUploadProgessInfo(
getItem(),
(int)getPercent(),
UPLOAD_STATE.finished,
getContentLength(),
getBytesRead());
}
return new CmsUploadProgessInfo(
getItem(),
(int)getPercent(),
UPLOAD_STATE.running,
getContentLength(),
getBytesRead());
}
/**
* Returns the number of the field, which is currently being read.<p>
* <ul>
* <li>0 = no item so far
* <li>1 = first item is being read, ...
* </ul>
* @return the number of the field, which is currently being read.
*/
public int getItem() {
return m_item;
}
/**
* Returns the percent done of the current upload.<p>
*
* @return the percent done of the current upload
*/
public long getPercent() {
return m_contentLength != 0 ? (m_bytesRead * 100) / m_contentLength : 0;
}
/**
* Returns <code>true</code> if the process has been canceled due to an error or by the user.<p>
*
* @return boolean<code>true</code> if the process has been canceled due to an error or by the user
*/
public boolean isCanceled() {
return m_exception != null;
}
/**
* Returns the finished.<p>
*
* @return the finished
*/
public boolean isFinished() {
return m_finished;
}
/**
* Sets the delay.<p>
*
* @param delay the delay to set
*/
public void setDelay(int delay) {
m_delay = delay;
}
/**
* Sets the finished.<p>
*
* @param finished the finished to set
*/
public void setFinished(boolean finished) {
m_finished = finished;
}
/**
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "UUID="
+ getId()
+ " total="
+ getContentLength()
+ " done="
+ getBytesRead()
+ " cancelled="
+ isCanceled();
}
/**
* Updates the listeners status information and does the following steps:
* <ul>
* <li> returns if there was already thrown an exception before
* <li> sets the local variables to the current upload state
* <li> throws an RuntimeException if it was set in the meanwhile (by another request e.g. user has canceled)
* <li> slows down the upload process if it's configured
* <li> stops the watcher if the upload has reached more than 100 percent
* </ul>
*
* @see org.apache.commons.fileupload.ProgressListener#update(long, long, int)
*/
public void update(long done, long total, int item) {
if (m_exceptionTrhown) {
return;
}
m_bytesRead = done;
m_contentLength = total;
m_item = item;
// If an other request has set an exception, it is thrown so the commons-fileupload's
// parser stops and the connection is closed.
if (isCanceled()) {
m_exceptionTrhown = true;
throw m_exception;
}
// Just a way to slow down the upload process and see the progress bar in fast networks.
if ((m_delay > 0) && (done < total)) {
try {
Thread.sleep(m_delay);
} catch (Exception e) {
m_exception = new RuntimeException(e);
}
}
if (getPercent() >= 100) {
stopWatcher();
}
}
/**
* Starts the watcher.<p>
*/
private void startWatcher() {
if (m_watcher == null) {
try {
m_watcher = new CmsUploadTimeoutWatcher(this);
m_watcher.start();
} catch (Exception e) {
LOG.info(Messages.get().getBundle().key(
Messages.LOG_UPLOAD_CREATE_WATCH_DOG_2,
getId(),
e.getMessage()));
}
}
}
/**
* Stops the watcher.<p>
*/
private void stopWatcher() {
if (m_watcher != null) {
m_watcher.cancel();
}
}
}