JAL-3446 unintentially left training message in code.
[jalview.git] / src / jalview / bin / Jalview.java
index ac44bfe..36b5ea3 100755 (executable)
@@ -20,6 +20,7 @@
  */
 package jalview.bin;
 
+import java.awt.GraphicsEnvironment;
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileOutputStream;
@@ -48,7 +49,6 @@ import com.threerings.getdown.util.LaunchUtil;
 import groovy.lang.Binding;
 import groovy.util.GroovyScriptEngine;
 import jalview.api.AlignCalcWorkerI;
-import jalview.api.JalviewJSApp;
 import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
 import jalview.ext.so.SequenceOntology;
 import jalview.gui.AlignFrame;
@@ -73,7 +73,6 @@ import jalview.schemes.ColourSchemeProperty;
 import jalview.util.MessageManager;
 import jalview.util.Platform;
 import jalview.ws.jws2.Jws2Discoverer;
-//import netscape.javascript.JSObject;
 
 /**
  * Main class for Jalview Application <br>
@@ -298,6 +297,8 @@ public class Jalview implements ApplicationSingletonI
 
     Cache.loadProperties(usrPropsFile); // must do this before
 
+    boolean allowServices = true;
+    
     if (isJS)
     {
       j2sAppletID = Platform.getAppID(null);
@@ -325,11 +326,20 @@ public class Jalview implements ApplicationSingletonI
         showUsage();
         System.exit(0);
       }
-      // ?>>
+      // BH note: Only -nodisplay is official; others are deprecated?
       if (aparser.contains("nodisplay") || aparser.contains("nogui")
-              || aparser.contains("headless"))
+              || aparser.contains("headless")
+              || GraphicsEnvironment.isHeadless())
+      {
+        if (!isJS) {
+          // BH Definitely not a good idea in JavaScript; 
+          // probably should not be here for Java, either.  
+          System.setProperty("java.awt.headless", "true");
+        }
+        headless = true;
+      }
+      if (GraphicsEnvironment.isHeadless())
       {
-        System.setProperty("java.awt.headless", "true");
         headless = true;
       }
       // <<?
@@ -337,7 +347,8 @@ public class Jalview implements ApplicationSingletonI
       // anything else!
 
       final String jabawsUrl = aparser.getValue(ArgsParser.JABAWS);
-      if (jabawsUrl != null)
+      allowServices = !("none".equals(jabawsUrl));
+      if (allowServices && jabawsUrl != null)
       {
         try
         {
@@ -370,11 +381,6 @@ public class Jalview implements ApplicationSingletonI
       }
       defs = aparser.getValue("setprop");
     }
-    if (System.getProperty("java.awt.headless") != null
-            && System.getProperty("java.awt.headless").equals("true"))
-    {
-      headless = true;
-    }
     System.setProperty("http.agent",
             "Jalview Desktop/" + Cache.getDefault("VERSION", "Unknown"));
     try
@@ -388,8 +394,6 @@ public class Jalview implements ApplicationSingletonI
       System.exit(0);
     }
 
-    desktop = null;
-
     if (!isJS)
     /** @j2sIgnore */
     {
@@ -450,6 +454,8 @@ public class Jalview implements ApplicationSingletonI
       SequenceOntologyFactory.setSequenceOntology(new SequenceOntology());
     }
 
