Clover icon

Coverage Report

  1. Project Clover database Wed Dec 3 2025 15:58:31 GMT
  2. Package jalview.bin

File Jalview.java

 

Coverage histogram

../../img/srcFileCovDistChart6.png
37% of files have more coverage

Code metrics

346
734
49
3
2,131
1,664
304
0.41
14.98
16.33
6.2

Classes

Class Line # Actions
Jalview 124 721 300
0.527877752.8%
Jalview.FeatureFetcher 191 13 4
0.00%
Jalview.ExitCode 1896 0 0
-1.0 -
 

Contributing tests

This file is covered by 225 tests. .

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ The Jalview Authors
4    *
5    * This file is part of Jalview.
6    *
7    * Jalview is free software: you can redistribute it and/or
8    * modify it under the terms of the GNU General Public License
9    * as published by the Free Software Foundation, either version 3
10    * of the License, or (at your option) any later version.
11    *
12    * Jalview is distributed in the hope that it will be useful, but
13    * WITHOUT ANY WARRANTY; without even the implied warranty
14    * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15    * PURPOSE. See the GNU General Public License for more details.
16    *
17    * You should have received a copy of the GNU General Public License
18    * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19    * The Jalview Authors are detailed in the 'AUTHORS' file.
20    */
21    package jalview.bin;
22   
23    import java.awt.Color;
24    import java.io.BufferedReader;
25    import java.io.File;
26    import java.io.FileNotFoundException;
27    import java.io.FileOutputStream;
28    import java.io.IOException;
29    import java.io.InputStreamReader;
30    import java.io.OutputStream;
31    import java.io.OutputStreamWriter;
32    import java.io.PrintStream;
33    import java.io.PrintWriter;
34    import java.net.MalformedURLException;
35    import java.net.URI;
36    import java.net.URISyntaxException;
37    import java.net.URL;
38    import java.security.AllPermission;
39    import java.security.CodeSource;
40    import java.security.PermissionCollection;
41    import java.security.Permissions;
42    import java.security.Policy;
43    import java.util.ArrayList;
44    import java.util.HashMap;
45    import java.util.List;
46    import java.util.Locale;
47    import java.util.Map;
48    import java.util.Properties;
49    import java.util.Vector;
50    import java.util.logging.ConsoleHandler;
51    import java.util.logging.Level;
52    import java.util.logging.Logger;
53    import java.util.stream.Collectors;
54   
55    import javax.swing.JDialog;
56    import javax.swing.JFrame;
57    import javax.swing.JInternalFrame;
58    import javax.swing.JOptionPane;
59    import javax.swing.SwingUtilities;
60    import javax.swing.UIManager;
61    import javax.swing.UIManager.LookAndFeelInfo;
62    import javax.swing.UnsupportedLookAndFeelException;
63   
64    import com.formdev.flatlaf.FlatLightLaf;
65    import com.formdev.flatlaf.themes.FlatMacLightLaf;
66    import com.formdev.flatlaf.util.SystemInfo;
67   
68    //import edu.stanford.ejalbert.launching.IBrowserLaunching;
69    import groovy.lang.Binding;
70    import groovy.util.GroovyScriptEngine;
71    import jalview.bin.argparser.Arg;
72    import jalview.bin.argparser.Arg.Opt;
73    import jalview.bin.argparser.Arg.Type;
74    import jalview.bin.argparser.ArgParser;
75    import jalview.bin.argparser.BootstrapArgs;
76    import jalview.bin.groovy.JalviewObject;
77    import jalview.bin.groovy.JalviewObjectI;
78    import jalview.ext.so.SequenceOntology;
79    import jalview.gui.AlignFrame;
80    import jalview.gui.Desktop;
81    import jalview.gui.JvOptionPane;
82    import jalview.gui.PromptUserConfig;
83    import jalview.gui.QuitHandler;
84    import jalview.gui.QuitHandler.QResponse;
85    import jalview.gui.StructureViewerBase;
86    import jalview.io.AppletFormatAdapter;
87    import jalview.io.BioJsHTMLOutput;
88    import jalview.io.DataSourceType;
89    import jalview.io.FileFormat;
90    import jalview.io.FileFormatException;
91    import jalview.io.FileFormatI;
92    import jalview.io.FileFormats;
93    import jalview.io.FileLoader;
94    import jalview.io.HtmlSvgOutput;
95    import jalview.io.IdentifyFile;
96    import jalview.io.NewickFile;
97    import jalview.io.exceptions.ImageOutputException;
98    import jalview.io.gff.SequenceOntologyFactory;
99    import jalview.schemes.ColourSchemeI;
100    import jalview.schemes.ColourSchemeProperty;
101    import jalview.util.ChannelProperties;
102    import jalview.util.HttpUtils;
103    import jalview.util.LaunchUtils;
104    import jalview.util.MessageManager;
105    import jalview.util.Platform;
106    import jalview.util.UserAgent;
107    import jalview.ws.jws2.Jws2Discoverer;
108   
109    /**
110    * Main class for Jalview Application <br>
111    * <br>
112    * start with: java -classpath "$PATH_TO_LIB$/*:$PATH_TO_CLASSES$" \
113    * jalview.bin.Jalview
114    *
115    * or on Windows: java -classpath "$PATH_TO_LIB$/*;$PATH_TO_CLASSES$" \
116    * jalview.bin.Jalview jalview.bin.Jalview
117    *
118    * (ensure -classpath arg is quoted to avoid shell expansion of '*' and do not
119    * embellish '*' to e.g. '*.jar')
120    *
121    * @author $author$
122    * @version $Revision$
123    */
 
