JAL-4409 Added multiple file open to getdown. Added URL source of JVL file ability...
authorBen Soares <b.soares@dundee.ac.uk>
Thu, 16 May 2024 19:01:01 +0000 (20:01 +0100)
committerBen Soares <b.soares@dundee.ac.uk>
Thu, 16 May 2024 19:01:01 +0000 (20:01 +0100)
getdown/lib/getdown-core.jar
getdown/lib/getdown-launcher-local.jar
getdown/lib/getdown-launcher.jar
getdown/src/getdown/core/src/main/java/com/threerings/getdown/data/Application.java
getdown/src/getdown/core/src/main/java/com/threerings/getdown/util/Config.java
getdown/src/getdown/launcher/src/main/java/com/threerings/getdown/launcher/GetdownApp.java
getdown/src/getdown/launcher/src/main/java/jalview/bin/StartupNotificationListener.java
j11lib/getdown-core.jar
j8lib/getdown-core.jar

index c779464..ec5ed62 100644 (file)
Binary files a/getdown/lib/getdown-core.jar and b/getdown/lib/getdown-core.jar differ
index 11af9c3..fd0b206 100644 (file)
Binary files a/getdown/lib/getdown-launcher-local.jar and b/getdown/lib/getdown-launcher-local.jar differ
index fe23090..1c7f42f 100644 (file)
Binary files a/getdown/lib/getdown-launcher.jar and b/getdown/lib/getdown-launcher.jar differ
index 408e9fa..202c30d 100644 (file)
@@ -11,8 +11,8 @@ import java.net.MalformedURLException;
 import java.net.Proxy;
 import java.net.SocketAddress;
 import java.net.InetSocketAddress;
-import java.net.URI;
-import java.net.URISyntaxException;
+//#####import java.net.URI;
+//#####import java.net.URISyntaxException;
 import java.net.URL;
 import java.net.URLClassLoader;
 import java.net.URLConnection;
@@ -1197,9 +1197,8 @@ public class Application
         }
 
         // almost finally check the startup file arguments