+
+    desktop = null;
     if (!headless)
     {
       desktop = Desktop.getInstance();
@@ -470,7 +476,8 @@ public class Jalview implements ApplicationSingletonI
        * @j2sIgnore
        */
       {
-        desktop.startServiceDiscovery();
+        if (allowServices)
+          desktop.startServiceDiscovery();
         if (!aparser.contains("nousagestats"))
         {
           startUsageStats(desktop);
@@ -526,9 +533,11 @@ public class Jalview implements ApplicationSingletonI
   }
 
   /**
-   * Parse all command-line String[] arguments as well as all JavaScript-derived parameters from Info.
+   * Parse all command-line String[] arguments as well as all JavaScript-derived
+   * parameters from Info.
    * 
-   * We allow for this method to be run from JavaScript. Basically allowing simple scripting.
+   * We allow for this method to be run from JavaScript. Basically allowing
+   * simple scripting.
    * 
    * @param aparser
    * @param isStartup
@@ -574,6 +583,8 @@ public class Jalview implements ApplicationSingletonI
       System.exit(1);
     }
 
+    setDisplayParameters(aparser);
+    
     // time to open a file.
 
     long progress = -1;
@@ -581,10 +592,67 @@ public class Jalview implements ApplicationSingletonI
     FileLoader fileLoader = new FileLoader(!headless);
     FileFormatI format = null;
     // Finally, deal with the remaining input data.
-    JalviewJSApp jsApp = null;
     AlignFrame af = null;
 
-    if (file != null)
+    JalviewJSApp jsApp = (isJS ? new JalviewJSApp(this, aparser) : null);
+
+    if (file == null)
+    {
+      if (isJS)
+      {
+        // JalviewJS allows sequence1 sequence2 ....
+        
+      }
+      else if (!headless && Cache.getDefault("SHOW_STARTUP_FILE", true))
+      /**
+       * Java only
+       * 
+       * @j2sIgnore
+       */
+      {
+
+        // We'll only open the default file if the desktop is visible.
+        // And the user
+        // ////////////////////
+
+        file = Cache.getDefault("STARTUP_FILE",
+                Cache.getDefault("www.jalview.org",
+                        "http://www.jalview.org")
+                        + "/examples/exampleFile_2_7.jar");
+        if (file.equals(
+                "http://www.jalview.org/examples/exampleFile_2_3.jar"))
+        {
+          // hardwire upgrade of the startup file
+          file.replace("_2_3.jar", "_2_7.jar");
+          // and remove the stale setting
+          Cache.removeProperty("STARTUP_FILE");
+        }
+
+        protocol = DataSourceType.FILE;
+
+        if (file.indexOf("http:") > -1)
+        {
+          protocol = DataSourceType.URL;
+        }
+
+        if (file.endsWith(".jar"))
+        {
+          format = FileFormat.Jalview;
+        }
+        else
+        {
+          try
+          {
+            format = new IdentifyFile().identify(file, protocol);
+          } catch (FileFormatException e)
+          {
+            // TODO what?
+          }
+        }
+        af = fileLoader.LoadFileWaitTillLoaded(file, protocol, format);
+      }
+    }
+    else
     {
       if (!headless)
       {
@@ -615,6 +683,7 @@ public class Jalview implements ApplicationSingletonI
           }
         }
       }
+      
       String fileFormat = (isJS
               ? (String) aparser.getAppletValue("format", null, true)
               : null);
@@ -633,35 +702,11 @@ public class Jalview implements ApplicationSingletonI
         // TODO ?
       }
 
-      if (aparser.contains(ArgsParser.NOMENUBAR))
-      {
-        noMenuBar = true;
-        System.out.println("CMD [nomenu] executed successfully!");
-      }
-
-      if (aparser.contains(ArgsParser.NOSTATUS))
-      {
-        noStatus = true;
-        System.out.println("CMD [nostatus] executed successfully!");
-      }
-
-      if (aparser.contains(ArgsParser.NOANNOTATION)
-              || aparser.contains(ArgsParser.NOANNOTATION2))
-      {
-        noAnnotation = true;
-        System.out.println("CMD no-annotation executed successfully!");
-      }
-      if (aparser.contains(ArgsParser.NOCALCULATION))
-      {
-        noCalculation = true;
-        System.out.println("CMD [nocalculation] executed successfully!");
-      }
-
       af = new FileLoader(!headless).LoadFileWaitTillLoaded(file, protocol,
               format);
       if (af == null)
       {
-        System.out.println("error");
+        System.out.println("jalview error - AlignFrame was not created");
       }
       else
       {
@@ -696,134 +741,11 @@ public class Jalview implements ApplicationSingletonI
         }
         setCurrentAlignFrame(af);
 