124    public class Jalview implements JalviewObjectI
125    {
 
126  55 toggle static
127    {
128  55 Platform.getURLCommandArguments();
129  55 Platform.addJ2SDirectDatabaseCall("https://www.jalview.org");
130  55 Platform.addJ2SDirectDatabaseCall("http://www.jalview.org");
131  55 Platform.addJ2SDirectDatabaseCall("http://www.compbio.dundee.ac.uk");
132  55 Platform.addJ2SDirectDatabaseCall("https://www.compbio.dundee.ac.uk");
133    }
134   
135    /*
136    * singleton instance of this class
137    */
138    private static Jalview instance;
139   
140    private Desktop desktop;
141   
142    protected Commands cmds;
143   
144    public AlignFrame currentAlignFrame = null;
145   
146    private ArgParser argparser = null;
147   
148    private BootstrapArgs bootstrapArgs = null;
149   
150    private boolean QUIET = false;
151   
 
152  409 toggle public static boolean quiet()
153    {
154  409 return Jalview.getInstance() != null && Jalview.getInstance().QUIET;
155    }
156   
 
157  55 toggle static
158    {
159  55 if (!Platform.isJS())
160    /**
161    * Java only
162    *
163    * @j2sIgnore
164    */
165    {
166    // grab all the rights we can for the JVM
167  55 Policy.setPolicy(new Policy()
168    {
 
169  0 toggle @Override
170    public PermissionCollection getPermissions(CodeSource codesource)
171    {
172  0 Permissions perms = new Permissions();
173  0 perms.add(new AllPermission());
174  0 return (perms);
175    }
176   
 
177  0 toggle @Override
178    public void refresh()
179    {
180    }
181    });
182    }
183    }
184   
185    /**
186    * keep track of feature fetching tasks.
187    *
188    * @author JimP
189    *
190    */
 
191    class FeatureFetcher
192    {
193    /*
194    * TODO: generalise to track all jalview events to orchestrate batch processing
195    * events.
196    */
197   
198    private int queued = 0;
199   
200    private int running = 0;
201   
 
202  0 toggle public FeatureFetcher()
203    {
204   
205    }
206   
 
207  0 toggle public void addFetcher(final AlignFrame af,
208    final Vector<String> dasSources)
209    {
210  0 final long id = System.currentTimeMillis();
211  0 queued++;
212  0 final FeatureFetcher us = this;
213  0 new Thread(new Runnable()
214    {
215   
 
216  0 toggle @Override
217    public void run()
218    {
219  0 synchronized (us)
220    {
221  0 queued--;
222  0 running++;
223    }
224   
225  0 af.setProgressBar(MessageManager
226    .getString("status.das_features_being_retrived"), id);
227  0 af.featureSettings_actionPerformed(null);
228  0 af.setProgressBar(null, id);
229  0 synchronized (us)
230    {
231  0 running--;
232    }
233    }
234    }).start();
235    }
236   
 
237  0 toggle public synchronized boolean allFinished()
238    {
239  0 return queued == 0 && running == 0;
240    }
241   
242    }
243   
 
244  4552 toggle public static Jalview getInstance()
245    {
246  4552 return instance;
247    }
248   
249    /**
250    * main class for Jalview application
251    *
252    * @param args
253    * open <em>filename</em>
254    */
 
255  100 toggle public static void main(String[] args)
256    {
257    // setLogging(); // BH - for event debugging in JavaScript
258  100 instance = new Jalview();
259  100 instance.doMain(args);
260    }
261   
 
262  0 toggle private static void logClass(String name)
263    {
264    // BH - for event debugging in JavaScript
265  0 ConsoleHandler consoleHandler = new ConsoleHandler();
266  0 consoleHandler.setLevel(Level.ALL);
267  0 Logger logger = Logger.getLogger(name);
268  0 logger.setLevel(Level.ALL);
269  0 logger.addHandler(consoleHandler);
270    }
271   
 
272  0 toggle @SuppressWarnings("unused")
273    private static void setLogging()
274    {
275   
276    /**
277    * @j2sIgnore
278    *
279    */
280    {
281  0 Console.outPrintln("not in js");
282    }
283   
284    // BH - for event debugging in JavaScript (Java mode only)
285  0 if (!Platform.isJS())
286    /**
287    * Java only
288    *
289    * @j2sIgnore
290    */
291    {
292  0 Logger.getLogger("").setLevel(Level.ALL);
293  0 logClass("java.awt.EventDispatchThread");
294  0 logClass("java.awt.EventQueue");
295  0 logClass("java.awt.Component");
296  0 logClass("java.awt.focus.Component");
297  0 logClass("java.awt.focus.DefaultKeyboardFocusManager");
298    }
299   
300    }
301   
302    /**
303    * @param args
304    */
 
305  149 toggle void doMain(String[] args)
306    {
307  149 if (!Platform.isJS())
308    {
309  149 System.setSecurityManager(null);
310    }
311   
312  149 if (args == null || args.length == 0 || (args.length == 1
313    && (args[0] == null || args[0].length() == 0)))
314    {
315  9 args = new String[] {};
316    }
317   
318    // get args needed before proper ArgParser
319  149 bootstrapArgs = BootstrapArgs.getBootstrapArgs(args);
320   
321  149 boolean usingLogfile = false;
322  149 if (!Platform.isJS())
323    {
324    // required to ensure log4j doesn't think it's running in a servlet
325  149 System.setProperty("log4j2.isWebapp", "false");
326   
327    // are we using a logfile?
328  149 String logfilename = System.getProperty("installer.logfile");
329  149 boolean append = Boolean
330    .parseBoolean(System.getProperty("installer.logfile_append"));
331   
332  149 usingLogfile = Console.setLogFile(logfilename, append);
333   
334    // are we being --quiet ? (doesn't matter if using a logfile)
335  149 if (!usingLogfile && bootstrapArgs.contains(Arg.QUIET))
336    {
337  0 QUIET = true;
338  0 OutputStream devNull = new OutputStream()
339    {
 
340  0 toggle @Override
341    public void write(int b)
342    {
343    // DO NOTHING
344    }
345    };
346  0 System.setOut(new PrintStream(devNull));
347    // redirecting stderr not working
348  0 if (bootstrapArgs.getList(Arg.QUIET).size() > 1)
349    {
350  0 System.setErr(new PrintStream(devNull));
351    }
352    }
353   
354  149 if (bootstrapArgs.contains(Arg.HELP)
355    || bootstrapArgs.contains(Arg.VERSION))
356    {
357  0 QUIET = true;
358    }
359    }
360   
361    // set individual session preferences
362  149 if (bootstrapArgs.contains(Arg.P))
363    {
364  0 for (String kev : bootstrapArgs.getValueList(Arg.P))
365    {
366  0 if (kev == null)
367    {
368  0 continue;
369    }
370  0 int equalsIndex = kev.indexOf(ArgParser.EQUALS);
371  0 if (equalsIndex > -1)
372    {
373  0 String key = kev.substring(0, equalsIndex);
374  0 String val = kev.substring(equalsIndex + 1);
375  0 Cache.setSessionProperty(key, val);
376    }
377    }
378    }
379   
380    // Move any new getdown-launcher-new.jar into place over old
381    // getdown-launcher.jar
382  149 final String appdirString = System
383    .getProperty("launcher.appdir") != null
384    ? System.getProperty("launcher.appdir")
385    :
386    // maybe an old install4j launch
387    System.getProperty("getdownappdir");
388  149 if (appdirString != null && appdirString.length() > 0)
389    {
390  0 Console.errPrintln("launcher.appdir property: " + appdirString);
391  0 new Thread()
392    {
393   
 
394  0 toggle @Override
395    public void run()
396    {
397  0 GetdownLauncherUpdate.main(new String[] { appdirString });
398    }
399    }.start();
400    }
401    else
402    {
403  149 Console.errPrintln("launcher.appdir property not found");
404    }
405   
406  149 if ((usingLogfile || !quiet()) || !bootstrapArgs.outputToStdout()
407    || bootstrapArgs.contains(Arg.VERSION))
408    {
409  149 if (usingLogfile)
410    {
411  0 Console.outPrintln("-------");
412    }
413  149 Console.outPrint(Cache.getVersionDetailsForConsole());
414  149 if (usingLogfile)
415    {
416  0 Console.outPrintln("-------");
417    }
418    }
419   
420  149 if (Platform.isLinux() && LaunchUtils.getJavaVersion() < 11)
421    {
422  0 System.setProperty("flatlaf.uiScale", "1");
423    }
424   
425    // get bootstrap properties (mainly for the logger level)
426  149 Properties bootstrapProperties = Cache
427    .bootstrapProperties(bootstrapArgs.getValue(Arg.PROPS));
428   
429    // report Jalview version
430  149 Cache.loadBuildProperties(
431    !quiet() || bootstrapArgs.contains(Arg.VERSION));
432   
433    // stop now if only after --version
434  149 if (bootstrapArgs.contains(Arg.VERSION))
435    {
436  0 Jalview.exit(null, ExitCode.OK);
437    }
438   
439    // old ArgsParser
440  149 ArgsParser aparser = new ArgsParser(args);
441   
442    // old
443  149 boolean headless = false;
444    // new
445  149 boolean headlessArg = false;
446   
447  149 try
448    {
449  149 String logLevel = null;
450  149 if (bootstrapArgs.contains(Arg.TRACE))
451    {
452  0 logLevel = "TRACE";
453    }
454  149 else if (bootstrapArgs.contains(Arg.DEBUG))
455    {
456  23 logLevel = bootstrapArgs.getBoolean(Arg.DEBUG) ? "DEBUG" : "INFO";
457    }
458  149 if (logLevel == null && !(bootstrapProperties == null))
459    {
460  126 logLevel = bootstrapProperties.getProperty(Cache.JALVIEWLOGLEVEL);
461    }
462  149 Console.initLogger(logLevel);
463    } catch (NoClassDefFoundError error)
464    {
465  0 error.printStackTrace();
466  0 String message = "\nEssential logging libraries not found."
467    + "\nUse: java -classpath \"$PATH_TO_LIB$/*:$PATH_TO_CLASSES$\" jalview.bin.Jalview";
468  0 Jalview.exit(message, ExitCode.OK);
469    }
470   
471    // register SIGTERM listener
472  149 Runtime.getRuntime().addShutdownHook(new Thread()
473    {
 
474  98 toggle @Override
475    public void run()
476    {
477  98 Console.debug("Running shutdown hook");
478  98 QuitHandler.startForceQuit();
479  97 boolean closeExternal = Cache
480    .getDefault("DEFAULT_CLOSE_EXTERNAL_VIEWERS", false)
481    || Cache.getDefault("ALWAYS_CLOSE_EXTERNAL_VIEWERS", false);
482  97 StructureViewerBase.setQuitClose(closeExternal);
483  88 if (desktop != null)
484    {
485  56 for (JInternalFrame frame : Desktop.desktop.getAllFrames())
486    {
487  5 if (frame instanceof StructureViewerBase)
488    {
489  1 ((StructureViewerBase) frame).closeViewer(closeExternal);
490    }
491    }
492    }
493   
494  88 if (QuitHandler.gotQuitResponse() == QResponse.CANCEL_QUIT)
495    {
496    // Got to here by a SIGTERM signal.
497    // Note we will not actually cancel the quit from here -- it's too
498    // late -- but we can wait for saving files and close external viewers
499    // if configured.
500    // Close viewers/Leave viewers open
501  0 Console.debug("Checking for saving files");
502  0 QuitHandler.getQuitResponse(false);
503    }
504    else
505    {
506  88 Console.debug("Nothing more to do");
507    }
508  88 Console.debug("Exiting, bye!");
509    // shutdownHook cannot be cancelled, JVM will now halt
510    }
511    });
512   
513  149 String usrPropsFile = bootstrapArgs.contains(Arg.PROPS)
514    ? bootstrapArgs.getValue(Arg.PROPS)
515    : aparser.getValue("props");
516    // if usrPropsFile == null, loadProperties will use the Channel
517    // preferences.file
518  149 Cache.loadProperties(usrPropsFile);
519  149 if (usrPropsFile != null)
520    {
521  48 Console.outPrintln(
522    "CMD [-props " + usrPropsFile + "] executed successfully!");
523  48 testoutput(bootstrapArgs, Arg.PROPS,
524    "test/jalview/bin/testProps.jvprops", usrPropsFile);
525    }
526   
527    // --argfile=... -- OVERRIDES ALL NON-BOOTSTRAP ARGS
528  149 if (bootstrapArgs.contains(Arg.ARGFILE))
529    {
530  8 argparser = ArgParser.parseArgFiles(
531    bootstrapArgs.getValueList(Arg.ARGFILE),
532    bootstrapArgs.getBoolean(Arg.INITSUBSTITUTIONS),
533    bootstrapArgs);
534    }
535    else
536    {
537  141 argparser = new ArgParser(args,
538    bootstrapArgs.getBoolean(Arg.INITSUBSTITUTIONS),
539    bootstrapArgs);
540    }
541   
542  149 if (!Platform.isJS())
543    /**
544    * Java only
545    *
546    * @j2sIgnore
547    */
548    {
549  149 if (bootstrapArgs.contains(Arg.HELP))
550    {
551  0 List<Map.Entry<Type, String>> helpArgs = bootstrapArgs
552    .getList(Arg.HELP);
553  0 Console.outPrintln(Arg.usage(helpArgs.stream().map(e -> e.getKey())
554    .collect(Collectors.toList())));
555  0 Jalview.exit(null, ExitCode.OK);
556    }
557  149 if (aparser.contains("help") || aparser.contains("h"))
558    {
559    /*
560    * Now using new usage statement.
561    showUsage();
562    */
563  0 Console.outPrintln(Arg.usage());
564  0 Jalview.exit(null, ExitCode.OK);
565    }
566   
567    // new CLI
568  149 headlessArg = bootstrapArgs.isHeadless();
569  149 if (headlessArg)
570    {
571  32 System.setProperty("java.awt.headless", "true");
572    }
573    // old CLI
574  149 if (aparser.contains("nodisplay") || aparser.contains("nogui")
575    || aparser.contains("headless"))
576    {
577  17 System.setProperty("java.awt.headless", "true");
578  17 headless = true;
579    }
580    // anything else!
581   
582    // allow https handshakes to download intermediate certs if necessary
583  149 System.setProperty("com.sun.security.enableAIAcaIssuers", "true");
584   
585  149 String jabawsUrl = bootstrapArgs.getValue(Arg.JABAWS);
586  149 if (jabawsUrl == null)
587  148 jabawsUrl = aparser.getValue("jabaws");
588  149 if (jabawsUrl != null)
589    {
590  2 try
591    {
592  2 Jws2Discoverer.getDiscoverer().setPreferredUrl(jabawsUrl);
593  2 Console.outPrintln(
594    "CMD [-jabaws " + jabawsUrl + "] executed successfully!");
595  2 testoutput(bootstrapArgs, Arg.JABAWS,
596    "http://www.compbio.dundee.ac.uk/jabaws", jabawsUrl);
597    } catch (MalformedURLException e)
598    {
599  0 jalview.bin.Console.errPrintln(
600    "Invalid jabaws parameter: " + jabawsUrl + " ignored");
601    }
602    }
603    }
604   
605  149 List<String> setprops = new ArrayList<>();
606  149 if (bootstrapArgs.contains(Arg.SETPROP))
607    {
608  0 setprops = bootstrapArgs.getValueList(Arg.SETPROP);
609    }
610    else
611    {
612  149 String sp = aparser.getValue("setprop");
613  149 while (sp != null)
614    {
615  0 setprops.add(sp);
616  0 sp = aparser.getValue("setprop");
617    }
618    }
619  149 for (String setprop : setprops)
620    {
621  0 int p = setprop.indexOf('=');
622  0 if (p == -1)
623    {
624  0 System.err
625    .println("Ignoring invalid setprop argument : " + setprop);
626    }
627    else
628    {
629  0 jalview.bin.Console
630    .errPrintln("Executing setprop argument: " + setprop);
631  0 if (Platform.isJS())
632    {
633  0 Cache.setProperty(setprop.substring(0, p),
634    setprop.substring(p + 1));
635    }
636    // DISABLED FOR SECURITY REASONS
637    // TODO: add a property to allow properties to be overriden by cli args
638    // Cache.setProperty(setprop.substring(0,p), setprop.substring(p+1));
639    }
640    }
641  149 if (System.getProperty("java.awt.headless") != null
642    && System.getProperty("java.awt.headless").equals("true"))
643    {
644  55 headless = true;
645    }
646  149 System.setProperty("http.agent", UserAgent.getUserAgent());
647   
648    // Initialise the logger
649  149 try
650    {
651  149 Console.initLogger();
652    } catch (NoClassDefFoundError error)
653    {
654  0 error.printStackTrace();
655  0 String message = "\nEssential logging libraries not found."
656    + "\nUse: java -classpath \"$PATH_TO_LIB$/*:$PATH_TO_CLASSES$\" jalview.bin.Jalview";
657  0 Jalview.exit(message, ExitCode.NO_LOGGING);
658    }
659  149 desktop = null;
660   
661  149 if (!(headless || headlessArg))
662  94 setLookAndFeel();
663   
664    /*
665    * configure 'full' SO model if preferences say to, else use the default (full SO)
666    * - as JS currently doesn't have OBO parsing, it must use 'Lite' version
667    */
668  148 boolean soDefault = !Platform.isJS();
669  148 if (Cache.getDefault("USE_FULL_SO", soDefault))
670    {
671  148 SequenceOntologyFactory.setInstance(new SequenceOntology());
672    }
673   
674  148 if (!(headless || headlessArg))
675    {
676  93 Desktop.nosplash = "false".equals(bootstrapArgs.getValue(Arg.SPLASH))
677    || aparser.contains("nosplash")
678    || Cache.getDefault("SPLASH", "true").equals("false");
679  93 desktop = new Desktop();
680  93 desktop.setInBatchMode(true); // indicate we are starting up
681   
682  93 mixedCliWarning();
683   
684  93 try
685    {
686  93 JalviewTaskbar.setTaskbar(this);
687    } catch (Exception e)
688    {
689  0 Console.info("Cannot set Taskbar");
690  0 Console.error(e.getMessage());
691    // e.printStackTrace();
692    } catch (Throwable t)
693    {
694  0 Console.info("Cannot set Taskbar");
695  0 Console.error(t.getMessage());
696    // t.printStackTrace();
697    }
698   
699    // set Proxy settings before all the internet calls
700  93 Cache.setProxyPropertiesFromPreferences();
701   
702  93 desktop.setVisible(true);
703   
704  93 if (!Platform.isJS())
705    /**
706    * Java only
707    *
708    * @j2sIgnore
709    */
710    {
711   
712  93 String appName = ChannelProperties.getProperty("app_name");
713   
714    /**
715    * Check to see that the JVM version being run is suitable for the Java
716    * version this Jalview was compiled for. Popup a warning if not.
717    */
718  93 if (!LaunchUtils.checkJavaVersion())
719    {
720  0 Console.warn("The Java version being used (Java "
721    + LaunchUtils.getJavaVersion()
722    + ") may lead to problems. This installation of "
723    + appName + " should be used with Java "
724    + LaunchUtils.getJavaCompileVersion() + ".");
725   
726  0 if (!LaunchUtils
727    .getBooleanUserPreference("IGNORE_JVM_WARNING_POPUP"))
728    {
729  0 Object[] options = {
730    MessageManager.getString("label.continue") };
731  0 JOptionPane.showOptionDialog(null,
732    MessageManager.formatMessage(
733    "warning.wrong_jvm_version_message",
734    LaunchUtils.getJavaVersion(),
735    LaunchUtils.getJavaCompileVersion()),
736    MessageManager
737    .getString("warning.wrong_jvm_version_title"),
738    JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE,
739    null, options, options[0]);
740    }
741    }
742   
743    /**
744    * Check to see if we've been launched from the installer volume
745    * (macOS).
746    */
747  93 String installerappdirString = System
748    .getProperty("installer.appdir");
749  93 if (Platform.isMac() && installerappdirString != null
750    && installerappdirString.startsWith("/Volumes/"))
751    {
752  0 Console.warn("You appear to be running " + appName
753    + " from the Installer volume. Please drag and drop the "
754    + appName + " icon into the Applications folder.");
755   
756  0 Object[] options = { MessageManager.getString("action.quit") };
757  0 JOptionPane.showOptionDialog(null, MessageManager.formatMessage(
758    "warning.running_from_installer_volume_message", appName),
759    MessageManager.getString(
760    "warning.running_from_installer_volume_title"),
761    JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE,
762    null, options, options[0]);
763  0 quit();
764    }
765   
766  93 boolean webservicediscovery = bootstrapArgs
767    .getBoolean(Arg.WEBSERVICEDISCOVERY);
768  93 if (aparser.contains("nowebservicediscovery"))
769  0 webservicediscovery = false;
770  93 if (webservicediscovery)
771    {
772  73 desktop.startServiceDiscovery();
773    }
774    else
775    {
776  20 testoutput(argparser, Arg.WEBSERVICEDISCOVERY);
777    }
778   
779  93 boolean usagestats = !bootstrapArgs.getBoolean(Arg.NOUSAGESTATS);
780  93 if (aparser.contains("nousagestats"))
781  1 usagestats = false;
782  93 if (usagestats)
783    {
784  87 startUsageStats(desktop);
785  87 testoutput(argparser, Arg.NOUSAGESTATS);
786    }
787    else
788    {
789  6 Console.outPrintln("CMD [-nousagestats] executed successfully!");
790  6 testoutput(argparser, Arg.NOUSAGESTATS);
791    }
792   
793  93 boolean questionnaire = bootstrapArgs.getBoolean(Arg.QUESTIONNAIRE);
794  93 if (aparser.contains("noquestionnaire"))
795  1 questionnaire = false;
796  93 if (questionnaire)
797    {
798  85 String url = aparser.getValue("questionnaire");
799  85 if (url != null)
800    {
801    // Start the desktop questionnaire prompter with the specified
802    // questionnaire
803  0 Console.debug("Starting questionnaire url at " + url);
804  0 desktop.checkForQuestionnaire(url);
805  0 Console.outPrintln("CMD questionnaire[-" + url
806    + "] executed successfully!");
807    }
808    else
809    {
810  85 if (Cache.getProperty("NOQUESTIONNAIRES") == null)
811    {
812    // Start the desktop questionnaire prompter with the specified
813    // questionnaire
814    // String defurl =
815    // "http://anaplog.compbio.dundee.ac.uk/cgi-bin/questionnaire.pl";
816    // //
817  39 String defurl = "https://www.jalview.org/cgi-bin/questionnaire.pl";
818  39 Console.debug(
819    "Starting questionnaire with default url: " + defurl);
820  39 desktop.checkForQuestionnaire(defurl);
821    }
822    }
823    }
824    else
825    {
826  8 Console.outPrintln(
827    "CMD [-noquestionnaire] executed successfully!");
828  8 testoutput(argparser, Arg.QUESTIONNAIRE);
829    }
830   
831  93 if ((!aparser.contains("nonews")
832    && Cache.getProperty("NONEWS") == null
833    && !"false".equals(bootstrapArgs.getValue(Arg.NEWS)))
834    || "true".equals(bootstrapArgs.getValue(Arg.NEWS)))
835    {
836  42 desktop.checkForNews();
837    }
838   
839  93 if (!aparser.contains("nohtmltemplates")
840    && Cache.getProperty("NOHTMLTEMPLATES") == null)
841    {
842  93 BioJsHTMLOutput.updateBioJS();
843    }
844    }
845    }
846    else
847    {
848   
849  55 if (getArgParser().isMixedStyle())
850    {
851  0 String warning = MessageManager.formatMessage(
852    "warning.using_mixed_command_line_arguments",
853    getArgParser().getMixedExamples());
854  0 Console.warn(warning);
855  0 Jalview.exit(
856    "Exiting due to mixed old and new command line arguments",
857    ExitCode.INVALID_ARGUMENT);
858    }
859  55 if (getArgParser().isOldStyle())
860    {
861  17 String warning = MessageManager
862    .getString("warning.using_old_command_line_arguments")
863    .replace("\n", " ")
864    + "https://www.jalview.org/help/html/features/commandline.html";
865  17 Console.warn(warning);
866    }
867   
868    }
869   
870    // Run Commands from cli
871  148 cmds = new Commands(argparser, headlessArg);
872  148 cmds.processArgs();
873  143 boolean commandsSuccess = cmds.argsWereParsed();
874   
875  143 if (commandsSuccess)
876    {
877  90 if (headlessArg)
878    {
879  32 if (argparser.getBoolean(Arg.NOQUIT))
880    {
881  6 Console.warn(
882    "Completed " + Arg.HEADLESS.getName() + " commands, but "
883    + Arg.NOQUIT + " is set so not quitting!");
884    }
885    else
886    {
887  26 Jalview.exit("Successfully completed commands in headless mode",
888    ExitCode.OK);
889    }
890    }
891  64 Console.info("Successfully completed commands");
892    }
893    else
894    {
895  53 if (headlessArg)
896    {
897  0 Jalview.exit("Error when running Commands in headless mode",
898    ExitCode.ERROR_RUNNING_COMMANDS);
899    }
900  53 Console.warn("Error when running commands");
901    }
902   
903    // Check if JVM and compile version might cause problems and log if it
904    // might.
905  117 if (headless && !Platform.isJS() && !LaunchUtils.checkJavaVersion())
906    {
907  0 Console.warn("The Java version being used (Java "
908    + LaunchUtils.getJavaVersion()
909    + ") may lead to problems. This installation of Jalview should be used with Java "
910    + LaunchUtils.getJavaCompileVersion() + ".");
911    }
912   
913  117 String file = null, data = null;
914   
915  117 FileFormatI format = null;
916   
917  117 DataSourceType protocol = null;
918   
919  117 FileLoader fileLoader = new FileLoader(!headless);
920   
921  117 String groovyscript = null; // script to execute after all loading is
922    // completed one way or another
923    // extract groovy argument and execute if necessary
924  117 groovyscript = aparser.getValue("groovy", true);
925  117 file = aparser.getValue("open", true);
926   
927  117 if (file == null && desktop == null && !commandsSuccess)
928    {
929  0 Jalview.exit("No files to open!", ExitCode.NO_FILES);
930    }
931   
932  117 long progress = -1;
933    // Finally, deal with the remaining input data.
934  117 if (file != null)
935    {
936  18 if (!headless)
937    {
938  1 desktop.setProgressBar(
939    MessageManager
940    .getString("status.processing_commandline_args"),
941    progress = System.currentTimeMillis());
942    }
943  18 Console.outPrintln("CMD [-open " + file + "] executed successfully!");
944   
945  18 if (!Platform.isJS())
946    /**
947    * ignore in JavaScript -- can't just file existence - could load it?
948    *
949    * @j2sIgnore
950    */
951    {
952  18 if (!HttpUtils.startsWithHttpOrHttps(file))
953    {
954  18 if (!(new File(file)).exists())
955    {
956  0 if (headless)
957    {
958  0 Jalview.exit(
959    "Can't find file '" + file + "' in headless mode",
960    ExitCode.FILE_NOT_FOUND);
961    }
962  0 Console.warn("Can't find file'" + file + "'");
963    }
964    }
965    }
966   
967  18 protocol = AppletFormatAdapter.checkProtocol(file);
968   
969  18 try
970    {
971  18 format = new IdentifyFile().identify(file, protocol);
972    } catch (FileNotFoundException e)
973    {
974  0 Console.error("File at '" + file + "' not found", e);
975    } catch (FileFormatException e)
976    {
977  0 Console.error("File '" + file + "' format not recognised", e);
978    }
979   
980  18 AlignFrame af = fileLoader.LoadFileWaitTillLoaded(file, protocol,
981    format);
982  18 if (af == null)
983    {
984  0 Console.outPrintln("error");
985    }
986    else
987    {
988  18 setCurrentAlignFrame(af);
989  18 data = aparser.getValue("colour", true);
990  18 if (data != null)
991    {
992  1 data.replaceAll("%20", " ");
993   
994  1 ColourSchemeI cs = ColourSchemeProperty.getColourScheme(
995    af.getViewport(), af.getViewport().getAlignment(), data);
996   
997  1 if (cs != null)
998    {
999  1 Console.outPrintln(
1000    "CMD [-colour " + data + "] executed successfully!");
1001    }
1002  1 af.changeColour(cs);
1003    }
1004   
1005    // Must maintain ability to use the groups flag
1006  18 data = aparser.getValue("groups", true);
1007  18 if (data != null)
1008    {
1009  0 af.parseFeaturesFile(data,
1010    AppletFormatAdapter.checkProtocol(data));
1011    // Console.outPrintln("Added " + data);
1012  0 Console.outPrintln(
1013    "CMD groups[-" + data + "] executed successfully!");
1014    }
1015  18 data = aparser.getValue("features", true);
1016  18 if (data != null)
1017    {
1018  1 af.parseFeaturesFile(data,
1019    AppletFormatAdapter.checkProtocol(data));
1020    // Console.outPrintln("Added " + data);
1021  1 Console.outPrintln(
1022    "CMD [-features " + data + "] executed successfully!");
1023    }
1024   
1025  18 data = aparser.getValue("annotations", true);
1026  18 if (data != null)
1027    {
1028  1 af.loadJalviewDataFile(data, null, null, null);
1029    // Console.outPrintln("Added " + data);
1030  1 Console.outPrintln(
1031    "CMD [-annotations " + data + "] executed successfully!");
1032    }
1033    // set or clear the sortbytree flag.
1034  18 if (aparser.contains("sortbytree"))
1035    {
1036  1 af.getViewport().setSortByTree(true);
1037  1 if (af.getViewport().getSortByTree())
1038    {
1039  1 Console.outPrintln("CMD [-sortbytree] executed successfully!");
1040    }
1041    }
1042  18 if (aparser.contains("no-annotation"))
1043    {
1044  0 af.getViewport().setShowAnnotation(false);
1045  0 if (!af.getViewport().isShowAnnotation())
1046    {
1047  0 Console.outPrintln("CMD no-annotation executed successfully!");
1048    }
1049    }
1050  18 if (aparser.contains("nosortbytree"))
1051    {
1052  1 af.getViewport().setSortByTree(false);
1053  1 if (!af.getViewport().getSortByTree())
1054    {
1055  1 Console.outPrintln(
1056    "CMD [-nosortbytree] executed successfully!");
1057    }
1058    }
1059  18 data = aparser.getValue("tree", true);
1060  18 if (data != null)
1061    {
1062  1 try
1063    {
1064  1 Console.outPrintln(
1065    "CMD [-tree " + data + "] executed successfully!");
1066  1 NewickFile nf = new NewickFile(data,
1067    AppletFormatAdapter.checkProtocol(data));
1068  1 af.getViewport()
1069    .setCurrentTree(af.showNewickTree(nf, data).getTree());
1070    } catch (IOException ex)
1071    {
1072  0 jalview.bin.Console.errPrintln("Couldn't add tree " + data);
1073  0 ex.printStackTrace(System.err);
1074    }
1075    }
1076   
1077  18 if (groovyscript != null)
1078    {
1079    // Execute the groovy script after we've done all the rendering stuff
1080    // and before any images or figures are generated.
1081  0 Console.outPrintln("Executing script " + groovyscript);
1082  0 executeGroovyScript(groovyscript, af);
1083  0 Console.outPrintln("CMD groovy[" + groovyscript
1084    + "] executed successfully!");
1085  0 groovyscript = null;
1086    }
1087  18 String imageName = "unnamed.png";
1088  34 while (aparser.getSize() > 1)
1089    {
1090  16 try
1091    {
1092  16 String outputFormat = aparser.nextValue();
1093  16 file = aparser.nextValue();
1094   
1095  16 if (outputFormat.equalsIgnoreCase("png"))
1096    {
1097  1 Console.outPrintln("Creating PNG image: " + file);
1098  1 af.createPNG(new File(file));
1099  1 imageName = (new File(file)).getName();
1100  1 continue;
1101    }
1102  15 else if (outputFormat.equalsIgnoreCase("svg"))
1103    {
1104  1 Console.outPrintln("Creating SVG image: " + file);
1105  1 File imageFile = new File(file);
1106  1 imageName = imageFile.getName();
1107  1 af.createSVG(imageFile);
1108  1 continue;
1109    }
1110  14 else if (outputFormat.equalsIgnoreCase("html"))
1111    {
1112  1 File imageFile = new File(file);
1113  1 imageName = imageFile.getName();
1114  1 HtmlSvgOutput htmlSVG = new HtmlSvgOutput(af.alignPanel);
1115   
1116  1 Console.outPrintln("Creating HTML image: " + file);
1117  1 htmlSVG.exportHTML(file);
1118  1 continue;
1119    }
1120  13 else if (outputFormat.equalsIgnoreCase("biojsmsa"))
1121    {
1122  0 if (file == null)
1123    {
1124  0 jalview.bin.Console.errPrintln(
1125    "The output html file must not be null");
1126  0 return;
1127    }
1128  0 try
1129    {
1130  0 BioJsHTMLOutput.refreshVersionInfo(
1131    BioJsHTMLOutput.BJS_TEMPLATES_LOCAL_DIRECTORY);
1132    } catch (URISyntaxException e)
1133    {
1134  0 e.printStackTrace();
1135    }
1136  0 BioJsHTMLOutput bjs = new BioJsHTMLOutput(af.alignPanel);
1137  0 Console.outPrintln(
1138    "Creating BioJS MSA Viwer HTML file: " + file);
1139  0 bjs.exportHTML(file);
1140  0 continue;
1141    }
1142  13 else if (outputFormat.equalsIgnoreCase("imgMap"))
1143    {
1144  0 Console.outPrintln("Creating image map: " + file);
1145  0 af.createImageMap(new File(file), imageName);
1146  0 continue;
1147    }
1148  13 else if (outputFormat.equalsIgnoreCase("eps"))
1149    {
1150  5 File outputFile = new File(file);
1151  5 Console.outPrintln(
1152    "Creating EPS file: " + outputFile.getAbsolutePath());
1153  5 af.createEPS(outputFile);
1154  5 continue;
1155    }
1156   
1157  8 FileFormatI outFormat = null;
1158  8 try
1159    {
1160  8 outFormat = FileFormats.getInstance().forName(outputFormat);
1161    } catch (Exception formatP)
1162    {
1163  0 Console.outPrintln("Couldn't parse " + outFormat
1164    + " as a valid Jalview format string.");
1165    }
1166  8 if (outFormat != null)
1167    {
1168  8 if (!outFormat.isWritable())
1169    {
1170  0 Console.outPrintln(
1171    "This version of Jalview does not support alignment export as "
1172    + outputFormat);
1173    }
1174    else
1175    {
1176  8 af.saveAlignment(file, outFormat);
1177  8 if (af.isSaveAlignmentSuccessful())
1178    {
1179  8 Console.outPrintln("Written alignment in "
1180    + outFormat.getName() + " format to " + file);
1181    }
1182    else
1183    {
1184  0 Console.outPrintln("Error writing file " + file + " in "
1185    + outFormat.getName() + " format!!");
1186    }
1187    }
1188    }
1189    } catch (ImageOutputException ioexc)
1190    {
1191  0 Console.outPrintln(
1192    "Unexpected error whilst exporting image to " + file);
1193  0 ioexc.printStackTrace();
1194    }
1195   
1196    }
1197   
1198  18 while (aparser.getSize() > 0)
1199    {
1200  0 Console.outPrintln("Unknown arg: " + aparser.nextValue());
1201    }
1202    }
1203    }
1204   
1205  117 AlignFrame startUpAlframe = null;
1206    // We'll only open the default file if the desktop is visible.
1207    // And the user
1208    // ////////////////////
1209   
1210  117 if (!Platform.isJS() && !headless && file == null
1211    && Cache.getDefault("SHOW_STARTUP_FILE", true)
1212    && !cmds.commandArgsProvided()
1213    && !bootstrapArgs.getBoolean(Arg.NOSTARTUPFILE))
1214    // don't open the startup file if command line args have been processed
1215    // (&& !Commands.commandArgsProvided())
1216    /**
1217    * Java only
1218    *
1219    * @j2sIgnore
1220    */
1221    {
1222  0 file = Cache.getDefault("STARTUP_FILE",
1223    Cache.getDefault("www.jalview.org", "https://www.jalview.org")
1224    + "/examples/exampleFile_2_7.jvp");
1225  0 if (file.equals("http://www.jalview.org/examples/exampleFile_2_3.jar")
1226    || file.equals(
1227    "http://www.jalview.org/examples/exampleFile_2_7.jar"))
1228    {
1229  0 file.replace("http:", "https:");
1230    // hardwire upgrade of the startup file
1231  0 file.replace("_2_3", "_2_7");
1232  0 file.replace("2_7.jar", "2_7.jvp");
1233    // and remove the stale setting
1234  0 Cache.removeProperty("STARTUP_FILE");
1235    }
1236   
1237  0 protocol = AppletFormatAdapter.checkProtocol(file);
1238   
1239  0 if (file.endsWith(".jar"))
1240    {
1241  0 format = FileFormat.Jalview;
1242    }
1243    else
1244    {
1245  0 try
1246    {
1247  0 format = new IdentifyFile().identify(file, protocol);
1248    } catch (FileNotFoundException e)
1249    {
1250  0 Console.error("File at '" + file + "' not found", e);
1251    } catch (FileFormatException e)
1252    {
1253  0 Console.error("File '" + file + "' format not recognised", e);
1254    }
1255    }
1256   
1257  0 startUpAlframe = fileLoader.LoadFileWaitTillLoaded(file, protocol,
1258    format);
1259    // don't ask to save when quitting if only the startup file has been
1260    // opened
1261  0 Console.debug("Resetting up-to-date flag for startup file");
1262  0 startUpAlframe.getViewport().setSavedUpToDate(true);
1263    // extract groovy arguments before anything else.
1264    }
1265   
1266    // Once all other stuff is done, execute any groovy scripts (in order)
1267  117 if (groovyscript != null)
1268    {
1269  0 if (Cache.groovyJarsPresent())
1270    {
1271  0 Console.outPrintln("Executing script " + groovyscript);
1272  0 executeGroovyScript(groovyscript, startUpAlframe);
1273    }
1274    else
1275    {
1276  0 jalview.bin.Console.errPrintln(
1277    "Sorry. Groovy Support is not available, so ignoring the provided groovy script "
1278    + groovyscript);
1279    }
1280    }
1281    // and finally, turn off batch mode indicator - if the desktop still exists
1282  117 if (desktop != null)
1283    {
1284  88 if (progress != -1)
1285    {
1286  1 desktop.setProgressBar(null, progress);
1287    }
1288  88 desktop.setInBatchMode(false);
1289    }
1290   
1291  117 cliWarning();
1292    }
1293   
 
1294  94 toggle private static void setLookAndFeel()
1295    {
1296  94 if (!Platform.isJS())
1297    /**
1298    * Java only
1299    *
1300    * @j2sIgnore
1301    */
1302    {
1303    // property laf = "crossplatform", "system", "gtk", "metal", "nimbus",
1304    // "mac" or "flat"
1305    // If not set (or chosen laf fails), use the normal SystemLaF and if on
1306    // Mac,
1307    // try Quaqua/Vaqua.
1308  94 String lafProp = System.getProperty("laf");
1309  94 String lafSetting = Cache.getDefault("PREFERRED_LAF", null);
1310  94 String laf = "none";
1311  94 if (lafProp != null)
1312    {
1313  0 laf = lafProp;
1314    }
1315  94 else if (lafSetting != null)
1316    {
1317  0 laf = lafSetting;
1318    }
1319  94 boolean lafSet = false;
1320  94 switch (laf)
1321    {
1322  0 case "crossplatform":
1323  0 lafSet = setCrossPlatformLookAndFeel();
1324  0 if (!lafSet)
1325    {
1326  0 Console.error("Could not set requested laf=" + laf);
1327    }
1328  0 break;
1329  0 case "system":
1330  0 lafSet = setSystemLookAndFeel();
1331  0 if (!lafSet)
1332    {
1333  0 Console.error("Could not set requested laf=" + laf);
1334    }
1335  0 break;
1336  0 case "gtk":
1337  0 lafSet = setGtkLookAndFeel();
1338  0 if (!lafSet)
1339    {
1340  0 Console.error("Could not set requested laf=" + laf);
1341    }
1342  0 break;
1343  0 case "metal":
1344  0 lafSet = setMetalLookAndFeel();
1345  0 if (!lafSet)
1346    {
1347  0 Console.error("Could not set requested laf=" + laf);
1348    }
1349  0 break;
1350  0 case "nimbus":
1351  0 lafSet = setNimbusLookAndFeel();
1352  0 if (!lafSet)
1353    {
1354  0 Console.error("Could not set requested laf=" + laf);
1355    }
1356  0 break;
1357  0 case "flat":
1358  0 lafSet = setFlatLookAndFeel();
1359  0 if (!lafSet)
1360    {
1361  0 Console.error("Could not set requested laf=" + laf);
1362    }
1363  0 break;
1364  0 case "mac":
1365  0 lafSet = setMacLookAndFeel();
1366  0 if (!lafSet)
1367    {
1368  0 Console.error("Could not set requested laf=" + laf);
1369    }
1370  0 break;
1371  94 case "none":
1372  94 break;
1373  0 default:
1374  0 Console.error("Requested laf=" + laf + " not implemented");
1375    }
1376  94 if (!lafSet)
1377    {
1378    // Flatlaf default for everyone!
1379  94 lafSet = setFlatLookAndFeel();
1380  93 if (!lafSet)
1381    {
1382  0 setSystemLookAndFeel();
1383    }
1384  93 if (Platform.isLinux())
1385    {
1386  93 setLinuxLookAndFeel();
1387    }
1388  93 if (Platform.isMac())
1389    {
1390  0 setMacLookAndFeel();
1391    }
1392    }
1393    }
1394    }
1395   
 
1396  0 toggle private static boolean setCrossPlatformLookAndFeel()
1397    {
1398  0 boolean set = false;
1399  0 try
1400    {
1401  0 UIManager.setLookAndFeel(
1402    UIManager.getCrossPlatformLookAndFeelClassName());
1403  0 set = true;
1404    } catch (Exception ex)
1405    {
1406  0 Console.error("Unexpected Look and Feel Exception");
1407  0 Console.error(ex.getMessage());
1408  0 Console.debug(Cache.getStackTraceString(ex));
1409    }
1410  0 return set;
1411    }
1412   
 
1413  0 toggle private static boolean setSystemLookAndFeel()
1414    {
1415  0 boolean set = false;
1416  0 try
1417    {
1418  0 UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
1419  0 set = true;
1420    } catch (Exception ex)
1421    {
1422  0 Console.error("Unexpected Look and Feel Exception");
1423  0 Console.error(ex.getMessage());
1424  0 Console.debug(Cache.getStackTraceString(ex));
1425    }
1426  0 return set;
1427    }
1428   
 
1429  0 toggle private static boolean setSpecificLookAndFeel(String name,
1430    String className, boolean nameStartsWith)
1431    {
1432  0 boolean set = false;
1433  0 try
1434    {
1435  0 for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels())
1436    {
1437  0 if (info.getName() != null && nameStartsWith
1438    ? info.getName().toLowerCase(Locale.ROOT)
1439    .startsWith(name.toLowerCase(Locale.ROOT))
1440    : info.getName().toLowerCase(Locale.ROOT)
1441    .equals(name.toLowerCase(Locale.ROOT)))
1442    {
1443  0 className = info.getClassName();
1444  0 break;
1445    }
1446    }
1447  0 UIManager.setLookAndFeel(className);
1448  0 set = true;
1449    } catch (Exception ex)
1450    {
1451  0 Console.error("Unexpected Look and Feel Exception");
1452  0 Console.error(ex.getMessage());
1453  0 Console.debug(Cache.getStackTraceString(ex));
1454    }
1455  0 return set;
1456    }
1457   
 
