New and improved Getdown! Now with better status and error reporting.
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: Application.java,v 1.12 2004/07/14 13:44:49 mdb Exp $
|
// $Id: Application.java,v 1.13 2004/07/19 11:59:06 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.getdown.data;
|
package com.threerings.getdown.data;
|
||||||
|
|
||||||
@@ -64,6 +64,14 @@ public class Application
|
|||||||
public String background;
|
public String background;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Used by {@link #verifyMetadata} to communicate status in
|
||||||
|
* circumstances where it needs to take network actions. */
|
||||||
|
public static interface StatusDisplay
|
||||||
|
{
|
||||||
|
/** Requests that the specified status message be displayed. */
|
||||||
|
public void updateStatus (String message);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an application instance which records the location of the
|
* Creates an application instance which records the location of the
|
||||||
* <code>getdown.txt</code> configuration file from the supplied
|
* <code>getdown.txt</code> configuration file from the supplied
|
||||||
@@ -386,7 +394,7 @@ public class Application
|
|||||||
* @exception IOException thrown if we encounter an unrecoverable
|
* @exception IOException thrown if we encounter an unrecoverable
|
||||||
* error while verifying the metadata.
|
* error while verifying the metadata.
|
||||||
*/
|
*/
|
||||||
public boolean verifyMetadata ()
|
public boolean verifyMetadata (StatusDisplay status)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
Log.info("Verifying application: " + _vappbase);
|
Log.info("Verifying application: " + _vappbase);
|
||||||
@@ -413,18 +421,25 @@ public class Application
|
|||||||
// to revalidate all of our resources as one or more of them
|
// to revalidate all of our resources as one or more of them
|
||||||
// have also changed
|
// have also changed
|
||||||
String olddig = (_digest == null) ? "" : _digest.getMetaDigest();
|
String olddig = (_digest == null) ? "" : _digest.getMetaDigest();
|
||||||
downloadControlFile(Digest.DIGEST_FILE);
|
try {
|
||||||
_digest = new Digest(_appdir);
|
downloadControlFile(Digest.DIGEST_FILE);
|
||||||
if (!olddig.equals(_digest.getMetaDigest())) {
|
_digest = new Digest(_appdir);
|
||||||
Log.info("Unversioned digest changed. Revalidating...");
|
if (!olddig.equals(_digest.getMetaDigest())) {
|
||||||
clearValidationMarkers();
|
Log.info("Unversioned digest changed. Revalidating...");
|
||||||
|
clearValidationMarkers();
|
||||||
|
}
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
Log.warning("Failed to refresh non-versioned digest: " +
|
||||||
|
ioe.getMessage() + ". Proceeding...");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else if (_digest == null) {
|
// regardless of whether we're versioned, if we failed to read the
|
||||||
// if we failed to load the digest, try to redownload the
|
// digest from disk, try to redownload the digest file and give it
|
||||||
// digest file and give it another good college try; this time
|
// another good college try; this time we allow exceptions to
|
||||||
// we allow exceptions to propagate up to the caller as there
|
// propagate up to the caller as there is nothing else we can do
|
||||||
// is nothing else we can do to recover
|
if (_digest == null) {
|
||||||
|
status.updateStatus("m.updating_metadata");
|
||||||
downloadControlFile(Digest.DIGEST_FILE);
|
downloadControlFile(Digest.DIGEST_FILE);
|
||||||
_digest = new Digest(_appdir);
|
_digest = new Digest(_appdir);
|
||||||
}
|
}
|
||||||
@@ -432,6 +447,7 @@ public class Application
|
|||||||
// now verify the contents of our main config file
|
// now verify the contents of our main config file
|
||||||
Resource crsrc = getConfigResource();
|
Resource crsrc = getConfigResource();
|
||||||
if (!_digest.validateResource(crsrc, null)) {
|
if (!_digest.validateResource(crsrc, null)) {
|
||||||
|
status.updateStatus("m.updating_metadata");
|
||||||
// attempt to redownload the file; again we pass errors up to
|
// attempt to redownload the file; again we pass errors up to
|
||||||
// our caller because we have no recourse to recovery
|
// our caller because we have no recourse to recovery
|
||||||
downloadControlFile(CONFIG_FILE);
|
downloadControlFile(CONFIG_FILE);
|
||||||
@@ -462,8 +478,6 @@ public class Application
|
|||||||
StreamUtil.close(fin);
|
StreamUtil.close(fin);
|
||||||
}
|
}
|
||||||
|
|
||||||
// next parse any custom user interface information
|
|
||||||
|
|
||||||
// finally let the caller know if we need an update
|
// finally let the caller know if we need an update
|
||||||
return _version != _targetVersion;
|
return _version != _targetVersion;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: Getdown.java,v 1.11 2004/07/14 14:04:44 mdb Exp $
|
// $Id: Getdown.java,v 1.12 2004/07/19 11:59:06 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.getdown.launcher;
|
package com.threerings.getdown.launcher;
|
||||||
|
|
||||||
@@ -24,6 +24,7 @@ import java.util.ResourceBundle;
|
|||||||
// import org.apache.commons.io.TeeOutputStream;
|
// import org.apache.commons.io.TeeOutputStream;
|
||||||
|
|
||||||
import com.samskivert.swing.util.SwingUtil;
|
import com.samskivert.swing.util.SwingUtil;
|
||||||
|
import com.samskivert.text.MessageUtil;
|
||||||
import com.samskivert.util.StringUtil;
|
import com.samskivert.util.StringUtil;
|
||||||
|
|
||||||
import com.threerings.getdown.Log;
|
import com.threerings.getdown.Log;
|
||||||
@@ -37,6 +38,7 @@ import com.threerings.getdown.util.ProgressObserver;
|
|||||||
* deployment system.
|
* deployment system.
|
||||||
*/
|
*/
|
||||||
public class Getdown extends Thread
|
public class Getdown extends Thread
|
||||||
|
implements Application.StatusDisplay
|
||||||
{
|
{
|
||||||
public Getdown (File appDir)
|
public Getdown (File appDir)
|
||||||
{
|
{
|
||||||
@@ -53,6 +55,7 @@ public class Getdown extends Thread
|
|||||||
_ifc = _app.init();
|
_ifc = _app.init();
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
Log.warning("Failed to parse 'getdown.txt': " + ioe);
|
Log.warning("Failed to parse 'getdown.txt': " + ioe);
|
||||||
|
updateStatus("m.init_failed");
|
||||||
_app.attemptRecovery();
|
_app.attemptRecovery();
|
||||||
_ifc = _app.init();
|
_ifc = _app.init();
|
||||||
}
|
}
|
||||||
@@ -60,8 +63,8 @@ public class Getdown extends Thread
|
|||||||
for (int ii = 0; ii < MAX_LOOPS; ii++) {
|
for (int ii = 0; ii < MAX_LOOPS; ii++) {
|
||||||
// make sure we have the desired version and that the
|
// make sure we have the desired version and that the
|
||||||
// metadata files are valid...
|
// metadata files are valid...
|
||||||
setStatus("m.validating", -1, -1L);
|
setStatus("m.validating", -1, -1L, false);
|
||||||
if (_app.verifyMetadata()) {
|
if (_app.verifyMetadata(this)) {
|
||||||
Log.info("Application requires update.");
|
Log.info("Application requires update.");
|
||||||
update();
|
update();
|
||||||
// loop back again and reverify the metadata
|
// loop back again and reverify the metadata
|
||||||
@@ -69,6 +72,7 @@ public class Getdown extends Thread
|
|||||||
}
|
}
|
||||||
|
|
||||||
// now verify our resources...
|
// now verify our resources...
|
||||||
|
setStatus("m.validating", -1, -1L, false);
|
||||||
List failures = _app.verifyResources(_progobs);
|
List failures = _app.verifyResources(_progobs);
|
||||||
if (failures == null) {
|
if (failures == null) {
|
||||||
Log.info("Resources verified.");
|
Log.info("Resources verified.");
|
||||||
@@ -83,14 +87,26 @@ public class Getdown extends Thread
|
|||||||
}
|
}
|
||||||
|
|
||||||
Log.warning("Pants! We couldn't get the job done.");
|
Log.warning("Pants! We couldn't get the job done.");
|
||||||
// TODO: throw exception
|
throw new IOException("m.unable_to_repair");
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.logStackTrace(e);
|
Log.logStackTrace(e);
|
||||||
// TODO: display error to user
|
String msg = e.getMessage();
|
||||||
|
if (msg == null) {
|
||||||
|
msg = "m.unknown_error";
|
||||||
|
} else if (!msg.startsWith("m.")) {
|
||||||
|
msg = MessageUtil.tcompose("m.init_error", msg);
|
||||||
|
}
|
||||||
|
updateStatus(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// documentation inherited from interface
|
||||||
|
public void updateStatus (String message)
|
||||||
|
{
|
||||||
|
setStatus(message, -1, -1L, true);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called if the application is determined to be of an old version.
|
* Called if the application is determined to be of an old version.
|
||||||
*/
|
*/
|
||||||
@@ -109,7 +125,7 @@ public class Getdown extends Thread
|
|||||||
download(list);
|
download(list);
|
||||||
|
|
||||||
// and apply it...
|
// and apply it...
|
||||||
setStatus("m.patching", -1, -1L);
|
updateStatus("m.patching");
|
||||||
Patcher patcher = new Patcher();
|
Patcher patcher = new Patcher();
|
||||||
patcher.patch(patch.getLocal().getParentFile(),
|
patcher.patch(patch.getLocal().getParentFile(),
|
||||||
patch.getLocal(), _progobs);
|
patch.getLocal(), _progobs);
|
||||||
@@ -143,11 +159,11 @@ public class Getdown extends Thread
|
|||||||
// create a downloader to download our resources
|
// create a downloader to download our resources
|
||||||
Downloader.Observer obs = new Downloader.Observer() {
|
Downloader.Observer obs = new Downloader.Observer() {
|
||||||
public void resolvingDownloads () {
|
public void resolvingDownloads () {
|
||||||
setStatus("m.resolving", -1, -1L);
|
updateStatus("m.resolving");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void downloadProgress (int percent, long remaining) {
|
public void downloadProgress (int percent, long remaining) {
|
||||||
setStatus("m.downloading", percent, remaining);
|
setStatus("m.downloading", percent, remaining, true);
|
||||||
if (percent == 100) {
|
if (percent == 100) {
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
lock.notify();
|
lock.notify();
|
||||||
@@ -159,7 +175,7 @@ public class Getdown extends Thread
|
|||||||
String msg = MessageFormat.format(
|
String msg = MessageFormat.format(
|
||||||
_msgs.getString("m.failure"),
|
_msgs.getString("m.failure"),
|
||||||
new Object[] { e.getMessage() });
|
new Object[] { e.getMessage() });
|
||||||
setStatus(msg, -1, -1L);
|
updateStatus(msg);
|
||||||
Log.warning("Download failed [rsrc=" + rsrc + "].");
|
Log.warning("Download failed [rsrc=" + rsrc + "].");
|
||||||
Log.logStackTrace(e);
|
Log.logStackTrace(e);
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
@@ -186,7 +202,7 @@ public class Getdown extends Thread
|
|||||||
*/
|
*/
|
||||||
protected void launch ()
|
protected void launch ()
|
||||||
{
|
{
|
||||||
setStatus("m.launching", 100, -1L);
|
setStatus("m.launching", 100, -1L, false);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Process proc = _app.createProcess();
|
Process proc = _app.createProcess();
|
||||||
@@ -235,8 +251,12 @@ public class Getdown extends Thread
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void setStatus (final String message, final int percent,
|
protected void setStatus (final String message, final int percent,
|
||||||
final long remaining)
|
final long remaining, boolean createUI)
|
||||||
{
|
{
|
||||||
|
if (_status == null && createUI) {
|
||||||
|
createInterface();
|
||||||
|
}
|
||||||
|
|
||||||
if (_status != null) {
|
if (_status != null) {
|
||||||
EventQueue.invokeLater(new Runnable() {
|
EventQueue.invokeLater(new Runnable() {
|
||||||
public void run () {
|
public void run () {
|
||||||
@@ -294,7 +314,7 @@ public class Getdown extends Thread
|
|||||||
/** Used to pass progress on to our user interface. */
|
/** Used to pass progress on to our user interface. */
|
||||||
protected ProgressObserver _progobs = new ProgressObserver() {
|
protected ProgressObserver _progobs = new ProgressObserver() {
|
||||||
public void progress (final int percent) {
|
public void progress (final int percent) {
|
||||||
setStatus(null, percent, -1L);
|
setStatus(null, percent, -1L, false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# $Id: messages.properties,v 1.2 2004/07/14 13:44:49 mdb Exp $
|
# $Id: messages.properties,v 1.3 2004/07/19 11:59:06 mdb Exp $
|
||||||
#
|
#
|
||||||
# Getdown translation messages
|
# Getdown translation messages
|
||||||
|
|
||||||
@@ -13,3 +13,27 @@ m.launching = Launching...
|
|||||||
|
|
||||||
m.complete = {0}% complete
|
m.complete = {0}% complete
|
||||||
m.complete_remain = {0}% complete {1}s remaining
|
m.complete_remain = {0}% complete {1}s remaining
|
||||||
|
|
||||||
|
m.updating_metadata = Downloading control files...
|
||||||
|
|
||||||
|
m.init_failed = Our configuration file is missing or corrupt. Attempting \
|
||||||
|
to download a new copy...
|
||||||
|
|
||||||
|
m.unable_to_repair = We were unable to download the necessary files after \
|
||||||
|
five attempts. You can try running the application again, but if it \
|
||||||
|
fails you may need to uninstall and reinstall.
|
||||||
|
|
||||||
|
m.unknown_error = The application has failed to launch due to some strange \
|
||||||
|
error from which we could not recover. Please visit the support section \
|
||||||
|
of the website for information on how to recover.
|
||||||
|
m.init_error = The application as failed to launch due to the following \
|
||||||
|
error:\n{0}\n\nPlease visit the support section of the website for \
|
||||||
|
information on how to handle such problems.
|
||||||
|
|
||||||
|
# application/digest errors
|
||||||
|
m.missing_appbase = The configuration file is missing the 'appbase'.
|
||||||
|
m.invalid_version = The configuration file specifies an invalid version.
|
||||||
|
m.invalid_appbase = The configuration file specifies an invalid 'appbase'.
|
||||||
|
m.missing_class = The configuration file is missing the application class.
|
||||||
|
m.missing_code = The configuration file specifies no code resources.
|
||||||
|
m.invalid_digest_file = The digest file is invalid.
|
||||||
|
|||||||
Reference in New Issue
Block a user