-        String data = aparser.getValue(ArgsParser.COLOUR, true);
-        if (data != null)
-        {
-          data.replaceAll("%20", " ");
-
-          ColourSchemeI cs = ColourSchemeProperty.getColourScheme(
-                  af.getViewport(), af.getViewport().getAlignment(), data);
-
-          if (cs != null)
-          {
-            System.out.println(
-                    "CMD [-color " + data + "] executed successfully!");
-          }
-          af.changeColour(cs);
-        }
-
-        // Must maintain ability to use the groups flag
-        data = aparser.getValue(ArgsParser.GROUPS, true);
-        if (data != null)
-        {
-          af.parseFeaturesFile(data,
-                  AppletFormatAdapter.checkProtocol(data));
-          // System.out.println("Added " + data);
-          System.out.println(
-                  "CMD groups[-" + data + "]  executed successfully!");
-        }
-        data = aparser.getValue(ArgsParser.FEATURES, true);
-        if (data != null)
-        {
-          af.parseFeaturesFile(data,
-                  AppletFormatAdapter.checkProtocol(data));
-          // System.out.println("Added " + data);
-          System.out.println(
-                  "CMD [-features " + data + "]  executed successfully!");
-        }
-        data = aparser.getValue(ArgsParser.ANNOTATIONS, true);
-        if (data != null)
-        {
-          af.loadJalviewDataFile(data, null, null, null);
-          // System.out.println("Added " + data);
-          System.out.println(
-                  "CMD [-annotations " + data + "] executed successfully!");
-        }
-
-        // JavaScript feature
-
-        if (aparser.contains(ArgsParser.SHOWOVERVIEW))
-        {
-          af.overviewMenuItem_actionPerformed(null);
-          System.out.println("CMD [showoverview] executed successfully!");
-        }
-
-        // set or clear the sortbytree flag.
-        if (aparser.contains(ArgsParser.SORTBYTREE))
-        {
-          af.getViewport().setSortByTree(true);
-          if (af.getViewport().getSortByTree())
-          {
-            System.out.println("CMD [-sortbytree] executed successfully!");
-          }
-        }
-
-        boolean doUpdateAnnotation = false;
-        /**
-         * we do this earlier in JalviewJS because of a complication with
-         * SHOWOVERVIEW
-         * 
-         * For now, just fixing this in JalviewJS.
-         *
-         * 
-         * @j2sIgnore
-         * 
-         */
-        {
-          if (aparser.contains(ArgsParser.NOANNOTATION)
-                  || aparser.contains(ArgsParser.NOANNOTATION2))
-          {
-            af.getViewport().setShowAnnotation(false);
-            if (!af.getViewport().isShowAnnotation())
-            {
-              doUpdateAnnotation = true;
-              System.out
-                      .println("CMD no-annotation executed successfully!");
-            }
-          }
-        }
-
-        if (aparser.contains(ArgsParser.NOSORTBYTREE))
-        {
-          af.getViewport().setSortByTree(false);
-          if (!af.getViewport().getSortByTree())
-          {
-            doUpdateAnnotation = true;
-            System.out
-                    .println("CMD [-nosortbytree] executed successfully!");
-          }
-        }
-        if (doUpdateAnnotation)
-        { // BH 2019.07.24
-          af.setMenusForViewport();
-          af.alignPanel.updateLayout();
-        }
-
-        data = aparser.getValue(ArgsParser.TREE, true);
-        if (data != null)
-        {
-          try
-          {
-            NewickFile nf = new NewickFile(data,
-                    AppletFormatAdapter.checkProtocol(data));
-            af.getViewport()
-                    .setCurrentTree(af.showNewickTree(nf, data).getTree());
-            System.out.println(
-                    "CMD [-tree " + data + "] executed successfully!");
-          } catch (IOException ex)
-          {
-            System.err.println("Couldn't add tree " + data);
-            ex.printStackTrace(System.err);
-          }
-        }
-        // TODO - load PDB structure(s) to alignment JAL-629
-        // (associate with identical sequence in alignment, or a specified
-        // sequence)
-
+        setFrameDependentProperties(aparser, af);
+        
         if (isJS)
         {
-          jsApp = new JalviewJSApp(aparser);
-          jsApp.load(af);
+          jsApp.initFromParams(af);
         }
         else
         /**
@@ -843,61 +765,10 @@ public class Jalview implements ApplicationSingletonI
                     + "] executed successfully!");
             groovyscript = null;
           }
-          createOutputFiles(aparser, af, format);
         }
-      }
-    }
-    else
-    {
-      if (!isJS && !headless && Cache.getDefault("SHOW_STARTUP_FILE", true))
-      /**
-       * Java only
-       * 
-       * @j2sIgnore
-       */
-      {
-
-        // We'll only open the default file if the desktop is visible.
-        // And the user
-        // ////////////////////
-
-        file = Cache.getDefault("STARTUP_FILE",
-                Cache.getDefault("www.jalview.org",
-                        "http://www.jalview.org")
-                        + "/examples/exampleFile_2_7.jar");
-        if (file.equals(
-                "http://www.jalview.org/examples/exampleFile_2_3.jar"))
-        {
-          // hardwire upgrade of the startup file
-          file.replace("_2_3.jar", "_2_7.jar");
-          // and remove the stale setting
-          Cache.removeProperty("STARTUP_FILE");
-        }
-
-        protocol = DataSourceType.FILE;
-
-        if (file.indexOf("http:") > -1)
-        {
-          protocol = DataSourceType.URL;
-        }
-
-        if (file.endsWith(".jar"))
-        {
-          format = FileFormat.Jalview;
-        }
-        else
-        {
-          try
-          {
-            format = new IdentifyFile().identify(file, protocol);
-          } catch (FileFormatException e)
-          {
-            // TODO what?
-          }
+        if (!isJS || !isStartup) {
+          createOutputFiles(aparser, format);
         }
-
-        af = fileLoader.LoadFileWaitTillLoaded(file, protocol, format);
-
       }
     }
     // extract groovy arguments before anything else.