1458  0 toggle private static boolean setGtkLookAndFeel()
1459    {
1460  0 return setSpecificLookAndFeel("gtk",
1461    "com.sun.java.swing.plaf.gtk.GTKLookAndFeel", true);
1462    }
1463   
 
1464  0 toggle private static boolean setMetalLookAndFeel()
1465    {
1466  0 return setSpecificLookAndFeel("metal",
1467    "javax.swing.plaf.metal.MetalLookAndFeel", false);
1468    }
1469   
 
1470  0 toggle private static boolean setNimbusLookAndFeel()
1471    {
1472  0 return setSpecificLookAndFeel("nimbus",
1473    "javax.swing.plaf.nimbus.NimbusLookAndFeel", false);
1474    }
1475   
 
1476  187 toggle private static boolean setFlatLookAndFeel()
1477    {
1478  187 boolean set = false;
1479  187 if (SystemInfo.isMacOS)
1480    {
1481  0 try
1482    {
1483  0 UIManager.setLookAndFeel(
1484    "com.formdev.flatlaf.themes.FlatMacLightLaf");
1485  0 set = true;
1486  0 Console.debug("Using FlatMacLightLaf");
1487    } catch (ClassNotFoundException | InstantiationException
1488    | IllegalAccessException | UnsupportedLookAndFeelException e)
1489    {
1490  0 Console.debug("Exception loading FlatLightLaf", e);
1491    }
1492  0 System.setProperty("apple.laf.useScreenMenuBar", "true");
1493  0 System.setProperty("apple.awt.application.name",
1494    ChannelProperties.getProperty("app_name"));
1495  0 System.setProperty("apple.awt.application.appearance", "system");
1496  0 if (SystemInfo.isMacFullWindowContentSupported
1497    && Desktop.desktop != null)
1498    {
1499  0 Console.debug("Setting transparent title bar");
1500  0 Desktop.desktop.getRootPane()
1501    .putClientProperty("apple.awt.fullWindowContent", true);
1502  0 Desktop.desktop.getRootPane()
1503    .putClientProperty("apple.awt.transparentTitleBar", true);
1504  0 Desktop.desktop.getRootPane()
1505    .putClientProperty("apple.awt.fullscreenable", true);
1506    }
1507  0 SwingUtilities.invokeLater(() -> {
1508  0 FlatMacLightLaf.setup();
1509    });
1510  0 Console.debug("Using FlatMacLightLaf");
1511  0 set = true;
1512    }
1513  187 if (!set)
1514    {
1515  187 try
1516    {
1517  187 UIManager.setLookAndFeel("com.formdev.flatlaf.FlatLightLaf");
1518  186 set = true;
1519  186 Console.debug("Using FlatLightLaf");
1520    } catch (ClassNotFoundException | InstantiationException
1521    | IllegalAccessException | UnsupportedLookAndFeelException e)
1522    {
1523  0 Console.debug("Exception loading FlatLightLaf", e);
1524    }
1525    // Windows specific properties here
1526  186 SwingUtilities.invokeLater(() -> {
1527  186 FlatLightLaf.setup();
1528    });
1529  186 Console.debug("Using FlatLightLaf");
1530  186 set = true;
1531    }
1532  0 else if (SystemInfo.isLinux)
1533    {
1534  0 try
1535    {
1536  0 UIManager.setLookAndFeel("com.formdev.flatlaf.FlatLightLaf");
1537  0 set = true;
1538  0 Console.debug("Using FlatLightLaf");
1539    } catch (ClassNotFoundException | InstantiationException
1540    | IllegalAccessException | UnsupportedLookAndFeelException e)
1541    {
1542  0 Console.debug("Exception loading FlatLightLaf", e);
1543    }
1544    // enable custom window decorations
1545  0 JFrame.setDefaultLookAndFeelDecorated(true);
1546  0 JDialog.setDefaultLookAndFeelDecorated(true);
1547  0 SwingUtilities.invokeLater(() -> {
1548  0 FlatLightLaf.setup();
1549    });
1550  0 Console.debug("Using FlatLightLaf");
1551  0 set = true;
1552    }
1553   
1554  186 if (!set)
1555    {
1556  0 try
1557    {
1558  0 UIManager.setLookAndFeel("com.formdev.flatlaf.FlatLightLaf");
1559  0 set = true;
1560  0 Console.debug("Using FlatLightLaf");
1561    } catch (ClassNotFoundException | InstantiationException
1562    | IllegalAccessException | UnsupportedLookAndFeelException e)
1563    {
1564  0 Console.debug("Exception loading FlatLightLaf", e);
1565    }
1566    }
1567   
1568  186 if (set)
1569    {
1570  186 UIManager.put("TabbedPane.tabType", "card");
1571  186 UIManager.put("TabbedPane.showTabSeparators", true);
1572  186 UIManager.put("TabbedPane.showContentSeparator", true);
1573    // UIManager.put("TabbedPane.tabSeparatorsFullHeight", true);
1574  186 UIManager.put("TabbedPane.tabsOverlapBorder", true);
1575  186 UIManager.put("TabbedPane.hasFullBorder", true);
1576  186 UIManager.put("TabbedPane.tabLayoutPolicy", "scroll");
1577  186 UIManager.put("TabbedPane.scrollButtonsPolicy", "asNeeded");
1578  186 UIManager.put("TabbedPane.smoothScrolling", true);
1579  186 UIManager.put("TabbedPane.tabWidthMode", "compact");
1580  186 UIManager.put("TabbedPane.selectedBackground", Color.white);
1581  186 UIManager.put("TabbedPane.background", new Color(236, 236, 236));
1582  186 UIManager.put("TabbedPane.hoverColor", Color.lightGray);
1583    }
1584   
1585  186 Desktop.setLiveDragMode(Cache.getDefault("FLAT_LIVE_DRAG_MODE", true));
1586  186 return set;
1587    }
1588   
 
