Minor reorg & fix all "config UI when getdown.txt" changes issues.

This commit is contained in:
Michael Bayne
2018-12-01 20:00:03 -08:00
parent f4679b4a36
commit 9f2071f152
6 changed files with 63 additions and 95 deletions
@@ -510,7 +510,7 @@ public class Application
* discovered later, the caller can use the application base to download a new {@code * discovered later, the caller can use the application base to download a new {@code
* getdown.txt} file and try again. * getdown.txt} file and try again.
* *
* @return a configured Config instance that contains information from the config file. * @return a {@code Config} instance that contains information from the config file.
* *
* @exception IOException thrown if there is an error reading the file or an error encountered * @exception IOException thrown if there is an error reading the file or an error encountered
* during its parsing. * during its parsing.
@@ -672,7 +672,7 @@ public class Application
parseResources(config, "resource", Resource.NORMAL, _resources); parseResources(config, "resource", Resource.NORMAL, _resources);
parseResources(config, "uresource", Resource.UNPACK, _resources); parseResources(config, "uresource", Resource.UNPACK, _resources);
parseResources(config, "xresource", Resource.EXEC, _resources); parseResources(config, "xresource", Resource.EXEC, _resources);
parseResources(config, "presource", Resource.PREDOWNLOAD, _resources); parseResources(config, "presource", Resource.PRELOAD, _resources);
// parse our auxiliary resource groups // parse our auxiliary resource groups
for (String auxgroup : config.getList("auxgroups")) { for (String auxgroup : config.getList("auxgroups")) {
@@ -721,26 +721,13 @@ public class Application
_maxConcDownloads = Math.max(1, config.getInt("max_concurrent_downloads", _maxConcDownloads = Math.max(1, config.getInt("max_concurrent_downloads",
SysProps.threadPoolSize())); SysProps.threadPoolSize()));
// extract some info used to configure our child process on macOS
_dockName = config.getString("ui.name");
_dockIconPath = config.getString("ui.mac_dock_icon", "../desktop.icns");
return config; return config;
} }
/**
* Sets various properties using an UpdateInterface based on {@code config}
* @param config Information to base the UpdateInterface off
* @return a configured UpdateInterface instance that will be used to configure the update UI
*/
public UpdateInterface initUpdateInterface(Config config) {
// parse and return our application config
UpdateInterface ui = new UpdateInterface(config);
_name = ui.name;
_dockIconPath = config.getString("ui.mac_dock_icon");
if (_dockIconPath == null) {
_dockIconPath = "../desktop.icns"; // use a sensible default
}
return ui;
}
/** /**
* Adds strings of the form pair0=pair1 to collector for each pair parsed out of pairLocation. * Adds strings of the form pair0=pair1 to collector for each pair parsed out of pairLocation.
*/ */
@@ -936,7 +923,7 @@ public class Application
// we love our Mac users, so we do nice things to preserve our application identity // we love our Mac users, so we do nice things to preserve our application identity
if (LaunchUtil.isMacOS()) { if (LaunchUtil.isMacOS()) {
args.add("-Xdock:icon=" + getLocalPath(_dockIconPath).getAbsolutePath()); args.add("-Xdock:icon=" + getLocalPath(_dockIconPath).getAbsolutePath());
args.add("-Xdock:name=" + _name); args.add("-Xdock:name=" + _dockName);
} }
// pass along our proxy settings // pass along our proxy settings
@@ -1179,7 +1166,7 @@ public class Application
clearValidationMarkers(); clearValidationMarkers();
// if the new copy validates, reinitialize ourselves; otherwise report baffling hoseage // if the new copy validates, reinitialize ourselves; otherwise report baffling hoseage
if (_digest.validateResource(crsrc, null)) { if (_digest.validateResource(crsrc, null)) {
initUpdateInterface(init(true)); init(true);
} else { } else {
log.warning(CONFIG_FILE + " failed to validate even after redownloading. " + log.warning(CONFIG_FILE + " failed to validate even after redownloading. " +
"Blindly forging onward."); "Blindly forging onward.");
@@ -1713,7 +1700,7 @@ public class Application
protected URL _vappbase; protected URL _vappbase;
protected URL _latest; protected URL _latest;
protected String _class; protected String _class;
protected String _name; protected String _dockName;
protected String _dockIconPath; protected String _dockIconPath;
protected boolean _strictComments; protected boolean _strictComments;
protected boolean _windebug; protected boolean _windebug;
@@ -37,13 +37,13 @@ public class Resource implements Comparable<Resource>
/** Indicates that the resource should be marked executable. */ /** Indicates that the resource should be marked executable. */
EXEC, EXEC,
/** Indicates that the resource should be downloaded before a UI is displayed. */ /** Indicates that the resource should be downloaded before a UI is displayed. */
PREDOWNLOAD PRELOAD
}; };
public static final EnumSet<Attr> NORMAL = EnumSet.noneOf(Attr.class); public static final EnumSet<Attr> NORMAL = EnumSet.noneOf(Attr.class);
public static final EnumSet<Attr> UNPACK = EnumSet.of(Attr.UNPACK); public static final EnumSet<Attr> UNPACK = EnumSet.of(Attr.UNPACK);
public static final EnumSet<Attr> EXEC = EnumSet.of(Attr.EXEC); public static final EnumSet<Attr> EXEC = EnumSet.of(Attr.EXEC);
public static final EnumSet<Attr> PREDOWNLOAD = EnumSet.of(Attr.PREDOWNLOAD); public static final EnumSet<Attr> PRELOAD = EnumSet.of(Attr.PRELOAD);
/** /**
* Computes the MD5 hash of the supplied file. * Computes the MD5 hash of the supplied file.
@@ -205,11 +205,11 @@ public class Resource implements Comparable<Resource>
} }
/** /**
* Returns true if this resource should be predownloaded. * Returns true if this resource should be pre-downloaded.
*/ */
public boolean shouldPredownload () public boolean shouldPredownload ()
{ {
return _attrs.contains(Attr.PREDOWNLOAD); return _attrs.contains(Attr.PRELOAD);
} }
/** /**
@@ -267,7 +267,7 @@ public class Resource implements Comparable<Resource>
/** /**
* Installs the {@code getLocalNew} version of this resource to {@code getLocal}. * Installs the {@code getLocalNew} version of this resource to {@code getLocal}.
* @param validate Validate resource after installing? * @param validate whether or not to mark the resource as valid after installing.
*/ */
public void install (boolean validate) throws IOException { public void install (boolean validate) throws IOException {
File source = getLocalNew(), dest = getLocal(); File source = getLocalNew(), dest = getLocal();
@@ -276,19 +276,11 @@ public class Resource implements Comparable<Resource>
throw new IOException("Failed to rename " + source + " to " + dest); throw new IOException("Failed to rename " + source + " to " + dest);
} }
applyAttrs(); applyAttrs();
if (validate) {
if (validate){
markAsValid(); markAsValid();
} }
} }
/**
* Same as calling {@link #install(boolean)} with {@code true}
*/
public void install () throws IOException {
install(true);
}
/** /**
* Unpacks this resource file into the directory that contains it. * Unpacks this resource file into the directory that contains it.
*/ */
@@ -60,13 +60,13 @@ public class Differ
} }
Application oapp = new Application(new EnvConfig(ovdir)); Application oapp = new Application(new EnvConfig(ovdir));
oapp.initUpdateInterface(oapp.init(false)); oapp.init(false);
ArrayList<Resource> orsrcs = new ArrayList<>(); ArrayList<Resource> orsrcs = new ArrayList<>();
orsrcs.addAll(oapp.getCodeResources()); orsrcs.addAll(oapp.getCodeResources());
orsrcs.addAll(oapp.getResources()); orsrcs.addAll(oapp.getResources());
Application napp = new Application(new EnvConfig(nvdir)); Application napp = new Application(new EnvConfig(nvdir));
napp.initUpdateInterface(napp.init(false)); napp.init(false);
ArrayList<Resource> nrsrcs = new ArrayList<>(); ArrayList<Resource> nrsrcs = new ArrayList<>();
nrsrcs.addAll(napp.getCodeResources()); nrsrcs.addAll(napp.getCodeResources());
nrsrcs.addAll(napp.getResources()); nrsrcs.addAll(napp.getResources());
@@ -75,7 +75,7 @@ public class Digester
// create our application and instruct it to parse its business // create our application and instruct it to parse its business
Application app = new Application(new EnvConfig(appdir)); Application app = new Application(new EnvConfig(appdir));
app.initUpdateInterface(app.init(false)); app.init(false);
List<Resource> rsrcs = new ArrayList<>(); List<Resource> rsrcs = new ArrayList<>();
rsrcs.add(app.getConfigResource()); rsrcs.add(app.getConfigResource());
@@ -114,7 +114,7 @@ public abstract class Getdown extends Thread
} else if (_readyToInstall) { } else if (_readyToInstall) {
log.info("Installing " + _toInstallResources.size() + " downloaded resources:"); log.info("Installing " + _toInstallResources.size() + " downloaded resources:");
for (Resource resource : _toInstallResources) { for (Resource resource : _toInstallResources) {
resource.install(); resource.install(true);
} }
_toInstallResources.clear(); _toInstallResources.clear();
_readyToInstall = false; _readyToInstall = false;
@@ -157,6 +157,7 @@ public abstract class Getdown extends Thread
} else { } else {
// create a panel they can use to configure the proxy settings // create a panel they can use to configure the proxy settings
_container = createContainer(); _container = createContainer();
configureContainer();
_container.add(new ProxyPanel(this, _msgs), BorderLayout.CENTER); _container.add(new ProxyPanel(this, _msgs), BorderLayout.CENTER);
showContainer(); showContainer();
// allow them to close the window to abort the proxy configuration // allow them to close the window to abort the proxy configuration
@@ -277,9 +278,7 @@ public abstract class Getdown extends Thread
// to get some sort of interface configuration and the appbase URL // to get some sort of interface configuration and the appbase URL
log.info("Checking whether we need to use a proxy..."); log.info("Checking whether we need to use a proxy...");
try { try {
Config config = _app.init(true); readConfig(true);
doPredownloads(_app.getResources());
_ifc = _app.initUpdateInterface(config);
} catch (IOException ioe) { } catch (IOException ioe) {
// no worries // no worries
} }
@@ -339,32 +338,34 @@ public abstract class Getdown extends Thread
} }
} }
protected void readConfig (boolean preloads) throws IOException {
Config config = _app.init(true);
if (preloads) doPredownloads(_app.getResources());
_ifc = new Application.UpdateInterface(config);
}
/** /**
* Finds resources from {@code resources} that have a {@code PREDOWNLOAD} attribute, * Downloads and installs (without verifying) any resources that are marked with a
* then downloads and installs them (without verifying them) * {@code PRELOAD} attribute.
* @param resources resources to predownload * @param resources the full set of resources from the application (the predownloads will be
* extracted from it).
*/ */
protected void doPredownloads (Collection<Resource> resources) { protected void doPredownloads (Collection<Resource> resources) {
List<Resource> predownloads = new ArrayList<>(); List<Resource> predownloads = new ArrayList<>();
for (Resource rsrc : resources) {
for(Resource rsrc: resources) { if (rsrc.shouldPredownload() && !rsrc.getLocal().exists()) {
if(rsrc.shouldPredownload() && !rsrc.getLocal().exists()) {
predownloads.add(rsrc); predownloads.add(rsrc);
} }
} }
try { try {
download(predownloads); download(predownloads);
for (Resource rsrc : predownloads) {
for(Resource rsrc: predownloads) { rsrc.install(false); // install but don't validate yet
// Install but don't validate yet
rsrc.install(false);
} }
} catch (IOException ioe) { } catch (IOException ioe) {
log.warning("Failed to predownload resources. Continuing...", ioe); log.warning("Failed to predownload resources. Continuing...", ioe);
} }
} }
/** /**
@@ -380,23 +381,15 @@ public abstract class Getdown extends Thread
try { try {
// first parses our application deployment file // first parses our application deployment file
try { try {
Config config = _app.init(true); readConfig(true);
doPredownloads(_app.getResources());
_ifc = _app.initUpdateInterface(config);
} catch (IOException ioe) { } catch (IOException ioe) {
log.warning("Failed to initialize: " + ioe); log.warning("Failed to initialize: " + ioe);
_app.attemptRecovery(this); _app.attemptRecovery(this);
// and re-initalize // and re-initalize
Config config = _app.init(true); readConfig(true);
doPredownloads(_app.getResources()); // and force our UI to be recreated with the updated info
_ifc = _app.initUpdateInterface(config);
// now force our UI to be recreated with the updated info
createInterfaceAsync(true); createInterfaceAsync(true);
setIcons(); // Force icons to be displayed
} }
if (!_app.lockForUpdates()) { if (!_app.lockForUpdates()) {
throw new MultipleGetdownRunning(); throw new MultipleGetdownRunning();
} }
@@ -603,12 +596,6 @@ public abstract class Getdown extends Thread
} }
} }
/**
* Force app to (re)set icons
*/
protected abstract void setIcons();
/** /**
* Downloads and installs an Java VM bundled with the application. This is called if we are not * Downloads and installs an Java VM bundled with the application. This is called if we are not
* running with the necessary Java version. * running with the necessary Java version.
@@ -631,7 +618,7 @@ public abstract class Getdown extends Thread
reportTrackingEvent("jvm_unpack", -1); reportTrackingEvent("jvm_unpack", -1);
updateStatus("m.unpacking_java"); updateStatus("m.unpacking_java");
vmjar.install(); vmjar.install(true);
// these only run on non-Windows platforms, so we use Unix file separators // these only run on non-Windows platforms, so we use Unix file separators
String localJavaDir = LaunchUtil.LOCAL_JAVA_DIR + "/"; String localJavaDir = LaunchUtil.LOCAL_JAVA_DIR + "/";
@@ -720,8 +707,7 @@ public abstract class Getdown extends Thread
// finally update our metadata files... // finally update our metadata files...
_app.updateMetadata(); _app.updateMetadata();
// ...and reinitialize the application // ...and reinitialize the application
Config config = _app.init(true); readConfig(false);
_ifc = _app.initUpdateInterface(config);
} }
/** /**
@@ -879,6 +865,7 @@ public abstract class Getdown extends Thread
} else { } else {
_container.removeAll(); _container.removeAll();
} }
configureContainer();
_layers = new JLayeredPane(); _layers = new JLayeredPane();
_container.add(_layers, BorderLayout.CENTER); _container.add(_layers, BorderLayout.CENTER);
_patchNotes = new JButton(new AbstractAction(_msgs.getString("m.patch_notes")) { _patchNotes = new JButton(new AbstractAction(_msgs.getString("m.patch_notes")) {
@@ -1059,6 +1046,11 @@ public abstract class Getdown extends Thread
*/ */
protected abstract Container createContainer (); protected abstract Container createContainer ();
/**
* Configures the interface container based on the latest UI config.
*/
protected abstract void configureContainer ();
/** /**
* Shows the container in which our user interface will be displayed. * Shows the container in which our user interface will be displayed.
*/ */
@@ -101,37 +101,36 @@ public class GetdownApp
@Override @Override
protected Container createContainer () { protected Container createContainer () {
// create our user interface, and display it // create our user interface, and display it
String title = StringUtil.isBlank(_ifc.name) ? "" : _ifc.name;
if (_frame == null) { if (_frame == null) {
_frame = new JFrame(title); _frame = new JFrame("");
_frame.addWindowListener(new WindowAdapter() { _frame.addWindowListener(new WindowAdapter() {
@Override @Override
public void windowClosing (WindowEvent evt) { public void windowClosing (WindowEvent evt) {
handleWindowClose(); handleWindowClose();
} }
}); });
// this cannot be called in configureContainer as it is only allowed before the
// frame has been displayed for the first time
_frame.setUndecorated(_ifc.hideDecorations); _frame.setUndecorated(_ifc.hideDecorations);
try {
_frame.setBackground(new Color(_ifc.background, true));
} catch (UnsupportedOperationException e) {
log.warning("Failed to set background", e);
} catch (IllegalComponentStateException e) {
log.warning("Failed to set background", e);
}
_frame.setResizable(false); _frame.setResizable(false);
} else { } else {
_frame.setTitle(title);
_frame.getContentPane().removeAll(); _frame.getContentPane().removeAll();
} }
setIcons();
_frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); _frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
return _frame.getContentPane(); return _frame.getContentPane();
} }
protected void setIcons() { @Override
if(_frame == null) return; protected void configureContainer () {
if (_frame == null) return;
_frame.setTitle(_ifc.name);
try {
_frame.setBackground(new Color(_ifc.background, true));
} catch (Exception e) {
log.warning("Failed to set background", "bg", _ifc.background, e);
}
if (_ifc.iconImages != null) { if (_ifc.iconImages != null) {
ArrayList<Image> icons = new ArrayList<>(); ArrayList<Image> icons = new ArrayList<>();
@@ -148,8 +147,6 @@ public class GetdownApp
} else { } else {
_frame.setIconImages(icons); _frame.setIconImages(icons);
} }
} else {
log.info("No icons found to load...");
} }
} }