@@ -926,13 +797,170 @@ public class Jalview implements ApplicationSingletonI
       }
       desktop.setInBatchMode(false);
     }
-
-    if (isJS && isStartup)
-    {
+    
+    if (jsApp != null) {
       jsApp.callInitCallback();
     }
   }
   
+  /**
+   * Set general display parameters irrespective of file loading or headlessness.
+   * 
+   * @param aparser
+   */
+  private void setDisplayParameters(ArgsParser aparser)
+  {
+    if (aparser.contains(ArgsParser.NOMENUBAR))
+    {
+      noMenuBar = true;
+      System.out.println("CMD [nomenu] executed successfully!");
+    }
+
+    if (aparser.contains(ArgsParser.NOSTATUS))
+    {
+      noStatus = true;
+      System.out.println("CMD [nostatus] executed successfully!");
+    }
+
+    if (aparser.contains(ArgsParser.NOANNOTATION)
+            || aparser.contains(ArgsParser.NOANNOTATION2))
+    {
+      noAnnotation = true;
+      System.out.println("CMD no-annotation executed successfully!");
+    }
+    if (aparser.contains(ArgsParser.NOCALCULATION))
+    {
+      noCalculation = true;
+      System.out.println("CMD [nocalculation] executed successfully!");
+    }
+  }
+
+
+  private void setFrameDependentProperties(ArgsParser aparser,
+          AlignFrame af)
+  {
+    String data = aparser.getValue(ArgsParser.COLOUR, true);
+    if (data != null)
+    {
+      data.replaceAll("%20", " ");
+
+      ColourSchemeI cs = ColourSchemeProperty.getColourScheme(
+              af.getViewport(), af.getViewport().getAlignment(), data);
+
+      if (cs != null)
+      {
+        System.out.println(
+                "CMD [-color " + data + "] executed successfully!");
+      }
+      af.changeColour(cs);
+    }
+
+    // Must maintain ability to use the groups flag
+    data = aparser.getValue(ArgsParser.GROUPS, true);
+    if (data != null)
+    {
+      af.parseFeaturesFile(data,
+              AppletFormatAdapter.checkProtocol(data));
+      // System.out.println("Added " + data);
+      System.out.println(
+              "CMD groups[-" + data + "]  executed successfully!");
+    }
+    data = aparser.getValue(ArgsParser.FEATURES, true);
+    if (data != null)
+    {
+      af.parseFeaturesFile(data,
+              AppletFormatAdapter.checkProtocol(data));
+      // System.out.println("Added " + data);
+      System.out.println(
+              "CMD [-features " + data + "]  executed successfully!");
+    }
+    data = aparser.getValue(ArgsParser.ANNOTATIONS, true);
+    if (data != null)
+    {
+      af.loadJalviewDataFile(data, null, null, null);
+      // System.out.println("Added " + data);
+      System.out.println(
+              "CMD [-annotations " + data + "] executed successfully!");
+    }
+
+    // JavaScript feature
+
+    if (aparser.contains(ArgsParser.SHOWOVERVIEW))
+    {
+      af.overviewMenuItem_actionPerformed(null);
+      System.out.println("CMD [showoverview] executed successfully!");
+    }
+
+    // set or clear the sortbytree flag.
+    if (aparser.contains(ArgsParser.SORTBYTREE))
+    {
+      af.getViewport().setSortByTree(true);
+      if (af.getViewport().getSortByTree())
+      {
+        System.out.println("CMD [-sortbytree] executed successfully!");
+      }
+    }
+
+    boolean doUpdateAnnotation = false;
+    /**
+     * we do this earlier in JalviewJS because of a complication with
+     * SHOWOVERVIEW
+     * 
+     * For now, just fixing this in JalviewJS.
+     *
+     * 
+     * @j2sIgnore
+     * 
+     */
+    {
+      if (noAnnotation)
+      {
+        af.getViewport().setShowAnnotation(false);
+        if (!af.getViewport().isShowAnnotation())
+        {
+          doUpdateAnnotation = true;
+        }
+      }
+    }
+
+    if (aparser.contains(ArgsParser.NOSORTBYTREE))
+    {
+      af.getViewport().setSortByTree(false);
+      if (!af.getViewport().getSortByTree())
+      {
+        doUpdateAnnotation = true;
+        System.out
+                .println("CMD [-nosortbytree] executed successfully!");
+      }
+    }
+    if (doUpdateAnnotation)
+    { // BH 2019.07.24
+      af.setMenusForViewport();
+      af.alignPanel.updateLayout();
+    }
+
+    data = aparser.getValue(ArgsParser.TREE, true);
+    if (data != null)
+    {
+      try
+      {
+        NewickFile nf = new NewickFile(data,
+                AppletFormatAdapter.checkProtocol(data));
+        af.getViewport()
+                .setCurrentTree(af.showNewickTree(nf, data).getTree());
+        System.out.println(
+                "CMD [-tree " + data + "] executed successfully!");
+      } catch (IOException ex)
+      {
+        System.err.println("Couldn't add tree " + data);
+        ex.printStackTrace(System.err);
+      }
+    }
+    // TODO - load PDB structure(s) to alignment JAL-629
+    // (associate with identical sequence in alignment, or a specified
+    // sequence)
+
+  }
 
   /**
    * Writes an output file for each format (if any) specified in the
@@ -950,12 +978,11 @@ public class Jalview implements ApplicationSingletonI
    * corresponding alignment image output.
    * 
    * @param aparser
-   * @param af
    * @param format
    */