1589  0 toggle private static boolean setMacLookAndFeel()
1590    {
1591  0 boolean set = false;
1592  0 System.setProperty("com.apple.mrj.application.apple.menu.about.name",
1593    ChannelProperties.getProperty("app_name"));
1594  0 System.setProperty("apple.laf.useScreenMenuBar", "true");
1595    /*
1596    * broken native LAFs on (ARM?) macbooks
1597    set = setQuaquaLookAndFeel();
1598    if ((!set) || !UIManager.getLookAndFeel().getClass().toString()
1599    .toLowerCase(Locale.ROOT).contains("quaqua"))
1600    {
1601    set = setVaquaLookAndFeel();
1602    }
1603    */
1604  0 set = setFlatLookAndFeel();
1605  0 return set;
1606    }
1607   
 
1608  93 toggle private static boolean setLinuxLookAndFeel()
1609    {
1610  93 boolean set = false;
1611  93 set = setFlatLookAndFeel();
1612  93 if (!set)
1613  0 set = setMetalLookAndFeel();
1614    // avoid GtkLookAndFeel -- not good results especially on HiDPI
1615  93 if (!set)
1616  0 set = setNimbusLookAndFeel();
1617  93 return set;
1618    }
1619   
1620    /*
1621    private static void showUsage()
1622    {
1623    jalview.bin.Console.outPrintln(
1624    "Usage: jalview -open [FILE] [OUTPUT_FORMAT] [OUTPUT_FILE]\n\n"
1625    + "-nodisplay\tRun Jalview without User Interface.\n"
1626    + "-props FILE\tUse the given Jalview properties file instead of users default.\n"
1627    + "-colour COLOURSCHEME\tThe colourscheme to be applied to the alignment\n"
1628    + "-annotations FILE\tAdd precalculated annotations to the alignment.\n"
1629    + "-tree FILE\tLoad the given newick format tree file onto the alignment\n"
1630    + "-features FILE\tUse the given file to mark features on the alignment.\n"
1631    + "-fasta FILE\tCreate alignment file FILE in Fasta format.\n"
1632    + "-clustal FILE\tCreate alignment file FILE in Clustal format.\n"
1633    + "-pfam FILE\tCreate alignment file FILE in PFAM format.\n"
1634    + "-msf FILE\tCreate alignment file FILE in MSF format.\n"
1635    + "-pileup FILE\tCreate alignment file FILE in Pileup format\n"
1636    + "-pir FILE\tCreate alignment file FILE in PIR format.\n"
1637    + "-blc FILE\tCreate alignment file FILE in BLC format.\n"
1638    + "-json FILE\tCreate alignment file FILE in JSON format.\n"
1639    + "-jalview FILE\tCreate alignment file FILE in Jalview format.\n"
1640    + "-png FILE\tCreate PNG image FILE from alignment.\n"
1641    + "-svg FILE\tCreate SVG image FILE from alignment.\n"
1642    + "-html FILE\tCreate HTML file from alignment.\n"
1643    + "-biojsMSA FILE\tCreate BioJS MSA Viewer HTML file from alignment.\n"
1644    + "-imgMap FILE\tCreate HTML file FILE with image map of PNG image.\n"
1645    + "-eps FILE\tCreate EPS file FILE from alignment.\n"
1646    + "-questionnaire URL\tQueries the given URL for information about any Jalview user questionnaires.\n"
1647    + "-noquestionnaire\tTurn off questionnaire check.\n"
1648    + "-nonews\tTurn off check for Jalview news.\n"
1649    + "-nousagestats\tTurn off analytics tracking for this session.\n"
1650    + "-sortbytree OR -nosortbytree\tEnable or disable sorting of the given alignment by the given tree\n"
1651    // +
1652    // "-setprop PROPERTY=VALUE\tSet the given Jalview property,
1653    // after all other properties files have been read\n\t
1654    // (quote the 'PROPERTY=VALUE' pair to ensure spaces are
1655    // passed in correctly)"
1656    + "-jabaws URL\tSpecify URL for Jabaws services (e.g. for a local installation).\n"
1657    + "-fetchfrom nickname\tQuery nickname for features for the alignments and display them.\n"
1658    + "-groovy FILE\tExecute groovy script in FILE, after all other arguments have been processed (if FILE is the text 'STDIN' then the file will be read from STDIN)\n"
1659    + "-jvmmempc=PERCENT\tOnly available with standalone executable jar or jalview.bin.Launcher. Limit maximum heap size (memory) to PERCENT% of total physical memory detected. This defaults to 90 if total physical memory can be detected. See https://www.jalview.org/help/html/memory.html for more details.\n"
1660    + "-jvmmemmax=MAXMEMORY\tOnly available with standalone executable jar or jalview.bin.Launcher. Limit maximum heap size (memory) to MAXMEMORY. MAXMEMORY can be specified in bytes, kilobytes(k), megabytes(m), gigabytes(g) or if you're lucky enough, terabytes(t). This defaults to 32g if total physical memory can be detected, or to 8g if total physical memory cannot be detected. See https://www.jalview.org/help/html/memory.html for more details.\n"
1661    + "\n~Read documentation in Application or visit https://www.jalview.org for description of Features and Annotations file~\n\n");
1662    }
1663    */
1664   
 
