The great big resource manager revamp: the resource manager now supports
the JNLP versioned resource protocol so that it can download jardiffs instead of whole new jar files when a resource bundle is updated. Unversioned http downloads (which we'll probably continue to use for the dynamically generated island bundles) are currently not working. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@2739 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
//
|
||||
// $Id: Downloader.java,v 1.1 2003/08/05 01:33:20 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 + "].");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
Reference in New Issue
Block a user