-  private void createOutputFiles(ArgsParser aparser, AlignFrame af,
-          FileFormatI format)
+  private void createOutputFiles(ArgsParser aparser, FileFormatI format)
   {
+    AlignFrame af = currentAlignFrame;
     while (aparser.getSize() >= 2)
     {
       String outputFormat = aparser.nextValue();
@@ -1007,29 +1034,52 @@ public class Jalview implements ApplicationSingletonI
         System.out.println(
                 "Creating image map: " + imageFile.getAbsolutePath());
         continue;
-      }
-      if (!Platform.isJS()) /** @j2sIgnore */
-      {
-        // skipping outputFormat?
-        System.out.println("Unknown arg: " + outputFormat);      
-        fname = new File(aparser.nextValue()).getAbsolutePath();
-        af.saveAlignment(fname, format);
-        if (af.isSaveAlignmentSuccessful())
+      default:
+        // fall through - try to parse as an alignment data export format
+        FileFormatI outFormat = null;
+        try
+        {
+          outFormat = FileFormats.getInstance().forName(outputFormat);
+        } catch (Exception formatP)
+        {
+        }
+        if (outFormat == null)
+        {
+          System.out.println("Couldn't parse " + outputFormat
+                  + " as a valid Jalview format string.");
+          continue;
+        }
+        if (!outFormat.isWritable())
         {
           System.out.println(
-                  "Written alignment in " + format + " format to " + fname);
+                  "This version of Jalview does not support alignment export as "
+                          + outputFormat);
+          continue;
+        }
+        // record file as it was passed to Jalview so it is recognisable to the CLI
+        // caller
+        String file;
+        fname = new File(file = aparser.nextValue()).getAbsolutePath();
+        // JBPNote - yuck - really wish we did have a bean returned from this which gave
+        // success/fail like before !
+        af.saveAlignment(fname, outFormat);
+        if (!af.isSaveAlignmentSuccessful())
+        {
+          System.out.println("Written alignment in " + outputFormat
+                  + " format to " + file);
+          continue;
         }
         else
         {
-          System.out.println("Error writing file " + fname + " in " + format
-                  + " format!!");
+          System.out.println("Error writing file " + file + " in "
+                  + outputFormat + " format!!");
         }
       }
-      break;
     }
+    // ??? Should report - 'ignoring' extra args here...
     while (aparser.getSize() > 0)
     {
-      System.out.println("Unknown arg: " + aparser.nextValue());
+      System.out.println("Ignoring extra argument: " + aparser.nextValue());
     }
   }
 
@@ -1272,5 +1322,18 @@ public class Jalview implements ApplicationSingletonI
     // System.out.println("Jalview worker " + worker.getClass().getSimpleName()
     // + " " + status);
   }
-  
+
+
+  private static boolean isInteractive = true;
+
+  public static boolean isInteractive()
+  {
+    return isInteractive;
+  }
+
+  public static void setInteractive(boolean tf)
+  {
+    isInteractive = tf;
+  }
+
 }