1665  87 toggle private static void startUsageStats(final Desktop desktop)
1666    {
1667    /**
1668    * start a User Config prompt asking if we can log usage statistics.
1669    */
1670  87 PromptUserConfig prompter = new PromptUserConfig(Desktop.desktop,
1671    "USAGESTATS",
1672    MessageManager.getString("prompt.analytics_title"),
1673    MessageManager.getString("prompt.analytics"), new Runnable()
1674    {
 
1675  0 toggle @Override
1676    public void run()
1677    {
1678  0 Console.debug("Initialising analytics for usage stats.");
1679  0 Cache.initAnalytics();
1680  0 Console.debug("Tracking enabled.");
1681    }
1682    }, new Runnable()
1683    {
 
1684  39 toggle @Override
1685    public void run()
1686    {
1687  39 Console.debug("Not enabling analytics.");
1688    }
1689    }, null, true);
1690  87 desktop.addDialogThread(prompter);
1691    }
1692   
1693    /**
1694    * Locate the given string as a file and pass it to the groovy interpreter.
1695    *
1696    * @param groovyscript
1697    * the script to execute
1698    * @param jalviewContext
1699    * the Jalview Desktop object passed in to the groovy binding as the
1700    * 'Jalview' object.
1701    */
 
1702  0 toggle protected void executeGroovyScript(String groovyscript, AlignFrame af)
1703    {
1704    /**
1705    * for scripts contained in files
1706    */
1707  0 File tfile = null;
1708    /**
1709    * script's URI
1710    */
1711  0 URL sfile = null;
1712  0 if (groovyscript.trim().equals("STDIN"))
1713    {
1714    // read from stdin into a tempfile and execute it
1715  0 try
1716    {
1717  0 tfile = File.createTempFile("jalview", "groovy");
1718  0 PrintWriter outfile = new PrintWriter(
1719    new OutputStreamWriter(new FileOutputStream(tfile)));
1720  0 BufferedReader br = new BufferedReader(
1721    new InputStreamReader(System.in));
1722  0 String line = null;
1723  0 while ((line = br.readLine()) != null)
1724    {
1725  0 outfile.write(line + "\n");
1726    }
1727  0 br.close();
1728  0 outfile.flush();
1729  0 outfile.close();
1730   
1731    } catch (Exception ex)
1732    {
1733  0 jalview.bin.Console
1734    .errPrintln("Failed to read from STDIN into tempfile "
1735  0 + ((tfile == null) ? "(tempfile wasn't created)"
1736    : tfile.toString()));
1737  0 ex.printStackTrace();
1738  0 return;
1739    }
1740  0 try
1741    {
1742  0 sfile = tfile.toURI().toURL();
1743    } catch (Exception x)
1744    {
1745  0 jalview.bin.Console.errPrintln(
1746    "Unexpected Malformed URL Exception for temporary file created from STDIN: "
1747    + tfile.toURI());
1748  0 x.printStackTrace();
1749  0 return;
1750    }
1751    }
1752    else
1753    {
1754  0 try
1755    {
1756  0 sfile = new URI(groovyscript).toURL();
1757    } catch (Exception x)
1758    {
1759  0 tfile = new File(groovyscript);
1760  0 if (!tfile.exists())
1761    {
1762  0 jalview.bin.Console.errPrintln(
1763    "File '" + groovyscript + "' does not exist.");
1764  0 return;
1765    }
1766  0 if (!tfile.canRead())
1767    {
1768  0 jalview.bin.Console.errPrintln(
1769    "File '" + groovyscript + "' cannot be read.");
1770  0 return;
1771    }
1772  0 if (tfile.length() < 1)
1773    {
1774  0 jalview.bin.Console
1775    .errPrintln("File '" + groovyscript + "' is empty.");
1776  0 return;
1777    }
1778  0 try
1779    {
1780  0 sfile = tfile.getAbsoluteFile().toURI().toURL();
1781    } catch (Exception ex)
1782    {
1783  0 jalview.bin.Console.errPrintln("Failed to create a file URL for "
1784    + tfile.getAbsoluteFile());
1785  0 return;
1786    }
1787    }
1788    }
1789  0 try
1790    {
1791  0 JalviewObjectI j = new JalviewObject(this);
1792  0 Map<String, java.lang.Object> vbinding = new HashMap<>();
1793  0 vbinding.put(JalviewObjectI.jalviewObjectName, j);
1794  0 vbinding.put(JalviewObjectI.currentAlFrameName,
1795  0 af != null ? af : getCurrentAlignFrame());
1796  0 Binding gbinding = new Binding(vbinding);
1797  0 GroovyScriptEngine gse = new GroovyScriptEngine(new URL[] { sfile });
1798  0 gse.run(sfile.toString(), gbinding);
1799  0 if ("STDIN".equals(groovyscript))
1800    {
1801    // delete temp file that we made -
1802    // only if it was successfully executed
1803  0 tfile.delete();
1804    }
1805    } catch (Exception e)
1806    {
1807  0 jalview.bin.Console
1808    .errPrintln("Exception Whilst trying to execute file " + sfile
1809    + " as a groovy script.");
1810  0 e.printStackTrace(System.err);
1811    }
1812    }
1813   
 