-        for (File f : _startupFiles) {
-          _appargs.add(f.getAbsolutePath());
-          break; // Only add one file to open
+        for (String f : _startupFiles) {
+          _appargs.add(HttpUtils.startsWithHttpOrHttps(f)?f:new File(f).getAbsolutePath());
         }
         
         // check if one arg with recognised extension
@@ -1936,59 +1935,67 @@ public class Application
     {
         return new File(appdir, path);
     }
-
-    public static void setStartupFilesFromParameterString(String p) {
+    
+    public static void setStartupFilesFromParameters(List<String> parameters) {
+      log.info("##### Filenames = '"+parameters.toString()+"'");
       // 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(Locale.ROOT).endsWith("."+Application.LOCATOR_FILE_EXTENSION)) {
-          if (HttpUtils.isJalviewSchemeUri(locatorFilename)) {
-            locatorFilename = HttpUtils.equivalentJalviewUrl(locatorFilename);
+      for (String p: parameters) {
+        if (!StringUtil.isBlank(p)) {
+          String filename;
+          // split quoted params or treat as single string array
+          if (p.startsWith(q) && p.endsWith(q)) {
+            filename = p.substring(q.length(),p.length()-q.length());
+          } else {
+            // single unquoted filename
+            filename = p;
+          }
+          
+          // convert jalviewX://... URLs
+          if (HttpUtils.isJalviewSchemeUri(filename)) {
+            filename = HttpUtils.equivalentJalviewUrl(filename);
           }
-          log.info("##### SETTING LOCATORFILENAME '"+ locatorFilename +"'");
-
-          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(Locale.ROOT).endsWith("."+Application.LOCATOR_FILE_EXTENSION)) {
-            if (HttpUtils.isJalviewSchemeUri(filename)) {
-              filename = HttpUtils.equivalentJalviewUrl(filename);
-            }
+          // check for locator file.  Only allow one locator file to be double clicked (if multiple files opened, ignore locator files)
+          if (filename.toLowerCase(Locale.ROOT).endsWith("."+Application.LOCATOR_FILE_EXTENSION)) {
+            log.info("##### SETTING LOCATORFILENAME '"+ filename +"'");
+            setLocatorFile(filename);
+          } else {
+            // skip any other locator files in a multiple file list
             log.info("##### ADDING FILENAME '"+ filename +"'");
             addStartupFile(filename);
           }
         }
       }
     }
-    
+        
+    public static String getStartupFilesParameterString(List<String> parameters, boolean changeJalviewSchemeUris) {
+      StringBuilder sb = new StringBuilder();
+      boolean first = true;
+      for(String f : parameters) {
+        if (first) {
+          first = false;
+        } else {
+          sb.append(' ');
+        }
+        String p = changeJalviewSchemeUris && HttpUtils.isJalviewSchemeUri(f) ? HttpUtils.equivalentJalviewUrl(f) : f;
+        if (p.contains(" ")) {
+          sb.append('"');
+          sb.append(p);
+          sb.append('"');
+        } else {
+          sb.append(p);
+        }
+      }
+      return sb.toString();
+    }
+
     public static void setLocatorFile(String filename) {
-      _locatorFile = new File(filename);
+      _locatorFile = filename;
     }
     
     public static void addStartupFile(String filename) {
-      _startupFiles.add(new File(filename));
+      _startupFiles.add(filename);
     }
     
     public static void setJalviewUri(String uri) {
@@ -2005,8 +2012,17 @@ public class Application
       try {
         Config tmpConfig = null;
         Map<String, Object> tmpData = new HashMap<>();
-        if (_locatorFile.exists()) {
-          tmpConfig = Config.parseConfig(_locatorFile,  opts);
+        if (HttpUtils.startsWithHttpOrHttps(_locatorFile)) {
+          URL locatorUrl = new URL(_locatorFile);
+          try (InputStream in = ConnectionUtil.open(proxy, locatorUrl, 0, 0).getInputStream();
+                 InputStreamReader reader = new InputStreamReader(in, UTF_8);
+                 BufferedReader bin = new BufferedReader(reader)) {
+                   tmpConfig = Config.parseConfig(bin, opts);
+          }
+        } else if (new File(_locatorFile).exists()) {
+          tmpConfig = Config.parseConfig(new File(_locatorFile),  opts);
+        }
+        if (tmpConfig != null) {
           // appbase is sanitised in HostWhitelist
           Map<String, Object> tmpConfigData = tmpConfig.getData();
           if (tmpConfig != null) {
@@ -2103,8 +2119,8 @@ public class Application
     protected static final String ENV_VAR_PREFIX = "%ENV.";
     protected static final Pattern ENV_VAR_PATTERN = Pattern.compile("%ENV\\.(.*?)%");
  
-    protected static File _locatorFile;
-    protected static List<File> _startupFiles = new ArrayList<>();
+    protected static String _locatorFile;
+    protected static List<String> _startupFiles = new ArrayList<>();
     protected static String _jalviewUri;
     public static final String LOCATOR_FILE_EXTENSION = "jvl";
 
index c7e2933..8bff8ef 100644 (file)
@@ -5,9 +5,13 @@
 
 package com.threerings.getdown.util;
 
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.Reader;
 import java.net.MalformedURLException;
@@ -174,38 +178,75 @@ public class Config
      * one key/value pair in the config file was associated with the same key.
      */
     public static Config parseConfig (File source, ParseOpts opts)
-        throws IOException
-    {
-        Map<String, Object> data = new HashMap<>();
-
-        // I thought that we could use HashMap<String, String[]> and put new String[] {pair[1]} for
-        // the null case, but it mysteriously dies on launch, so leaving it as HashMap<String,
-        // Object> for now
-        for (String[] pair : parsePairs(source, opts)) {
-            Object value = data.get(pair[0]);
-            if (value == null) {
-                data.put(pair[0], pair[1]);
-            } else if (value instanceof String) {
-                data.put(pair[0], new String[] { (String)value, pair[1] });
-            } else if (value instanceof String[]) {
-                String[] values = (String[])value;
-                String[] nvalues = new String[values.length+1];
-                System.arraycopy(values, 0, nvalues, 0, values.length);
-                nvalues[values.length] = pair[1];
-                data.put(pair[0], nvalues);
+            throws IOException
+        {
+            Map<String, Object> data = new HashMap<>();
+
+            // I thought that we could use HashMap<String, String[]> and put new String[] {pair[1]} for
+            // the null case, but it mysteriously dies on launch, so leaving it as HashMap<String,
+            // Object> for now
+            for (String[] pair : parsePairs(source, opts)) {
+                Object value = data.get(pair[0]);
+                if (value == null) {
+                    data.put(pair[0], pair[1]);
+                } else if (value instanceof String) {
+                    data.put(pair[0], new String[] { (String)value, pair[1] });
+                } else if (value instanceof String[]) {
+                    String[] values = (String[])value;
+                    String[] nvalues = new String[values.length+1];
+                    System.arraycopy(values, 0, nvalues, 0, values.length);
+                    nvalues[values.length] = pair[1];
+                    data.put(pair[0], nvalues);
+                }
+            }
+
+            // special magic for the getdown.txt config: if the parsed data contains 'strict_comments =
+            // true' then we reparse the file with strict comments (i.e. # is only assumed to start a
+            // comment in column 0)
+            if (!opts.strictComments && Boolean.parseBoolean((String)data.get("strict_comments"))) {
+                opts.strictComments = true;
+                return parseConfig(source, opts);
             }
-        }
 
-        // special magic for the getdown.txt config: if the parsed data contains 'strict_comments =
-        // true' then we reparse the file with strict comments (i.e. # is only assumed to start a
-        // comment in column 0)
-        if (!opts.strictComments && Boolean.parseBoolean((String)data.get("strict_comments"))) {
-            opts.strictComments = true;
-            return parseConfig(source, opts);
+            return new Config(data);
         }
 
-        return new Config(data);
-    }
+    public static Config parseConfig (Reader source, ParseOpts opts)
+            throws IOException
+        {
+            Map<String, Object> data = new HashMap<>();
+
+            // I thought that we could use HashMap<String, String[]> and put new String[] {pair[1]} for
+            // the null case, but it mysteriously dies on launch, so leaving it as HashMap<String,
+            // Object> for now
+            for (String[] pair : parsePairs(source, opts)) {
+                Object value = data.get(pair[0]);
+                if (value == null) {
+                    data.put(pair[0], pair[1]);
+                } else if (value instanceof String) {
+                    data.put(pair[0], new String[] { (String)value, pair[1] });
+                } else if (value instanceof String[]) {
+                    String[] values = (String[])value;
+                    String[] nvalues = new String[values.length+1];
+                    System.arraycopy(values, 0, nvalues, 0, values.length);
+                    nvalues[values.length] = pair[1];
+                    data.put(pair[0], nvalues);
+                }
+            }
+
+            // special magic for the getdown.txt config: if the parsed data contains 'strict_comments =
+            // true' then we reparse the file with strict comments (i.e. # is only assumed to start a
+            // comment in column 0)
+            if (!opts.strictComments && Boolean.parseBoolean((String)data.get("strict_comments"))) {
+                opts.strictComments = true;
+                System.err.println("##### About to reset reader");
+                source.reset();
+                System.err.println("##### Reset reader");
+                return parseConfig(source, opts);
+            }
+
+            return new Config(data);
+        }
 
     public Config (Map<String,  Object> data) {
         _data = data;
index 58cf8cd..31b2538 100644 (file)
@@ -42,7 +42,7 @@ import jalview.util.HttpUtils;
  */
 public class GetdownApp
 {
-  public static String startupFilesParameterString = "";
+  public static List<String> startupFilesParameters = new ArrayList<>();
   /**
    * The main entry point of the Getdown launcher application.
    */
@@ -121,8 +121,8 @@ public class GetdownApp
     log.info("-- User Home: " + System.getProperty("user.home"));
     log.info("-- Cur dir: " + System.getProperty("user.dir"));
     log.info("-- Launcher version: "+Build.version());
-    log.info("-- startupFilesParameterString: " + startupFilesParameterString);
-    log.info("-- getStartupFilesParameterString(): " + getStartupFilesParameterString());
+    log.info("-- startupFilesParameterString: " + getStartupFilesParameterString(getStartupFilesParameters(), false));
+    log.info("-- getStartupFilesParameterString(): " + getStartupFilesParameterString(getStartupFilesParameters(), true));
     log.info("---------------------------------------------");
 
     Getdown app = new Getdown(envc) {
@@ -286,23 +286,40 @@ public class GetdownApp
       protected JFrame _frame;
     };
     
-    String startupFile = getStartupFilesParameterString();
-    if (!StringUtil.isBlank(startupFile)) {
-      Application.setStartupFilesFromParameterString(startupFile);
+    if (getStartupFilesParameters().size() > 0) {
+      Application.setStartupFilesFromParameters(getStartupFilesParameters());
     }
  
     app.start();
     return app;
   }
   
-  public static void setStartupFilesParameterString(String parameters) {
-    startupFilesParameterString = parameters;
+  public static void addStartupFilesParameter(String parameter) {
+    startupFilesParameters.add(parameter);
   }
   
-  public static String getStartupFilesParameterString() {
-    if (HttpUtils.isJalviewSchemeUri(startupFilesParameterString)) {
-      return HttpUtils.equivalentJalviewUrl(startupFilesParameterString);
+  public static List<String> getStartupFilesParameters() {
+    return startupFilesParameters;
+  }
+  
+  public static String getStartupFilesParameterString(List<String> parameters, boolean changeJalviewSchemeUris) {
+    StringBuilder sb = new StringBuilder();
+    boolean first = true;
+    for(String f : parameters) {
+      if (first) {
+        first = false;
+      } else {
+        sb.append(' ');
+      }
+      String p = changeJalviewSchemeUris && HttpUtils.isJalviewSchemeUri(f) ? HttpUtils.equivalentJalviewUrl(f) : f;
+      if (p.contains(" ")) {
+        sb.append('"');
+        sb.append(p);
+        sb.append('"');
+      } else {
+        sb.append(p);
+      }
     }
-    return startupFilesParameterString;
+    return sb.toString();
   }
 }
index b3cfa9a..cb313c0 100644 (file)
@@ -13,9 +13,9 @@ public class StartupNotificationListener {
       com.install4j.api.launcher.StartupNotification.registerStartupListener(
         new com.install4j.api.launcher.StartupNotification.Listener() {
           @Override
-          public void startupPerformed(String parameters) { 
-            log.info("StartupNotification.Listener.startupPerformed: '"+parameters+"'");
-            GetdownApp.setStartupFilesParameterString(parameters);
+          public void startupPerformed(String parameter) { 
+            log.info("StartupNotification.Listener.startupPerformed: '"+parameter+"'");
+            GetdownApp.addStartupFilesParameter(parameter);
           }
         }
       );
index c779464..ec5ed62 100644 (file)
Binary files a/j11lib/getdown-core.jar and b/j11lib/getdown-core.jar differ
index c779464..ec5ed62 100644 (file)
Binary files a/j8lib/getdown-core.jar and b/j8lib/getdown-core.jar differ