Added support for requesting external tracking URLs during the download

process. This will replace the flaky Applet -> JavaScript bridge but first
needs some testing.
This commit is contained in:
Michael Bayne
2007-03-14 02:05:22 +00:00
parent e5f8d8478a
commit 7e61bbdf90
2 changed files with 128 additions and 4 deletions
@@ -54,6 +54,7 @@ import java.util.regex.Pattern;
import com.samskivert.io.StreamUtil;
import com.samskivert.text.MessageUtil;
import com.samskivert.util.ArrayIntSet;
import com.samskivert.util.RunAnywhere;
import com.samskivert.util.StringUtil;
@@ -320,6 +321,36 @@ public class Application
}
}
/**
* Returns the URL to use to report an initial download event. Returns null if no tracking
* start URL was configured for this application.
*
* @param event the event to be reported: start, jvm_start, jvm_complete, complete.
*/
public URL getTrackingURL (String event)
{
try {
return _trackingURL == null ? null : new URL(_trackingURL + event);
} catch (MalformedURLException mue) {
Log.warning("Invalid tracking URL [path=" + _trackingURL + ", event=" + event +
", error=" + mue + "].");
return null;
}
}
/**
* Returns the URL to request to report that we have reached the specified percentage of our
* initial download. Returns null if no tracking request was configured for the specified
* percentage.
*/
public URL getTrackingProgressURL (int percent)
{
if (_trackingPcts == null || !_trackingPcts.contains(percent)) {
return null;
}
return getTrackingURL("pct" + percent);
}
/**
* Instructs the application to parse its <code>getdown.txt</code> configuration and prepare
* itself for operation. The application base URL will be parsed first so that if there are
@@ -410,6 +441,17 @@ public class Application
_javaLocation = (String)javaloc;
}
// determine whether we have any tracking configuration
_trackingURL = (String)cdata.get("tracking_url");
// check for tracking progress percent configuration
String trackPcts = (String)cdata.get("tracking_percents");
if (!StringUtil.isBlank(trackPcts)) {
_trackingPcts = new ArrayIntSet(StringUtil.parseIntArray(trackPcts));
} else if (!StringUtil.isBlank(_trackingURL)) {
_trackingPcts = new ArrayIntSet(new int[] { 50 });
}
// clear our arrays as we may be reinitializing
_codes.clear();
_resources.clear();
@@ -1039,6 +1081,9 @@ public class Application
protected boolean _windebug;
protected boolean _useTorrent = false;
protected String _trackingURL;
protected ArrayIntSet _trackingPcts;
protected int _javaVersion;
protected String _javaLocation;
@@ -347,7 +347,12 @@ public abstract class Getdown extends Thread
// download and install the necessary version of java, then loop back again and
// reverify everything; if we can't download java; we'll throw an exception
Log.info("Attempting to update Java VM...");
updateJava();
_enableTracking = true; // always track JVM downloads
try {
updateJava();
} finally {
_enableTracking = false;
}
continue;
}
@@ -369,9 +374,20 @@ public abstract class Getdown extends Thread
return;
}
// redownload any that are corrupt or invalid...
Log.info(failures.size() + " rsrcs require update.");
download(failures);
try {
int rcount = _app.getAllResources().size();
_enableTracking = (failures.size() == rcount);
reportTrackingEvent("app_start", -1);
// redownload any that are corrupt or invalid...
Log.info(failures.size() + " of " + rcount + " rsrcs require update.");
download(failures);
reportTrackingEvent("app_complete", -1);
} finally {
_enableTracking = false;
}
// now we'll loop back and try it all again
}
@@ -416,11 +432,15 @@ public abstract class Getdown extends Thread
throw new IOException("m.java_download_failed");
}
reportTrackingEvent("jvm_start", -1);
updateStatus("m.downloading_java");
ArrayList<Resource> list = new ArrayList<Resource>();
list.add(vmjar);
download(list);
reportTrackingEvent("jvm_unpack", -1);
updateStatus("m.unpacking_java");
if (!vmjar.unpack()) {
throw new IOException("m.java_unpack_failed");
@@ -452,6 +472,8 @@ public abstract class Getdown extends Thread
} catch (Exception e) {
Log.warning("Failed to regenerate .jsa dum file [error=" + e + "].");
}
reportTrackingEvent("jvm_complete", -1);
}
/**
@@ -529,6 +551,9 @@ public abstract class Getdown extends Thread
public void downloadProgress (int percent, long remaining) {
setStatus("m.downloading", percent, remaining, true);
if (percent > 0) {
reportTrackingEvent("progress", percent);
}
if (percent == 100) {
synchronized (lock) {
lock.notify();
@@ -715,6 +740,28 @@ public abstract class Getdown extends Thread
});
}
protected void reportTrackingEvent (String event, int progress)
{
if (!_enableTracking) {
return;
} else if (progress > 0) {
// we need to make sure we do the right thing if we skip over progress levels
for (int ii = _reportedProgress+1; ii <= progress; ii++) {
URL url = _app.getTrackingProgressURL(progress);
if (url != null) {
new ProgressReporter(url).start();
}
}
} else {
URL url = _app.getTrackingURL(event);
if (url != null) {
new ProgressReporter(url).start();
}
}
}
/**
* Load the image at the path. Before trying the exact path/file specified
* we will look to see if we can find a localized version by sticking a
@@ -785,6 +832,35 @@ public abstract class Getdown extends Thread
*/
protected abstract void exit (int exitCode);
/** Used to fetch a progress report URL. */
protected static class ProgressReporter extends Thread
{
public ProgressReporter (URL url) {
setDaemon(true);
_url = url;
}
public void run () {
try {
HttpURLConnection ucon = (HttpURLConnection)_url.openConnection();
ucon.connect();
try {
if (ucon.getResponseCode() != HttpURLConnection.HTTP_OK) {
Log.warning("Failed to report tracking event [url=" + _url +
", rcode=" + ucon.getResponseCode() + "].");
}
} finally {
ucon.disconnect();
}
} catch (IOException ioe) {
Log.warning("Failed to report tracking event [url=" + _url +
", error=" + ioe + "].");
}
}
protected URL _url;
}
/** Used to pass progress on to our user interface. */
protected ProgressObserver _progobs = new ProgressObserver() {
public void progress (final int percent) {
@@ -803,6 +879,9 @@ public abstract class Getdown extends Thread
protected boolean _dead;
protected long _startup;
protected boolean _enableTracking = true;
protected int _reportedProgress = 0;
/** The maximum number of resources that can be already present for bittorrent to be used. */
protected static final int MAX_TORRENT_VERIFIED_RESOURCES = 1;