1814  1218 toggle public static boolean isHeadlessMode()
1815    {
1816  1218 String isheadless = System.getProperty("java.awt.headless");
1817  1218 if (isheadless != null && isheadless.equalsIgnoreCase("true"))
1818    {
1819  220 return true;
1820    }
1821  998 return false;
1822    }
1823   
 
1824  0 toggle @Override
1825    public AlignFrame[] getAlignFrames()
1826    {
1827  0 return desktop == null ? new AlignFrame[] { getCurrentAlignFrame() }
1828    : Desktop.getDesktopAlignFrames();
1829    }
1830   
1831    /**
1832    * jalview.bin.Jalview.quit() will just run the non-GUI shutdownHook and exit
1833    */
 
1834  0 toggle @Override
1835    public void quit()
1836    {
1837    // System.exit will run the shutdownHook first
1838  0 Jalview.exit("Quitting now. Bye!", ExitCode.OK);
1839    }
1840   
 
1841  0 toggle @Override
1842    public AlignFrame getCurrentAlignFrame()
1843    {
1844  0 return currentAlignFrame;
1845    }
1846   
 
1847  1129 toggle public void setCurrentAlignFrame(AlignFrame af)
1848    {
1849  1129 this.currentAlignFrame = af;
1850    }
1851   
 
