// avoid ambiguity with java.util.Base64 which we can't use as it's 1.8+
import com.threerings.getdown.util.Base64;
+import com.threerings.getdown.data.EnvConfig;
+import com.threerings.getdown.data.EnvConfig.Note;
+
import static com.threerings.getdown.Log.log;
import static java.nio.charset.StandardCharsets.UTF_8;
log.info("Found no getdown.txt file", "appdir", getAppDir());
}
} catch (Exception e) {
- log.warning("Failure reading config file", "file", config, e);
+ log.warning("Failure reading config file", "file", _config, e);
+ }
+
+ // see if there's an override config from locator file
+ Config locatorConfig = createLocatorConfig(opts);
+
+ // merge the locator file config into config (or replace config with)
+ if (locatorConfig != null) {
+ if (config == null || locatorConfig.getBoolean(LOCATOR_FILE_EXTENSION+"_replace")) {
+ config = locatorConfig;
+ } else {
+ config.mergeConfig(locatorConfig, locatorConfig.getBoolean(LOCATOR_FILE_EXTENSION+"_merge"));
+ }
}
// if we failed to read our config file, check for an appbase specified via a system
// first determine our application base, this way if anything goes wrong later in the
// process, our caller can use the appbase to download a new configuration file
_appbase = config.getString("appbase");
- // override if a Version Locator file has been used
- if (newAppbase != null) {
- _appbase = newAppbase.toString();
- }
+
if (_appbase == null) {
throw new RuntimeException("m.missing_appbase");
}
}
// almost finally check the startup file arguments
- for (File f : startupFiles) {
+ for (File f : _startupFiles) {
_appargs.add(f.getAbsolutePath());
break; // Only add one file to open
}
if (j > -1) {
ext = filename.substring(j+1);
}
- if (locatorFileExtension.equals(ext.toLowerCase())) {
+ if (LOCATOR_FILE_EXTENSION.equals(ext.toLowerCase())) {
// this file extension should have been dealt with in Getdown class
} else {
_appargs.add(0, "-open");
{
return new File(appdir, path);
}
-
- public void addStartupFile (File f) {
- startupFiles.add(f);
- }
-
- public void newAppbase (URL url) {
- if (
- url.getHost().equals(locatorDomain)
- || (allowLocatorSubdomains && url.getHost().endsWith("."+locatorDomain))
- || (allowLocatorFileProtocol && url.getProtocol().equals("file") && url.getHost().equals(""))
- ) {
- newAppbase = url;
- log.info("Appbase set to Java Version Locator url '"+url.toString()+"'");
- return;
+
+ public static void setStartupFilesFromParameterString(String p) {
+ // multiple files *might* be passed in as space separated quoted filenames
+ String q = "\"";
+ if (!StringUtil.isBlank(p)) {
+ String[] filenames;
+ // split quoted params or treat as single string array
+ if (p.startsWith(q) && p.endsWith(q)) {
+ // this fails if, e.g.
+ // p=q("stupidfilename\" " "otherfilename")
+ // let's hope no-one ever ends a filename with '" '
+ filenames = p.substring(q.length(),p.length()-q.length()).split(q+" "+q);
+ } else {
+ // single unquoted filename
+ filenames = new String[]{p};
+ }
+
+ // check for locator file. Only allow one locator file to be double clicked (if multiple files opened, ignore locator files)
+ String locatorFilename = filenames.length >= 1 ? filenames[0] : null;
+ if (
+ !StringUtil.isBlank(locatorFilename)
+ && locatorFilename.toLowerCase().endsWith("."+Application.LOCATOR_FILE_EXTENSION)
+ ) {
+ setLocatorFile(locatorFilename);
+ // remove the locator filename from the filenames array
+ String[] otherFilenames = new String[filenames.length - 1];
+ System.arraycopy(filenames, 1, otherFilenames, 0, otherFilenames.length);
+ filenames = otherFilenames;
+ }
+
+ for (int i = 0; i < filenames.length; i++) {
+ String filename = filenames[i];
+ // skip any other locator files in a multiple file list
+ if (! filename.toLowerCase().endsWith("."+Application.LOCATOR_FILE_EXTENSION)) {
+ addStartupFile(filename);
+ }
+ }
}
- log.info("Java Version Locator url '"+url.toString()+"' does not have satisfy domain rules ("
- +(allowLocatorFileProtocol?"file:///|":"")
- +"https://"
- +(allowLocatorSubdomains?"[*.]":locatorDomain)
- +"). Ignoring");
+ }
+
+ public static void setLocatorFile(String filename) {
+ _locatorFile = new File(filename);
+ }
+
+ public static void addStartupFile(String filename) {
+ _startupFiles.add(new File(filename));
}
+
+ private Config createLocatorConfig(Config.ParseOpts opts) {
+ if (_locatorFile == null) {
+ return null;
+ }
+
+ Config locatorConfig = null;
+
+ try {
+ Config tmpConfig = null;
+ if (_locatorFile.exists()) {
+ tmpConfig = Config.parseConfig(_locatorFile, opts);
+ } else {
+ log.warning("Given locator file does not exist", "file", _locatorFile);
+ }
+
+ // appbase is sanitised in HostWhitelist and here!
+ Map<String, Object> tmpdata = new HashMap<>();
+ tmpdata.put("appbase", tmpConfig.getString("appbase"));
+ tmpdata.put("appargs", tmpConfig.getString("appargs"));
+ tmpdata.put("jvmargs", tmpConfig.getString("jvmargs"));
+ tmpdata.put(LOCATOR_FILE_EXTENSION+"replace", tmpConfig.getString(LOCATOR_FILE_EXTENSION+"replace"));
+ tmpdata.put(LOCATOR_FILE_EXTENSION+"merge", tmpConfig.getString(LOCATOR_FILE_EXTENSION+"merge"));
+ locatorConfig = new Config(tmpdata);
+
+ } catch (Exception e) {
+ log.warning("Failure reading locator file", "file", _locatorFile, e);
+ }
+
+ return locatorConfig;
+ }
+
protected final EnvConfig _envc;
protected File _config;
protected Digest _digest;
protected List<String> _jvmargs = new ArrayList<>();
protected List<String> _appargs = new ArrayList<>();
- protected List<File> startupFiles = new ArrayList<>();
- protected URL newAppbase;
protected String[] _optimumJvmArgs;
protected static final String ENV_VAR_PREFIX = "%ENV.";
protected static final Pattern ENV_VAR_PATTERN = Pattern.compile("%ENV\\.(.*?)%");
- protected static final String locatorDomain = "jalview.org";
- protected boolean allowLocatorSubdomains = true;
- protected boolean allowLocatorFileProtocol = true;
-
- public static final String locatorFileExtension = "jvl";
+
+ protected static File _locatorFile;
+ protected static List<File> _startupFiles = new ArrayList<>();
+ public static final String LOCATOR_FILE_EXTENSION = "jvl";
}
import java.io.File;
import java.io.FileInputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.*;
import com.threerings.getdown.util.StringUtil;
+import com.threerings.getdown.data.Application;
/** Configuration that comes from our "environment" (command line args, sys props, etc.). */
public final class EnvConfig {
appIdProv + "'"));
}
}
+
+ int skipArgs = 2;
+ // Look for locator file, pass to Application and remove from appArgs
+ String argvLocatorFilename = argv.length > 2 ? argv[2] : null;
+ if (
+ !StringUtil.isBlank(argvLocatorFilename)
+ && argvLocatorFilename.toLowerCase().endsWith("."+Application.LOCATOR_FILE_EXTENSION)
+ ) {
+ notes.add(Note.info("locatorFilename in args: '"+argv[2]+"'"));
+ Application.setLocatorFile(argvLocatorFilename);
+
+ skipArgs++;
+ }
- // ensure that we were able to fine an app dir
+ // ensure that we were able to find an app dir
if (appDir == null) {
return null; // caller will report problem to user
}
return null;
}
- // pass along anything after the first two args as extra app args
- List<String> appArgs = argv.length > 2 ?
- Arrays.asList(argv).subList(2, argv.length) :
+ // pass along anything after the first two (or three) args as extra app args
+ List<String> appArgs = argv.length > skipArgs ?
+ Arrays.asList(argv).subList(skipArgs, argv.length) :
Collections.<String>emptyList();
// load X.509 certificate if it exists
String os = bits[0], arch = (bits.length > 1) ? bits[1] : "";
return (osname.indexOf(os) != -1) && (osarch.indexOf(arch) != -1);
}
+
+ public void mergeConfig(Config newValues, boolean merge) {
+
+ for (Map.Entry<String, Object> entry : newValues.getData().entrySet()) {
+
+ String key = entry.getKey();
+ Object nvalue = entry.getValue();
+
+ if (!merge || key.equals("appbase")) {
+ _data.put(key, nvalue);
+ } else {
+
+ // merge
+
+ Object value = _data.get(key);
+
+ if (value == null) {
+ _data.put(key, nvalue);
+ } else if (value instanceof String) {
+ if (nvalue instanceof String) {
+
+ // value is String, nvalue is String
+ _data.put(key, new String[] { (String)value, (String)nvalue });
+
+ } else if (nvalue instanceof String[]) {
+
+ // value is String, nvalue is String[]
+ String[] nvalues = (String[])nvalue;
+ String[] newvalues = new String[nvalues.length+1];
+ newvalues[0] = (String)value;
+ System.arraycopy(nvalues, 0, newvalues, 1, nvalues.length);
+ _data.put(key, newvalues);
+
+ }
+ } else if (value instanceof String[]) {
+ if (nvalue instanceof String) {
+
+ // value is String[], nvalue is String
+ String[] values = (String[])value;
+ String[] newvalues = new String[values.length+1];
+ System.arraycopy(values, 0, newvalues, 0, values.length);
+ newvalues[values.length] = (String)nvalue;
+ _data.put(key, newvalues);
+
+ } else if (nvalue instanceof String[]) {
+
+ // value is String[], nvalue is String[]
+ String[] values = (String[])value;
+ String[] nvalues = (String[])nvalue;
+ String[] newvalues = new String[values.length + nvalues.length];
+ System.arraycopy(values, 0, newvalues, 0, values.length);
+ System.arraycopy(nvalues, 0, newvalues, values.length, newvalues.length);
+ _data.put(key, newvalues);
+
+ }
+ }
+
+ }
+
+ }
+
+ }
+
+ public Map<String, Object> getData() {
+ return _data;
+ }
private final Map<String, Object> _data;
}
*/
public static URL verify (URL url) throws MalformedURLException
{
+
+
return verify(Build.hostWhitelist(), url);
}
}
String urlHost = url.getHost();
+ String protocol = url.getProtocol();
+
+ if (ALLOW_LOCATOR_FILE_PROTOCOL && protocol.equals("file") && urlHost.equals("")) {
+ return url;
+ }
+
for (String host : hosts) {
String regex = host.replace(".", "\\.").replace("*", ".*");
if (urlHost.matches(regex)) {
throw new MalformedURLException(
"The host for the specified URL (" + url + ") is not in the host whitelist: " + hosts);
}
+ private static boolean ALLOW_LOCATOR_FILE_PROTOCOL = true;
}
}
};
- public void setStartupFilesFromParameterString(String p) {
- String q = "\"";
- if (p != null && p.length() > 0) {
- String[] filenames;
- if (p.startsWith(q) && p.endsWith(q)) {
- filenames = p.substring(q.length(),p.length()-q.length()).split(q+" "+q);
- } else {
- filenames = new String[]{p};
- }
- for (int i = 0; i < filenames.length; i++) {
- String filename = filenames[i];
- String ext = null;
- int j = filename.lastIndexOf('.');
- if (j > -1) {
- ext = filename.substring(j+1);
- }
- // jvl files
- if (_app.locatorFileExtension.equals(ext.toLowerCase())) {
- File f = new File(filename);
- if (f.exists()) {
- String appbase = null;
- try {
- java.util.Properties jvlprops = new java.util.Properties();
- FileInputStream in = new FileInputStream(f);
- jvlprops.load(in);
- in.close();
- appbase = jvlprops.getProperty("appbase");
- } catch(Exception e) {
- log.warning("Something went wrong reading Jalview Version Locator file '"+filename+"'", e);
- }
- if (appbase != null) {
- try {
- URL newAppbase = new URL(appbase);
- _app.newAppbase(newAppbase);
- log.warning("Java Version Locator url '"+appbase+"' found in file '"+filename+"' being used");
- } catch(MalformedURLException e) {
- log.warning("Java Version Locator url '"+appbase+"' found in file '"+filename+"' is malformed", e);
- }
- }
- }
- } else {
- // jvp files etc
- boolean addedStartupFile = false; // only add one startup file
- if (! addedStartupFile) {
- File f = new File(filename);
- if (f.exists()) {
- _app.addStartupFile(f);
- addedStartupFile = true;
- }
- }
- }
- }
- }
- }
-
protected Application _app;
protected Application.UpdateInterface _ifc = new Application.UpdateInterface(Config.EMPTY);
@Override
public void startupPerformed(String parameters)
{
- log.warning("startupPerformed: '"+parameters+"'");
+ log.warning("StartupNotification.Listener.startupPerformed: '"+parameters+"'");
setStartupFilesParameterString(parameters);
}
});
e.printStackTrace();
}
- //Thread.sleep(200);
-
// record a few things for posterity
log.info("------------------ VM Info ------------------");
log.info("-- OS Name: " + System.getProperty("os.name"));
protected JFrame _frame;
};
- /*
- log.warning("Startup file?",
- "paramstring", '"'+getStartupFilesParameterString()+'"',
- "isWindows", LaunchUtil.isWindows(),
- "argv.length", argv.length,
- "argv[0]", argv.length>0?argv[0]:"NULL",
- "argv[1]", argv.length>1?argv[1]:"NULL",
- "argv[2]", argv.length>2?argv[2]:"NULL",
- "argv[3]", argv.length>3?argv[3]:"NULL"
- );
- */
- if (getStartupFilesParameterString() != null && getStartupFilesParameterString().length() > 0) {
- app.setStartupFilesFromParameterString(getStartupFilesParameterString());
- } else if (
- getStartupFilesParameterString().length() == 0
- && LaunchUtil.isWindows()
- && argv.length >= 3
- && argv[0].equals(".")
- && argv[1].equals("noappid")
- && argv[2].endsWith("."+Application.locatorFileExtension)
- ) {
- log.info("Jalview Version Locator in args: "+argv[2]);
- app.setStartupFilesFromParameterString(argv[2]);
- String[] newArgv = new String[argv.length - 1];
- System.arraycopy(argv, 0, newArgv, 0, 2);
- System.arraycopy(argv, 3, newArgv, 2, argv.length - 3);
- argv = newArgv;
+
+ String startupFile = getStartupFilesParameterString();
+ if (!StringUtil.isBlank(startupFile)) {
+ Application.setStartupFilesFromParameterString(startupFile);
}
+
app.start();
return app;
}
--- /dev/null
+mv clean package -Dgetdown.host.whitelist=jalview.org,*.jalview.org && cp launcher/target/getdown-launcher-1.8.3-SNAPSHOT.jar ../../../getdown/lib/getdown-launcher.jar && cp core/target/getdown-core-1.8.3-SNAPSHOT.jar ../../../getdown/lib/getdown-core-1.8.3-SNAPSHOT.jar && cp core/target/getdown-core-1.8.3-SNAPSHOT.jar ../../../j8lib/getdown-core.jar && cp core/target/getdown-core-1.8.3-SNAPSHOT.jar ../../../j11lib/getdown-core.jar
APPLICATIONS=/Applications
CHANNEL=NOCHANNEL
-DMG=build/install4j/11/Jalview-OFFLINE_macos-app_DEVELOPMENT-j11.dmg
+DMG=build/install4j/1.8/Jalview-OFFLINE_macos-app_DEVELOPMENT-j8.dmg
-gradle installers -Pgetdown_channel_name=NOCHANNEL -Pinstall4jMediaTypes=macosArchive -Pgetdown_local=true
+if [ $1 != "nogradle" ]; then
+ gradle installers -Pgetdown_channel_name=NOCHANNEL -Pinstall4jMediaTypes=macosArchive -Pgetdown_local=true -Pdev=true
+else
+ echo "Not running gradle installers"
+fi
if [ $? = 0 ]; then
umount "/Volumes/$INSTALLERVOL"
<file name="Jalview.app/Contents/Resources/Jalview-Version-Locator.icns" file="Jalview-Version-Locator.icns" />
</topLevelFiles>
</macosArchive>
- <windows name="Network Windows" id="1272" customizedId="" mediaFileName="${compiler:sys.shortName}-NETWORK_${compiler:sys.platform}_${compiler:sys.version}-j$$JAVA_INTEGER_VERSION$$" installDir="${compiler:sys.shortName}" overridePrincipalLanguage="false" jreBitType="64" runPostProcessor="true" postProcessor="${compiler:JSIGN_SH} $EXECUTABLE" failOnPostProcessorError="false" useLegacyMediaFileIds="false" legacyMediaFileIds="" downloadURL="" includeAllDownloadableComponents="false" includedJRE="$$WINDOWS_JAVA_VM_TGZ$$" manualJREEntry="true" bundleType="1" jreURL="" jreShared="false" directDownload="false" installOnlyIfNecessary="false" customInstallBaseDir="~/AppData/Local" contentFilesType="1" verifyIntegrity="true">
- <excludedComponents>
- <component id="1031" />
- <component id="1155" />
- <component id="1156" />
- </excludedComponents>
- <includedDownloadableComponents />
- <excludedLaunchers>
- <launcher id="737" />
- </excludedLaunchers>
- <excludedBeans />
- <overriddenPrincipalLanguage id="en" customLocalizationFile="" />
- <exclude>
- <entry location=".i4j_fileset_734" fileType="regular" />
- <entry location=".i4j_fileset_880" fileType="regular" />
- <entry location=".i4j_fileset_882" fileType="regular" />
- </exclude>
- <variables />
- <autoUpdate useMinUpdatableVersion="false" minUpdatableVersion="" useMaxUpdatableVersion="false" maxUpdatableVersion="">
- <commentFiles />
- <customAttributes />
- </autoUpdate>
- </windows>
<macosArchive name="Network macOS Single Bundle Archive" id="1274" customizedId="" mediaFileName="${compiler:sys.shortName}-NETWORK_${compiler:sys.platform}-app_${compiler:sys.version}-j$$JAVA_INTEGER_VERSION$$" installDir="${compiler:sys.shortName}" overridePrincipalLanguage="false" jreBitType="all" runPostProcessor="false" postProcessor="" failOnPostProcessorError="false" useLegacyMediaFileIds="false" legacyMediaFileIds="" downloadURL="" includeAllDownloadableComponents="true" includedJRE="" manualJREEntry="false" archiveType="dmg" volumeName="${compiler:sys.shortName} Installer" launcherId="1402">
<excludedComponents>
<component id="1031" />
<customAttributes />
</autoUpdate>
</unixArchive>
+ <windows name="Network Windows" id="1862" customizedId="" mediaFileName="${compiler:sys.shortName}-NETWORK_${compiler:sys.platform}_${compiler:sys.version}-j$$JAVA_INTEGER_VERSION$$" installDir="${compiler:sys.shortName}" overridePrincipalLanguage="false" jreBitType="64" runPostProcessor="true" postProcessor="${compiler:JSIGN_SH} $EXECUTABLE" failOnPostProcessorError="false" useLegacyMediaFileIds="false" legacyMediaFileIds="" downloadURL="" includeAllDownloadableComponents="false" includedJRE="$$WINDOWS_JAVA_VM_TGZ$$" manualJREEntry="true" bundleType="1" jreURL="" jreShared="false" directDownload="false" installOnlyIfNecessary="false" customInstallBaseDir="~/AppData/Local" contentFilesType="1" verifyIntegrity="true">
+ <excludedComponents>
+ <component id="1031" />
+ <component id="1155" />
+ <component id="1156" />
+ </excludedComponents>
+ <includedDownloadableComponents />
+ <excludedLaunchers>
+ <launcher id="737" />
+ </excludedLaunchers>
+ <excludedBeans />
+ <overriddenPrincipalLanguage id="en" customLocalizationFile="" />
+ <exclude>
+ <entry location=".i4j_fileset_734" fileType="regular" />
+ <entry location=".i4j_fileset_880" fileType="regular" />
+ </exclude>
+ <variables />
+ <autoUpdate useMinUpdatableVersion="false" minUpdatableVersion="" useMaxUpdatableVersion="false" maxUpdatableVersion="">
+ <commentFiles />
+ <customAttributes />
+ </autoUpdate>
+ </windows>
</mediaSets>
<buildIds buildAll="true">
<mediaSet refId="153" />
<mediaSet refId="570" />
<mediaSet refId="743" />
<mediaSet refId="878" />
- <mediaSet refId="1272" />
<mediaSet refId="1274" />
<mediaSet refId="1595" />
<mediaSet refId="1596" />
- <mediaSet refId="1695" />
+ <mediaSet refId="1862" />
</buildIds>
<buildOptions verbose="false" faster="false" disableSigning="false" disableJreBundling="false" debug="false" />
</install4j>