diff --git a/src/java/com/threerings/resource/DownloadManager.java b/src/java/com/threerings/resource/DownloadManager.java
index 666496d9c..1924ee970 100644
--- a/src/java/com/threerings/resource/DownloadManager.java
+++ b/src/java/com/threerings/resource/DownloadManager.java
@@ -1,5 +1,5 @@
//
-// $Id: DownloadManager.java,v 1.13 2003/10/23 20:31:28 ray Exp $
+// $Id: DownloadManager.java,v 1.14 2003/10/29 22:31:55 mdb Exp $
package com.threerings.resource;
@@ -27,6 +27,9 @@ import com.samskivert.util.StringUtil;
*/
public class DownloadManager
{
+ /** Indicates whether or not we're using versioned resources. */
+ public static boolean VERSIONING = false;
+
/**
* Provides facilities for notifying an observer of file download
* progress.
@@ -384,8 +387,6 @@ public class DownloadManager
/** The data buffer size for reading file data. */
protected static final int BUFFER_SIZE = 2048;
- /** Indicates whether or not we're using versioned resources. */
- protected static boolean VERSIONING = false;
static {
try {
VERSIONING = "true".equalsIgnoreCase(
diff --git a/src/java/com/threerings/resource/JNLPDownloader.java b/src/java/com/threerings/resource/JNLPDownloader.java
index c028fa698..f39852cca 100644
--- a/src/java/com/threerings/resource/JNLPDownloader.java
+++ b/src/java/com/threerings/resource/JNLPDownloader.java
@@ -1,5 +1,5 @@
//
-// $Id: JNLPDownloader.java,v 1.9 2003/10/29 02:42:56 mdb Exp $
+// $Id: JNLPDownloader.java,v 1.10 2003/10/29 22:31:55 mdb Exp $
package com.threerings.resource;
@@ -40,12 +40,52 @@ public class JNLPDownloader extends Downloader
{
super.init(ddesc);
- // determine which version we already have, if any
+ String dpath = _desc.destFile.getPath();
+
+ // determine the path of our version file before we version the
+ // path of the destination file
_vfile = new File(FileUtil.resuffix(_desc.destFile, ".jar", ".vers"));
- if (_vfile.exists() && _desc.destFile.exists()) {
+
+ // if we're using a version, adjust our destination file path
+ // based on said version
+ if (!StringUtil.blank(_desc.version)) {
+ _desc.destFile = new File(
+ ResourceManager.versionPath(dpath, _desc.version, ".jar"));
+ }
+
+ // determine which version we already have, if any
+ if (_vfile.exists()) {
try {
BufferedReader vin = new BufferedReader(new FileReader(_vfile));
_cvers = vin.readLine();
+
+ // make sure the version referenced by that file still
+ // exists; if not ignore our "current version"
+ _curFile = new File(ResourceManager.versionPath(
+ dpath, _cvers, ".jar"));
+ if (!_curFile.exists()) {
+ // for backwards compatibility, check to see if we
+ // have an old non-versioned-path version of our
+ // existing version
+ File legacyFile = new File(dpath);
+ if (legacyFile.exists()) {
+ if (!legacyFile.renameTo(_curFile)) {
+ Log.warning("Failed to rename legacy bundle to " +
+ "versioned name [cur=" + _curFile +
+ ", leg=" + legacyFile + "].");
+ // just cope and we won't be able to blow away
+ // this version of the resources
+ _curFile = legacyFile;
+ } else {
+ Log.info("Renamed legacy bundle [cur=" + _curFile +
+ ", leg=" + legacyFile + "].");
+ }
+
+ } else {
+ _cvers = null;
+ }
+ }
+
} catch (IOException ioe) {
Log.warning("Error reading version file [path=" + _vfile +
", error=" + ioe + "].");
@@ -106,7 +146,7 @@ public class JNLPDownloader extends Downloader
if (ucon.getContentType().equals(JARDIFF_TYPE)) {
Log.info("Downloading patch [url=" + rsrcURL + "].");
_patchFile = new File(
- FileUtil.resuffix(_desc.destFile, ".jar", ".diff"));
+ FileUtil.resuffix(_curFile, ".jar", ".diff"));
downloadContent(dmgr, obs, pinfo, buffer, ucon, _patchFile);
} else {
@@ -121,25 +161,9 @@ public class JNLPDownloader extends Downloader
throws IOException
{
if (_patchFile != null) {
- // move the old jar out of the way
- File oldDest = new File(
- FileUtil.resuffix(_desc.destFile, ".jar", ".old"));
- if (!_desc.destFile.renameTo(oldDest)) {
- Log.warning("Unable to move " + _desc.destFile + " to " +
- oldDest + ". Trying another strategy.");
- oldDest = new File(_desc.destFile,
- RandomUtil.rand.nextLong() + ".jar");
- if (!_desc.destFile.renameTo(oldDest)) {
- Log.warning("Unable to move " + _desc.destFile + " to " +
- oldDest + ". Giving up and wiping.");
- // attempt to blow everything away before choking so that
- // next time we'll download afresh
- cleanUpAndFail(null);
- }
- }
-
// now apply the patch
- Log.info("Applying patch [old=" + oldDest + ", path=" + _patchFile +
+ Log.info("Applying patch [old=" + _curFile +
+ ", patch=" + _patchFile +
", new=" + _desc.destFile + "].");
Patcher.PatchDelegate delegate = new Patcher.PatchDelegate() {
public void patching (int value) {
@@ -153,7 +177,7 @@ public class JNLPDownloader extends Downloader
try {
out = new BufferedOutputStream(
new FileOutputStream(_desc.destFile));
- patcher.applyPatch(delegate, oldDest.getPath(),
+ patcher.applyPatch(delegate, _curFile.getPath(),
_patchFile.getPath(), out);
out.close();
@@ -161,13 +185,16 @@ public class JNLPDownloader extends Downloader
Log.warning("Failure applying patch [rfile=" + _desc.destFile +
", error=" + ioe + "]. Cleaning up and failing.");
StreamUtil.close(out);
- oldDest.delete();
cleanUpAndFail(ioe);
}
// clean up the old jar and the patch file
- oldDest.delete();
- _patchFile.delete();
+ if (!_curFile.delete()) {
+ Log.warning("Failed to delete old bundle " + _curFile + ".");
+ }
+ if (!_patchFile.delete()) {
+ Log.warning("Failed to delete patch file " + _curFile + ".");
+ }
}
PrintWriter pout = new PrintWriter(
@@ -210,7 +237,7 @@ public class JNLPDownloader extends Downloader
protected void cleanUpAndFail (IOException cause)
throws IOException
{
- if (!_desc.destFile.delete()) {
+ if (_curFile != null) {
Log.warning("Failed to delete " + _desc.destFile +
" in cleanUpAndFail().");
}
@@ -241,6 +268,9 @@ public class JNLPDownloader extends Downloader
/** The current version of the resource if we have one. */
protected String _cvers;
+ /** The existing version of our bundle file. */
+ protected File _curFile;
+
/** The mime-type of a jardiff patch file. */
protected static final String JARDIFF_TYPE =
"application/x-java-archive-diff";
diff --git a/src/java/com/threerings/resource/ResourceManager.java b/src/java/com/threerings/resource/ResourceManager.java
index 6890e07cc..3e6b36416 100644
--- a/src/java/com/threerings/resource/ResourceManager.java
+++ b/src/java/com/threerings/resource/ResourceManager.java
@@ -1,5 +1,5 @@
//
-// $Id: ResourceManager.java,v 1.37 2003/10/27 11:43:26 mdb Exp $
+// $Id: ResourceManager.java,v 1.38 2003/10/29 22:31:55 mdb Exp $
package com.threerings.resource;
@@ -661,8 +661,17 @@ public class ResourceManager
// make sure the cache directory exists for this set
createCacheDirectory(setName);
+ // compute the versioned path for this bundle if we have a
+ // version configured
+ String vpath = path;
+ if (DownloadManager.VERSIONING && !StringUtil.blank(_version)) {
+ vpath = versionPath(
+ path, _version, getSuffix(path, ".jar"));
+ }
+
// compute the path to the cache file for this bundle
File cfile = new File(genCachePath(setName, path));
+ File vfile = new File(genCachePath(setName, vpath));
// slap this on the list for retrieval or update by the
// download manager
@@ -670,7 +679,7 @@ public class ResourceManager
// finally, add the file that will be cached to the set as
// a resource bundle
- set.add(new ResourceBundle(cfile, true, true));
+ set.add(new ResourceBundle(vfile, true, true));
} catch (MalformedURLException mue) {
Log.warning("Unable to create URL for resource " +
@@ -850,6 +859,40 @@ public class ResourceManager
return (ResourceBundle[])_sets.get(name);
}
+ /**
+ * Creates a versioned path using the supplied version string, path
+ * and file suffix. For example foo/bar/baz.jar becomes
+ * foo/bar/baz__Vversion.jar.
+ */
+ public static String versionPath (
+ String path, String version, String suffix)
+ {
+ if (!suffix.startsWith(".")) {
+ suffix = "." + suffix;
+ }
+ int sidx = path.indexOf(suffix);
+ if (sidx == -1) {
+ Log.warning("Invalid unversioned path, missing suffix " +
+ "[path=" + path + ", suffix=" + suffix + "].");
+ return path;
+ }
+ return path.substring(0, sidx) + "__V" + version + suffix;
+ }
+
+ /**
+ * Returns the suffix of the specified path, ie. .jar if
+ * the path references a file that ends in .jar.
+ */
+ public static String getSuffix (String path, String defsuf)
+ {
+ int didx = path.lastIndexOf(".");
+ if (didx == -1) {
+ return defsuf;
+ } else {
+ return path.substring(didx);
+ }
+ }
+
/** The classloader we use for classpath-based resource loading. */
protected ClassLoader _loader;