package ecologylab.concurrent;
import java.io.IOException;
import ecologylab.generic.Continuation;
import ecologylab.generic.Debug;
/**
* Closure that keeps state about a download, as it progresses.
*/
public class DownloadState<T extends Downloadable>
extends Debug
{
T downloadable;
private Continuation<T> continuation;
private DownloadMonitor downloadMonitor;
private Thread downloadingThread;
private boolean continued;
private boolean recycled;
DownloadState(T downloadable, Continuation<T> dispatchTarget,DownloadMonitor downloadMonitor)
{
this.downloadable = downloadable;
this.continuation = dispatchTarget;
this.downloadMonitor = downloadMonitor;
}
boolean shouldCancel()
{
boolean result = downloadable.isRecycled();
if (!result)
{
BasicSite site = downloadable.getDownloadSite();
if (site != null)
result = site.isDown();
}
return result;
}
/**
* Do the work to download this.
* @throws IOException
*
* @throws Exception
*/
void performDownload() throws IOException
{
downloadingThread = Thread.currentThread();
//TODO need a lock here to prevent recycle() while downloading!!!!!!
if (downloadable != null && !downloadable.isRecycled())
{
//Update site statistics if available
BasicSite site = downloadable.getDownloadSite();
if(site != null)
site.beginActualDownload();
downloadable.performDownload();
if(site != null)
site.countNormalDownload();
//ajit-added below condition for documents in local repository
//download monitor can't do it after return from here
if(site != null && downloadable.getDownloadLocation().isFile())
site.endDownload();
}
}
protected synchronized void callContinuation()
{
if (!continued && !recycled)
{
// debug("dispatch()"+" "+downloadable+" -> "+dispatchTarget);
continued = true;
downloadMonitor.dispatched++;
if (continuation != null)
continuation.callback(downloadable);
}
}
@Override
public String toString()
{
String downloadableString = downloadable == null ? "recycled" : downloadable.toString();
return super.toString() + "["+downloadableString +" "+
downloadingThread + "]";
}
public void recycle(boolean recycleDownloadable)
{
if (!recycled)
{
recycled = true;
if (recycleDownloadable)
downloadable.recycle();
downloadable = null;
continuation = null;
downloadMonitor = null;
downloadingThread = null;
}
}
}