1852  381 toggle public Commands getCommands()
1853    {
1854  381 return cmds;
1855    }
1856   
 
1857  27 toggle public static void exit(String message, ExitCode ec)
1858    {
1859  27 int exitcode = ec == ExitCode.OK ? 0 : ec.ordinal() + 1;
1860  27 if (Console.log == null)
1861    {
1862    // Don't start the logger just to exit!
1863  0 if (message != null)
1864    {
1865  0 if (exitcode == 0)
1866    {
1867  0 Console.outPrintln(message);
1868    }
1869    else
1870    {
1871  0 jalview.bin.Console.errPrintln(message);
1872    }
1873    }
1874    }
1875    else
1876    {
1877  27 Console.debug("Using Jalview.exit");
1878  27 if (message != null)
1879    {
1880  27 if (exitcode == 0)
1881    {
1882  27 Console.info(message);
1883    }
1884    else
1885    {
1886  0 Console.error(message);
1887    }
1888    }
1889    }
1890  27 if (exitcode > -1)
1891    {
1892  27 System.exit(exitcode);
1893    }
1894    }
1895   
 
1896    public enum ExitCode
1897    {
1898    // only add new ones to the end of the list (to preserve ordinal values)
1899    OK, FILE_NOT_FOUND, FILE_NOT_READABLE, NO_FILES, INVALID_FORMAT,
1900    INVALID_ARGUMENT, INVALID_VALUE, MIXED_CLI_ARGUMENTS,
1901    ERROR_RUNNING_COMMANDS, NO_LOGGING, GROOVY_ERROR;
1902    }
1903   
1904    /******************************
1905    *
1906    * TEST OUTPUT METHODS
1907    *
1908    * these operate only when Arg.TESTOUTPUT has been passed, and variously check
1909    * if an expected value / arg was set and report it to the test framework.
1910    *
1911    ******************************/
1912    /**
1913    * report string values parsed/processed during tests When the Bootstrap
1914    * argument Arg.TESTOUTPUT is present - reports on debug if given s1 is not
1915    * null and not equals s2, warns if given argument is not set, and calls
1916    * testoutput(true,a,s1,s2) to report processing progress.
1917    *
1918    * @param ap
1919    * - ArgParser handling parsing
1920    * @param a
1921    * - Arg currently being processed
1922    * @param s1
1923    * - expected
1924    * @param s2
1925    */
 
