Added support for running Getdown as a signed applet as well as support for
running our target application directly in the same JVM instead of forking off a new VM.
This commit is contained in:
@@ -6,6 +6,10 @@
|
|||||||
<property name="src.dir" value="src/java"/>
|
<property name="src.dir" value="src/java"/>
|
||||||
<property name="deploy.dir" value="dist"/>
|
<property name="deploy.dir" value="dist"/>
|
||||||
|
|
||||||
|
<!-- these are only used if we're going to sign things -->
|
||||||
|
<property file="build.properties"/>
|
||||||
|
<property file="${cert_dir}/certificate.properties"/>
|
||||||
|
|
||||||
<!-- used when generating javadocs -->
|
<!-- used when generating javadocs -->
|
||||||
<property name="javadoc.dir" value="${deploy.dir}/docs"/>
|
<property name="javadoc.dir" value="${deploy.dir}/docs"/>
|
||||||
<property name="doc.packages" value="com.threerings.getdown.*"/>
|
<property name="doc.packages" value="com.threerings.getdown.*"/>
|
||||||
@@ -82,5 +86,18 @@
|
|||||||
classpath="lib/retroweaver-all-1.2.2.jar"/>
|
classpath="lib/retroweaver-all-1.2.2.jar"/>
|
||||||
<weave inputjar="${deploy.dir}/${app.name}-pro.jar"
|
<weave inputjar="${deploy.dir}/${app.name}-pro.jar"
|
||||||
outputjar="${deploy.dir}/${app.name}-retro-pro.jar"/>
|
outputjar="${deploy.dir}/${app.name}-retro-pro.jar"/>
|
||||||
|
<!-- now combine the retroweaved jar file with the retroweaver runtime -->
|
||||||
|
<unjar src="${deploy.dir}/${app.name}-retro-pro.jar"
|
||||||
|
dest="${deploy.dir}/rptmp"/>
|
||||||
|
<unjar src="lib/retroweaver-rt-1.2.2.jar" dest="${deploy.dir}/rptmp"/>
|
||||||
|
<jar destfile="${deploy.dir}/${app.name}-retro-pro.jar"
|
||||||
|
manifest="lib/manifest.mf" basedir="${deploy.dir}/rptmp"/>
|
||||||
|
<delete dir="${deploy.dir}/rptmp"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="sign" depends="proguard">
|
||||||
|
<signjar jar="${deploy.dir}/${app.name}-retro-pro.jar" lazy="true"
|
||||||
|
keystore="${cert_dir}/lib/keystore.dat" storepass="${sign.storepass}"
|
||||||
|
alias="${sign.alias}" keypass="${sign.keypass}"/>
|
||||||
</target>
|
</target>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -23,3 +23,11 @@
|
|||||||
-keep public class com.threerings.getdown.launcher.Getdown {
|
-keep public class com.threerings.getdown.launcher.Getdown {
|
||||||
public static void main (java.lang.String[]);
|
public static void main (java.lang.String[]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-keep public class com.threerings.getdown.launcher.GetdownApp {
|
||||||
|
public static void main (java.lang.String[]);
|
||||||
|
}
|
||||||
|
|
||||||
|
-keep public class com.threerings.getdown.launcher.GetdownApplet {
|
||||||
|
*;
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,6 +6,12 @@ package com.threerings.getdown.data;
|
|||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.security.AllPermission;
|
||||||
|
import java.security.CodeSource;
|
||||||
|
import java.security.PermissionCollection;
|
||||||
|
import java.security.Permissions;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
@@ -17,6 +23,7 @@ import java.io.InputStreamReader;
|
|||||||
|
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -488,6 +495,54 @@ public class Application
|
|||||||
return Runtime.getRuntime().exec(sargs, null);
|
return Runtime.getRuntime().exec(sargs, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs this application directly in the current VM.
|
||||||
|
*/
|
||||||
|
public void invokeDirect ()
|
||||||
|
{
|
||||||
|
// create a custom class loader
|
||||||
|
ArrayList<URL> jars = new ArrayList<URL>();
|
||||||
|
for (Resource rsrc : _codes) {
|
||||||
|
try {
|
||||||
|
jars.add(
|
||||||
|
new URL("file", "", rsrc.getLocal().getAbsolutePath()));
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace(System.err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
URLClassLoader loader = new URLClassLoader(
|
||||||
|
jars.toArray(new URL[jars.size()]),
|
||||||
|
ClassLoader.getSystemClassLoader()) {
|
||||||
|
protected PermissionCollection getPermissions (CodeSource code) {
|
||||||
|
Permissions perms = new Permissions();
|
||||||
|
perms.add(new AllPermission());
|
||||||
|
return perms;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (String jvmarg : _jvmargs) {
|
||||||
|
if (jvmarg.startsWith("-D")) {
|
||||||
|
jvmarg = processArg(jvmarg.substring(2));
|
||||||
|
int eqidx = jvmarg.indexOf("=");
|
||||||
|
if (eqidx == -1) {
|
||||||
|
Log.warning("Bogus system property: '" + jvmarg + "'?");
|
||||||
|
} else {
|
||||||
|
System.setProperty(jvmarg.substring(0, eqidx),
|
||||||
|
jvmarg.substring(eqidx+1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Class<?> appclass = loader.loadClass(_class);
|
||||||
|
Method main = appclass.getMethod("main", SA_PROTO.getClass());
|
||||||
|
String[] args = _appargs.toArray(new String[_appargs.size()]);
|
||||||
|
main.invoke(null, new Object[] { args });
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace(System.err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Replaces the application directory and version in any argument. */
|
/** Replaces the application directory and version in any argument. */
|
||||||
protected String processArg (String arg)
|
protected String processArg (String arg)
|
||||||
{
|
{
|
||||||
@@ -813,4 +868,6 @@ public class Application
|
|||||||
|
|
||||||
protected ArrayList<String> _jvmargs = new ArrayList<String>();
|
protected ArrayList<String> _jvmargs = new ArrayList<String>();
|
||||||
protected ArrayList<String> _appargs = new ArrayList<String>();
|
protected ArrayList<String> _appargs = new ArrayList<String>();
|
||||||
|
|
||||||
|
protected static final String[] SA_PROTO = new String[0];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
package com.threerings.getdown.launcher;
|
package com.threerings.getdown.launcher;
|
||||||
|
|
||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
|
import java.awt.Container;
|
||||||
import java.awt.EventQueue;
|
import java.awt.EventQueue;
|
||||||
import java.awt.event.WindowAdapter;
|
import java.awt.event.WindowAdapter;
|
||||||
import java.awt.event.WindowEvent;
|
import java.awt.event.WindowEvent;
|
||||||
@@ -52,9 +53,15 @@ import com.threerings.getdown.util.ProgressObserver;
|
|||||||
* Manages the main control for the Getdown application updater and
|
* Manages the main control for the Getdown application updater and
|
||||||
* deployment system.
|
* deployment system.
|
||||||
*/
|
*/
|
||||||
public class Getdown extends Thread
|
public abstract class Getdown extends Thread
|
||||||
implements Application.StatusDisplay
|
implements Application.StatusDisplay
|
||||||
{
|
{
|
||||||
|
public static void main (String[] args)
|
||||||
|
{
|
||||||
|
// legacy support
|
||||||
|
GetdownApp.main(args);
|
||||||
|
}
|
||||||
|
|
||||||
public Getdown (File appDir, String appId)
|
public Getdown (File appDir, String appId)
|
||||||
{
|
{
|
||||||
super("Getdown");
|
super("Getdown");
|
||||||
@@ -78,6 +85,19 @@ public class Getdown extends Thread
|
|||||||
_startup = System.currentTimeMillis();
|
_startup = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is used by the applet which always needs a user interface and wants
|
||||||
|
* to load it as soon as possible.
|
||||||
|
*/
|
||||||
|
public void preInit ()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
_ifc = _app.init(true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.warning("Failed to preinit: " + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void run ()
|
public void run ()
|
||||||
{
|
{
|
||||||
// if we have no messages, just bail because we're hosed; the
|
// if we have no messages, just bail because we're hosed; the
|
||||||
@@ -104,12 +124,10 @@ public class Getdown extends Thread
|
|||||||
getdown();
|
getdown();
|
||||||
} else {
|
} else {
|
||||||
// create a panel they can use to configure the proxy settings
|
// create a panel they can use to configure the proxy settings
|
||||||
_frame.getContentPane().removeAll();
|
_container = createContainer();
|
||||||
_frame.getContentPane().add(
|
_container.add(
|
||||||
new ProxyPanel(this, _msgs), BorderLayout.CENTER);
|
new ProxyPanel(this, _msgs), BorderLayout.CENTER);
|
||||||
_frame.pack();
|
showContainer();
|
||||||
SwingUtil.centerWindow(_frame);
|
|
||||||
_frame.setVisible(true);
|
|
||||||
// allow them to close the window to abort the proxy
|
// allow them to close the window to abort the proxy
|
||||||
// configuration
|
// configuration
|
||||||
_dead = true;
|
_dead = true;
|
||||||
@@ -164,9 +182,8 @@ public class Getdown extends Thread
|
|||||||
}
|
}
|
||||||
|
|
||||||
// clear out our UI
|
// clear out our UI
|
||||||
_frame.dispose();
|
disposeContainer();
|
||||||
_status = null;
|
_status = null;
|
||||||
_frame = null;
|
|
||||||
|
|
||||||
// fire up a new thread
|
// fire up a new thread
|
||||||
new Thread(this).start();
|
new Thread(this).start();
|
||||||
@@ -477,40 +494,40 @@ public class Getdown extends Thread
|
|||||||
setStatus("m.launching", 100, -1L, false);
|
setStatus("m.launching", 100, -1L, false);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Process proc = _app.createProcess();
|
if (invokeDirect()) {
|
||||||
|
_app.invokeDirect();
|
||||||
|
|
||||||
// on Windows 98 and ME we need to stick around and read the
|
} else {
|
||||||
// output of stderr lest the process fill its output buffer
|
Process proc = _app.createProcess();
|
||||||
// and choke, yay!
|
|
||||||
if (LaunchUtil.mustMonitorChildren()) {
|
// on Windows 98 and ME we need to stick around and read the
|
||||||
// close our window if it's around
|
// output of stderr lest the process fill its output buffer and
|
||||||
if (_frame != null) {
|
// choke, yay!
|
||||||
_frame.dispose();
|
if (LaunchUtil.mustMonitorChildren()) {
|
||||||
|
// close our window if it's around
|
||||||
|
disposeContainer();
|
||||||
_status = null;
|
_status = null;
|
||||||
_frame = null;
|
InputStream stderr = proc.getErrorStream();
|
||||||
|
BufferedReader reader = new BufferedReader(
|
||||||
|
new InputStreamReader(stderr));
|
||||||
|
while (reader.readLine() != null) {
|
||||||
|
// nothing doing!
|
||||||
|
}
|
||||||
|
Log.info("Process exited: " + proc.waitFor());
|
||||||
}
|
}
|
||||||
Log.info("Sticking around to read stderr...");
|
|
||||||
InputStream stderr = proc.getErrorStream();
|
|
||||||
BufferedReader reader = new BufferedReader(
|
|
||||||
new InputStreamReader(stderr));
|
|
||||||
while (reader.readLine() != null) {
|
|
||||||
// nothing doing!
|
|
||||||
}
|
|
||||||
Log.info("Process exited: " + proc.waitFor());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we have a UI open and we haven't been around for at
|
// if we have a UI open and we haven't been around for at least 5
|
||||||
// least 5 seconds, don't stick a fork in ourselves straight
|
// seconds, don't stick a fork in ourselves straight away but give
|
||||||
// away but give our lovely user a chance to see what we're
|
// our lovely user a chance to see what we're doing
|
||||||
// doing
|
|
||||||
long uptime = System.currentTimeMillis() - _startup;
|
long uptime = System.currentTimeMillis() - _startup;
|
||||||
if (_frame != null && uptime < MIN_EXIST_TIME) {
|
if (_container != null && uptime < MIN_EXIST_TIME) {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(MIN_EXIST_TIME - uptime);
|
Thread.sleep(MIN_EXIST_TIME - uptime);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
System.exit(0);
|
exit(0);
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.logStackTrace(e);
|
Log.logStackTrace(e);
|
||||||
@@ -523,7 +540,7 @@ public class Getdown extends Thread
|
|||||||
*/
|
*/
|
||||||
protected void createInterface (boolean force)
|
protected void createInterface (boolean force)
|
||||||
{
|
{
|
||||||
if (_frame != null && !force) {
|
if (_container != null && !force) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -531,38 +548,26 @@ public class Getdown extends Thread
|
|||||||
BufferedImage bgimg = loadImage(_ifc.backgroundImage);
|
BufferedImage bgimg = loadImage(_ifc.backgroundImage);
|
||||||
BufferedImage barimg = loadImage(_ifc.progressImage);
|
BufferedImage barimg = loadImage(_ifc.progressImage);
|
||||||
|
|
||||||
// create our user interface, and display it
|
_container = createContainer();
|
||||||
String title = StringUtil.isBlank(_ifc.name) ? "" : _ifc.name;
|
|
||||||
if (_frame == null) {
|
|
||||||
_frame = new JFrame(title);
|
|
||||||
_frame.addWindowListener(new WindowAdapter() {
|
|
||||||
public void windowClosing (WindowEvent evt) {
|
|
||||||
if (_dead) {
|
|
||||||
System.exit(0);
|
|
||||||
} else {
|
|
||||||
if (_abort == null) {
|
|
||||||
_abort = new AbortPanel(Getdown.this, _msgs);
|
|
||||||
}
|
|
||||||
_abort.pack();
|
|
||||||
SwingUtil.centerWindow(_abort);
|
|
||||||
_abort.setVisible(true);
|
|
||||||
_abort.setState(JFrame.NORMAL);
|
|
||||||
_abort.requestFocus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
_frame.setResizable(false);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
_frame.setTitle(title);
|
|
||||||
_frame.getContentPane().removeAll();
|
|
||||||
}
|
|
||||||
_frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
|
|
||||||
_status = new StatusPanel(_msgs, _ifc, bgimg, barimg);
|
_status = new StatusPanel(_msgs, _ifc, bgimg, barimg);
|
||||||
_frame.getContentPane().add(_status, BorderLayout.CENTER);
|
_container.add(_status, BorderLayout.CENTER);
|
||||||
_frame.pack();
|
showContainer();
|
||||||
SwingUtil.centerWindow(_frame);
|
}
|
||||||
_frame.setVisible(true);
|
|
||||||
|
protected void handleWindowClose ()
|
||||||
|
{
|
||||||
|
if (_dead) {
|
||||||
|
exit(0);
|
||||||
|
} else {
|
||||||
|
if (_abort == null) {
|
||||||
|
_abort = new AbortPanel(Getdown.this, _msgs);
|
||||||
|
}
|
||||||
|
_abort.pack();
|
||||||
|
SwingUtil.centerWindow(_abort);
|
||||||
|
_abort.setVisible(true);
|
||||||
|
_abort.setState(JFrame.NORMAL);
|
||||||
|
_abort.requestFocus();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setStatus (final String message, final int percent,
|
protected void setStatus (final String message, final int percent,
|
||||||
@@ -575,6 +580,10 @@ public class Getdown extends Thread
|
|||||||
if (_status != null) {
|
if (_status != null) {
|
||||||
EventQueue.invokeLater(new Runnable() {
|
EventQueue.invokeLater(new Runnable() {
|
||||||
public void run () {
|
public void run () {
|
||||||
|
if (_status == null) {
|
||||||
|
Log.info("Dropping status '" + message + "'.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (message != null) {
|
if (message != null) {
|
||||||
_status.setStatus(message);
|
_status.setStatus(message);
|
||||||
}
|
}
|
||||||
@@ -601,67 +610,32 @@ public class Getdown extends Thread
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main (String[] args)
|
/**
|
||||||
{
|
* Creates the container in which our user interface will be displayed.
|
||||||
// maybe they specified the appdir in a system property
|
*/
|
||||||
int aidx = 0;
|
protected abstract Container createContainer ();
|
||||||
String adarg = System.getProperty("appdir");
|
|
||||||
// if not, check for a command line argument
|
|
||||||
if (StringUtil.isBlank(adarg)) {
|
|
||||||
if (args.length < 1) {
|
|
||||||
System.err.println(
|
|
||||||
"Usage: java -jar getdown.jar app_dir [app_id]");
|
|
||||||
System.exit(-1);
|
|
||||||
}
|
|
||||||
adarg = args[aidx++];
|
|
||||||
}
|
|
||||||
|
|
||||||
// look for a specific app identifier
|
/**
|
||||||
String appId = null;
|
* Shows the container in which our user interface will be displayed.
|
||||||
if (args.length > aidx) {
|
*/
|
||||||
appId = args[aidx++];
|
protected abstract void showContainer ();
|
||||||
}
|
|
||||||
|
|
||||||
// ensure a valid directory was supplied
|
/**
|
||||||
File appDir = new File(adarg);
|
* Disposes the container in which we have our user interface.
|
||||||
if (!appDir.exists() || !appDir.isDirectory()) {
|
*/
|
||||||
Log.warning("Invalid app_dir '" + adarg + "'.");
|
protected abstract void disposeContainer ();
|
||||||
System.exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// pipe our output into a file in the application directory
|
/**
|
||||||
if (System.getProperty("no_log_redir") == null) {
|
* If this method returns true we will run the application in the same JVM,
|
||||||
File log = new File(appDir, "launcher.log");
|
* otherwise we will fork off a new JVM. Some options are not supported if
|
||||||
try {
|
* we do not fork off a new JVM.
|
||||||
PrintStream logOut = new PrintStream(
|
*/
|
||||||
new BufferedOutputStream(new FileOutputStream(log)), true);
|
protected abstract boolean invokeDirect ();
|
||||||
System.setOut(logOut);
|
|
||||||
System.setErr(logOut);
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
Log.warning("Unable to redirect output to '" + log +
|
|
||||||
"': " + ioe);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// record a few things for posterity
|
/**
|
||||||
Log.info("------------------ VM Info ------------------");
|
* Requests that Getdown exit. In applet mode this does nothing.
|
||||||
Log.info("-- OS Name: " + System.getProperty("os.name"));
|
*/
|
||||||
Log.info("-- OS Arch: " + System.getProperty("os.arch"));
|
protected abstract void exit (int exitCode);
|
||||||
Log.info("-- OS Vers: " + System.getProperty("os.version"));
|
|
||||||
Log.info("-- Java Vers: " + System.getProperty("java.version"));
|
|
||||||
Log.info("-- Java Home: " + System.getProperty("java.home"));
|
|
||||||
Log.info("-- User Name: " + System.getProperty("user.name"));
|
|
||||||
Log.info("-- User Home: " + System.getProperty("user.home"));
|
|
||||||
Log.info("-- Cur dir: " + System.getProperty("user.dir"));
|
|
||||||
Log.info("---------------------------------------------");
|
|
||||||
|
|
||||||
try {
|
|
||||||
Getdown app = new Getdown(appDir, appId);
|
|
||||||
app.start();
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.logStackTrace(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 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() {
|
||||||
@@ -675,7 +649,7 @@ public class Getdown extends Thread
|
|||||||
new Application.UpdateInterface();
|
new Application.UpdateInterface();
|
||||||
|
|
||||||
protected ResourceBundle _msgs;
|
protected ResourceBundle _msgs;
|
||||||
protected JFrame _frame;
|
protected Container _container;
|
||||||
protected StatusPanel _status;
|
protected StatusPanel _status;
|
||||||
protected AbortPanel _abort;
|
protected AbortPanel _abort;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,128 @@
|
|||||||
|
//
|
||||||
|
// $Id$
|
||||||
|
|
||||||
|
package com.threerings.getdown.launcher;
|
||||||
|
|
||||||
|
import java.awt.Container;
|
||||||
|
import java.awt.event.WindowEvent;
|
||||||
|
import java.awt.event.WindowAdapter;
|
||||||
|
import javax.swing.JFrame;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.BufferedOutputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
|
||||||
|
import com.samskivert.swing.util.SwingUtil;
|
||||||
|
import com.samskivert.util.StringUtil;
|
||||||
|
|
||||||
|
import com.threerings.getdown.Log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does something extraordinary.
|
||||||
|
*/
|
||||||
|
public class GetdownApp
|
||||||
|
{
|
||||||
|
public static void main (String[] args)
|
||||||
|
{
|
||||||
|
// maybe they specified the appdir in a system property
|
||||||
|
int aidx = 0;
|
||||||
|
String adarg = System.getProperty("appdir");
|
||||||
|
// if not, check for a command line argument
|
||||||
|
if (StringUtil.isBlank(adarg)) {
|
||||||
|
if (args.length < 1) {
|
||||||
|
System.err.println(
|
||||||
|
"Usage: java -jar getdown.jar app_dir [app_id]");
|
||||||
|
System.exit(-1);
|
||||||
|
}
|
||||||
|
adarg = args[aidx++];
|
||||||
|
}
|
||||||
|
|
||||||
|
// look for a specific app identifier
|
||||||
|
String appId = null;
|
||||||
|
if (args.length > aidx) {
|
||||||
|
appId = args[aidx++];
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure a valid directory was supplied
|
||||||
|
File appDir = new File(adarg);
|
||||||
|
if (!appDir.exists() || !appDir.isDirectory()) {
|
||||||
|
Log.warning("Invalid app_dir '" + adarg + "'.");
|
||||||
|
System.exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// pipe our output into a file in the application directory
|
||||||
|
if (System.getProperty("no_log_redir") == null) {
|
||||||
|
File log = new File(appDir, "launcher.log");
|
||||||
|
try {
|
||||||
|
PrintStream logOut = new PrintStream(
|
||||||
|
new BufferedOutputStream(new FileOutputStream(log)), true);
|
||||||
|
System.setOut(logOut);
|
||||||
|
System.setErr(logOut);
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
Log.warning("Unable to redirect output to '" + log +
|
||||||
|
"': " + ioe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// record a few things for posterity
|
||||||
|
Log.info("------------------ VM Info ------------------");
|
||||||
|
Log.info("-- OS Name: " + System.getProperty("os.name"));
|
||||||
|
Log.info("-- OS Arch: " + System.getProperty("os.arch"));
|
||||||
|
Log.info("-- OS Vers: " + System.getProperty("os.version"));
|
||||||
|
Log.info("-- Java Vers: " + System.getProperty("java.version"));
|
||||||
|
Log.info("-- Java Home: " + System.getProperty("java.home"));
|
||||||
|
Log.info("-- User Name: " + System.getProperty("user.name"));
|
||||||
|
Log.info("-- User Home: " + System.getProperty("user.home"));
|
||||||
|
Log.info("-- Cur dir: " + System.getProperty("user.dir"));
|
||||||
|
Log.info("---------------------------------------------");
|
||||||
|
|
||||||
|
try {
|
||||||
|
Getdown app = new Getdown(appDir, appId) {
|
||||||
|
protected Container createContainer () {
|
||||||
|
// create our user interface, and display it
|
||||||
|
String title =
|
||||||
|
StringUtil.isBlank(_ifc.name) ? "" : _ifc.name;
|
||||||
|
if (_frame == null) {
|
||||||
|
_frame = new JFrame(title);
|
||||||
|
_frame.addWindowListener(new WindowAdapter() {
|
||||||
|
public void windowClosing (WindowEvent evt) {
|
||||||
|
handleWindowClose();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
_frame.setResizable(false);
|
||||||
|
} else {
|
||||||
|
_frame.setTitle(title);
|
||||||
|
_frame.getContentPane().removeAll();
|
||||||
|
}
|
||||||
|
_frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
|
||||||
|
return _frame.getContentPane();
|
||||||
|
}
|
||||||
|
protected void showContainer () {
|
||||||
|
if (_frame != null) {
|
||||||
|
_frame.pack();
|
||||||
|
SwingUtil.centerWindow(_frame);
|
||||||
|
_frame.setVisible(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
protected void disposeContainer () {
|
||||||
|
if (_frame != null) {
|
||||||
|
_frame.dispose();
|
||||||
|
_frame = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
protected boolean invokeDirect () {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
protected void exit (int exitCode) {
|
||||||
|
System.exit(exitCode);
|
||||||
|
}
|
||||||
|
protected JFrame _frame;
|
||||||
|
};
|
||||||
|
app.start();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.logStackTrace(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
//
|
||||||
|
// $Id$
|
||||||
|
|
||||||
|
package com.threerings.getdown.launcher;
|
||||||
|
|
||||||
|
import java.awt.Container;
|
||||||
|
|
||||||
|
import javax.swing.JApplet;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
|
||||||
|
import com.samskivert.util.RunAnywhere;
|
||||||
|
import com.samskivert.util.StringUtil;
|
||||||
|
|
||||||
|
import com.threerings.getdown.Log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An applet that can be used to launch a Getdown application (when signed and
|
||||||
|
* given privileges).
|
||||||
|
*/
|
||||||
|
public class GetdownApplet extends JApplet
|
||||||
|
{
|
||||||
|
@Override // documentation inherited
|
||||||
|
public void init ()
|
||||||
|
{
|
||||||
|
// when run from an applet, we install
|
||||||
|
String root;
|
||||||
|
if (RunAnywhere.isWindows()) {
|
||||||
|
root = "Application Data";
|
||||||
|
} else if (RunAnywhere.isMacOS()) {
|
||||||
|
root = "Library" + File.separator + "Application Support";
|
||||||
|
} else /* isLinux() or something wacky */ {
|
||||||
|
root = ".getdown";
|
||||||
|
}
|
||||||
|
|
||||||
|
String appname = getParameter("appname");
|
||||||
|
String appdir = System.getProperty("user.home") +
|
||||||
|
File.separator + root + File.separator + appname;
|
||||||
|
|
||||||
|
// if our application directory does not exist, auto-create it
|
||||||
|
File appDir = new File(appdir);
|
||||||
|
if (!appDir.exists() || !appDir.isDirectory()) {
|
||||||
|
if (!appDir.mkdirs()) {
|
||||||
|
Log.warning("Unable to create app_dir '" + appdir + "'.");
|
||||||
|
// TODO: report error
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if our getdown.txt file does not exist, auto-create it
|
||||||
|
File gdfile = new File(appDir, "getdown.txt");
|
||||||
|
if (!gdfile.exists()) {
|
||||||
|
String appbase = getParameter("appbase");
|
||||||
|
if (StringUtil.isBlank(appbase)) {
|
||||||
|
Log.warning("Missing 'appbase' cannot auto-create " +
|
||||||
|
"application directory.");
|
||||||
|
// TODO: report
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
PrintStream out = new PrintStream(new FileOutputStream(gdfile));
|
||||||
|
out.println("appbase = " + appbase);
|
||||||
|
out.close();
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
Log.warning("Failed to create '" + gdfile + "'.");
|
||||||
|
Log.logStackTrace(ioe);
|
||||||
|
// TODO: report
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// record a few things for posterity
|
||||||
|
Log.info("------------------ VM Info ------------------");
|
||||||
|
Log.info("-- OS Name: " + System.getProperty("os.name"));
|
||||||
|
Log.info("-- OS Arch: " + System.getProperty("os.arch"));
|
||||||
|
Log.info("-- OS Vers: " + System.getProperty("os.version"));
|
||||||
|
Log.info("-- Java Vers: " + System.getProperty("java.version"));
|
||||||
|
Log.info("-- Java Home: " + System.getProperty("java.home"));
|
||||||
|
Log.info("-- User Name: " + System.getProperty("user.name"));
|
||||||
|
Log.info("-- User Home: " + System.getProperty("user.home"));
|
||||||
|
Log.info("-- Cur dir: " + System.getProperty("user.dir"));
|
||||||
|
Log.info("---------------------------------------------");
|
||||||
|
|
||||||
|
try {
|
||||||
|
_getdown = new Getdown(appDir, null) {
|
||||||
|
protected Container createContainer () {
|
||||||
|
getContentPane().removeAll();
|
||||||
|
return getContentPane();
|
||||||
|
}
|
||||||
|
protected void showContainer () {
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
protected void disposeContainer () {
|
||||||
|
}
|
||||||
|
protected boolean invokeDirect () {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
protected void exit (int exitCode) {
|
||||||
|
Log.info("Applet \"exiting\".");
|
||||||
|
// don't exit as we're in an applet
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
SwingUtilities.invokeAndWait(new Runnable() {
|
||||||
|
public void run () {
|
||||||
|
_getdown.preInit();
|
||||||
|
_getdown.createInterface(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.logStackTrace(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override // documentation inherited
|
||||||
|
public void start ()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
_getdown.start();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.logStackTrace(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override // documentation inherited
|
||||||
|
public void stop ()
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Getdown _getdown;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user