Clover icon

Coverage Report

  1. Project Clover database Thu Nov 7 2024 17:01:39 GMT
  2. Package jalview.bin

File Jalview.java

 

Coverage histogram

../../img/srcFileCovDistChart0.png
0% of files have more coverage

Code metrics

344
732
49
3
2,121
1,655
303
0.41
14.94
16.33
6.18

Classes

Class Line # Actions
Jalview 124 719 299
0.00%
Jalview.FeatureFetcher 191 13 4
0.00%
Jalview.ExitCode 1886 0 0
-1.0 -
 

Contributing tests

No tests hitting this source file were found.

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