1926  168 toggle protected static void testoutput(ArgParser ap, Arg a, String s1,
1927    String s2)
1928    {
1929  168 BootstrapArgs bsa = ap.getBootstrapArgs();
1930  168 if (!bsa.getBoolean(Arg.TESTOUTPUT))
1931  146 return;
1932  22 if (!((s1 == null && s2 == null) || (s1 != null && s1.equals(s2))))
1933    {
1934  0 Console.debug("testoutput with unmatching values '" + s1 + "' and '"
1935    + s2 + "' for arg " + a.argString());
1936  0 return;
1937    }
1938  22 boolean isset = a.hasOption(Opt.BOOTSTRAP) ? bsa.contains(a)
1939    : ap.isSet(a);
1940  22 if (!isset)
1941    {
1942  0 Console.warn("Arg '" + a.getName() + "' not set at all");
1943  0 return;
1944    }
1945  22 testoutput(true, a, s1, s2);
1946    }
1947   
1948    /**
1949    * report values passed via bootstrap arguments
1950    *
1951    * TODO: significant code duplication with testouput(Argparser...) - move it
1952    */
1953   
 
1954  50 toggle protected static void testoutput(BootstrapArgs bsa, Arg a, String s1,
1955    String s2)
1956    {
1957  50 if (!bsa.getBoolean(Arg.TESTOUTPUT))
1958  48 return;
1959  2 if (!((s1 == null && s2 == null) || (s1 != null && s1.equals(s2))))
1960    {
1961  0 Console.debug("testoutput with unmatching values '" + s1 + "' and '"
1962    + s2 + "' for arg " + a.argString());
1963  0 return;
1964    }
1965  2 if (!a.hasOption(Opt.BOOTSTRAP))
1966    {
1967  0 Console.error("Non-bootstrap Arg '" + a.getName()
1968    + "' given to testoutput(BootstrapArgs bsa, Arg a, String s1, String s2) with only BootstrapArgs");
1969    }
1970  2 if (!bsa.contains(a))
1971    {
1972  0 Console.warn("Arg '" + a.getName() + "' not set at all");
1973  0 return;
1974    }
1975  2 testoutput(true, a, s1, s2);
1976    }
1977   
1978    /**
1979    * conditionally (on @param yes) report that expected value s1 was set during
1980    * CommandsTest tests
1981    */
 
1982  24 toggle private static void testoutput(boolean yes, Arg a, String s1, String s2)
1983    {
1984  24 if (yes && ((s1 == null && s2 == null)
1985    || (s1 != null && s1.equals(s2))))
1986    {
1987  24 Console.outPrintln("[TESTOUTPUT] arg " + a.argString() + "='" + s1
1988    + "' was set");
1989    }
1990    }
1991   
1992    /*
1993    * testoutput for boolean and unary values
1994    */
 
1995  122 toggle protected static void testoutput(ArgParser ap, Arg a)
1996    {
1997  122 if (ap == null)
1998  0 return;
1999  122 BootstrapArgs bsa = ap.getBootstrapArgs();
2000  122 if (bsa == null)
2001  2 return;
2002  120 if (!bsa.getBoolean(Arg.TESTOUTPUT))
2003  117 return;
2004  3 boolean val = a.hasOption(Opt.BOOTSTRAP) ? bsa.getBoolean(a)
2005    : ap.getBoolean(a);
2006  3 boolean isset = a.hasOption(Opt.BOOTSTRAP) ? bsa.contains(a)
2007    : ap.isSet(a);
2008  3 if (!isset)
2009    {
2010  0 Console.warn("Arg '" + a.getName() + "' not set at all");
2011  0 return;
2012    }
2013  3 testoutput(val, a);
2014    }
2015   
 
2016  0 toggle protected static void testoutput(BootstrapArgs bsa, Arg a)
2017    {
2018  0 if (!bsa.getBoolean(Arg.TESTOUTPUT))
2019  0 return;
2020  0 if (!a.hasOption(Opt.BOOTSTRAP))
2021    {
2022  0 Console.warn("Non-bootstrap Arg '" + a.getName()
2023    + "' given to testoutput(BootstrapArgs bsa, Arg a) with only BootstrapArgs");
2024   
2025    }
2026  0 if (!bsa.contains(a))
2027    {
2028  0 Console.warn("Arg '" + a.getName() + "' not set at all");
2029  0 return;
2030    }
2031  0 testoutput(bsa.getBoolean(a), a);
2032    }
2033   
 
2034  3 toggle private static void testoutput(boolean yes, Arg a)
2035    {
2036  3 String message = null;
2037  3 if (a.hasOption(Opt.BOOLEAN))
2038    {
2039  2 message = (yes ? a.argString() : a.negateArgString()) + " was set";
2040    }
2041  1 else if (a.hasOption(Opt.UNARY))
2042    {
2043  1 message = a.argString() + (yes ? " was set" : " was not set");
2044    }
2045  3 Console.outPrintln("[TESTOUTPUT] arg " + message);
2046    }
2047   
 
2048  623 toggle public ArgParser getArgParser()
2049    {
2050  623 return argparser;
2051    }
2052   
 
2053  1262 toggle public BootstrapArgs getBootstrapArgs()
2054    {
2055  1262 return bootstrapArgs;
2056    }
2057   
 
2058  56 toggle public static boolean isBatchMode()
2059    {
2060  56 return getInstance() != null && (getInstance().desktop == null
2061    || getInstance().desktop.isInBatchMode());
2062    }
2063   
2064    /**
2065    * Warning about old or mixed command line arguments
2066    */
 
2067  93 toggle private void mixedCliWarning()
2068    {
2069  93 Jalview j = Jalview.getInstance();
2070  93 boolean mixedStyle = j.getArgParser() != null
2071    && j.getArgParser().isMixedStyle();
2072  93 String title = MessageManager.getString("label.command_line_arguments");
2073  93 if (mixedStyle)
2074    {
2075  0 String warning = MessageManager.formatMessage(
2076    "warning.using_mixed_command_line_arguments",
2077    j.getArgParser().getMixedExamples());
2078  0 String quit = MessageManager.getString("action.quit");
2079   
2080  0 Desktop.instance.nonBlockingDialog(title, warning, null, quit,
2081    JvOptionPane.WARNING_MESSAGE, false, false, true, 30000);
2082   
2083  0 Jalview.exit(
2084    "Exiting due to mixed old and new command line arguments.",
2085    ExitCode.MIXED_CLI_ARGUMENTS);
2086    }
2087    }
2088   
 
2089  117 toggle private void cliWarning()
2090    {
2091  117 Jalview j = Jalview.getInstance();
2092  117 Commands c = j.getCommands();
2093  117 boolean oldStyle = j.getArgParser() != null
2094    && j.getArgParser().isOldStyle();
2095  117 String title = MessageManager.getString("label.command_line_arguments");
2096  117 if (oldStyle)
2097    {
2098  18 String warning = MessageManager
2099    .getString("warning.using_old_command_line_arguments");
2100  18 String url = "<a href=\"https://www.jalview.org/help/html/features/commandline.html\">https://www.jalview.org/help/html/features/commandline.html</a>";
2101  18 if (Desktop.instance != null)
2102    {
2103  1 String cont = MessageManager.getString("label.continue");
2104   
2105  1 Desktop.instance.nonBlockingDialog(title, warning, url, cont,
2106    JvOptionPane.WARNING_MESSAGE, false, true, true, 30000);
2107    }
2108    }
2109  116 if (j.getCommands() != null && j.getCommands().getErrors().size() > 0)
2110    {
2111  0 if (Desktop.instance != null)
2112    {
2113  0 String message = MessageManager
2114    .getString("warning.the_following_errors");
2115  0 String ok = MessageManager.getString("action.ok");
2116  0 int shortest = 60;
2117  0 List<String> errors = j.getCommands().getErrors();
2118  0 for (int i = 0; i < errors.size(); i++)
2119    {
2120  0 shortest = Math.min(shortest, errors.get(i).length());
2121    }
2122  0 Desktop.instance.nonBlockingDialog(
2123    Math.max(message.length(), Math.min(60, shortest)),
2124    Math.min(errors.size(), 20), title, message,
2125    j.getCommands().errorsToString(), ok,
2126    JvOptionPane.WARNING_MESSAGE, true, false, true, -1);
2127    }
2128    }
2129    }
2130   
2131    }