00b983ccf7
jar files when we're done patching. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@2741 542714f4-19e9-0310-aa3c-eee0fc999fb1
165 lines
5.8 KiB
Java
165 lines
5.8 KiB
Java
//
|
|
// $Id: Downloader.java,v 1.2 2003/08/05 07:03:34 mdb Exp $
|
|
|
|
package com.threerings.resource;
|
|
|
|
import java.io.File;
|
|
import java.io.FileOutputStream;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.net.URLConnection;
|
|
|
|
import com.threerings.resource.DownloadManager.DownloadDescriptor;
|
|
import com.threerings.resource.DownloadManager.DownloadObserver;
|
|
|
|
/**
|
|
* Does something extraordinary.
|
|
*/
|
|
public abstract class Downloader
|
|
{
|
|
/**
|
|
* Provides this downloader with a reference to the download
|
|
* descriptor it needs to do its business.
|
|
*/
|
|
public void init (DownloadDescriptor ddesc)
|
|
{
|
|
_desc = ddesc;
|
|
_desc.destFileSize = _desc.destFile.length();
|
|
_desc.destLastModified = _desc.destFile.lastModified();
|
|
}
|
|
|
|
/**
|
|
* Returns a reference to the descriptor we are downloading.
|
|
*/
|
|
public DownloadDescriptor getDescriptor ()
|
|
{
|
|
return _desc;
|
|
}
|
|
|
|
/**
|
|
* Requests that this downloader determine whether it needs to be
|
|
* updated and if so, it should add its total download requirement to
|
|
* {@link ProgressInfo#totalSize} the supplied {@link ProgressInfo}
|
|
* record.
|
|
*
|
|
* @return true if this downloader needs be updated, false if not.
|
|
*/
|
|
public abstract boolean checkUpdate (ProgressInfo info)
|
|
throws IOException;
|
|
|
|
/**
|
|
* Compares the supplied size and last modified time with the size and
|
|
* last modified time of our local copy of the file.
|
|
*/
|
|
protected boolean compareWithLocal (long fileSize, long lastModified)
|
|
{
|
|
// check to see whether we have a local copy at all, and if so,
|
|
// whether its file size or last-modified time differs from the
|
|
// source file modulo a delta to account for inexactness on the
|
|
// part of the file-system (thanks Microsoft)
|
|
return ((!_desc.destFile.exists()) ||
|
|
(_desc.destFileSize != fileSize) ||
|
|
(_desc.destLastModified < (lastModified - DELTA)) ||
|
|
(_desc.destLastModified > (lastModified + DELTA)));
|
|
}
|
|
|
|
/**
|
|
* Processes a single download descriptor.
|
|
*/
|
|
public void processDownload (DownloadManager dmgr, DownloadObserver obs,
|
|
ProgressInfo pinfo, byte[] buffer)
|
|
throws IOException
|
|
{
|
|
// download the resource bundle from the specified URL
|
|
URLConnection ucon = _desc.sourceURL.openConnection();
|
|
|
|
// prepare to read the data from the URL into the cache file
|
|
Log.info("Downloading file [url=" + _desc.sourceURL + "].");
|
|
downloadContent(dmgr, obs, pinfo, buffer, ucon, _desc.destFile);
|
|
|
|
// if we have a last modified time, we want to adjust our cache
|
|
// file accordingly
|
|
if (_desc.lastModified != 0) {
|
|
if (!_desc.destFile.setLastModified(_desc.lastModified)) {
|
|
Log.warning("Failed to set last-modified date " +
|
|
"[file=" + _desc.destFile + "].");
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Called after the download phase has completed to allow patching or
|
|
* other post-download activities.
|
|
*/
|
|
public void postDownload (DownloadManager dmgr, DownloadObserver obs,
|
|
ProgressInfo pinfo)
|
|
throws IOException
|
|
{
|
|
// nothing to do by default
|
|
}
|
|
|
|
/**
|
|
* Downloads the content from the supplied URL connection into the
|
|
* specified destination file, informing the supplied download manager
|
|
* and observer of our progress along the way.
|
|
*/
|
|
protected void downloadContent (DownloadManager dmgr, DownloadObserver obs,
|
|
ProgressInfo pinfo, byte[] buffer,
|
|
URLConnection ucon, File destFile)
|
|
throws IOException
|
|
{
|
|
InputStream in = ucon.getInputStream();
|
|
FileOutputStream out = new FileOutputStream(destFile);
|
|
int read;
|
|
|
|
// read in the file data
|
|
while ((read = in.read(buffer)) != -1) {
|
|
// write it out to our local copy
|
|
out.write(buffer, 0, read);
|
|
|
|
// report our progress to the download observer as a
|
|
// percentage of the total file data to be transferred
|
|
pinfo.currentSize += read;
|
|
|
|
// update our percent completion; if we're totally done, hold
|
|
// off on notifying the observer until the download manager
|
|
// finishes fiddling to ensure that any action the observer
|
|
// may take on the downloaded files can be safely undertaken
|
|
int pctdone = pinfo.getPercentDone();
|
|
pinfo.complete = (pctdone >= 100);
|
|
if (pinfo.complete) {
|
|
continue;
|
|
}
|
|
|
|
// update the transfer rate to reflect the bit of data we just
|
|
// transferred
|
|
long now = System.currentTimeMillis();
|
|
pinfo.updateXferRate(now);
|
|
|
|
// notify the progress observer if it's been sufficiently long
|
|
// since our last notification
|
|
if ((now - pinfo.lastUpdate) >= UPDATE_DELAY) {
|
|
pinfo.lastUpdate = now;
|
|
long remaining = pinfo.getXferTimeRemaining();
|
|
dmgr.notifyProgress(obs, pctdone, remaining);
|
|
}
|
|
}
|
|
|
|
// close the streams
|
|
in.close();
|
|
out.close();
|
|
}
|
|
|
|
/** The descriptor that we're downloading. */
|
|
protected DownloadDescriptor _desc;
|
|
|
|
/** The last-modified difference in milliseconds allowed between the
|
|
* source and destination file without considering the destination
|
|
* file to be out of date. */
|
|
protected static final long DELTA = 5000L;
|
|
|
|
/** The delay in milliseconds between notifying progress observers of
|
|
* file download progress. */
|
|
protected static final long UPDATE_DELAY = 2500L;
|
|
}
|