1. Project Clover database Fri Dec 6 2024 13:47:14 GMT
  2. Package jalview.bin

File Jalview.java

 

Coverage histogram

../../img/srcFileCovDistChart6.png
37% 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.5279783652.8%
Jalview.FeatureFetcher 191 13 4
0.00%
Jalview.ExitCode 1886 0 0
-1.0 -
 

Contributing tests

This file is covered by 204 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  373 toggle public static boolean quiet()
153    {
154  373 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  3992 toggle public static Jalview getInstance()
245    {
246  3992 return instance;
247    }
248   
249    /**
250    * main class for Jalview application
251    *
252    * @param args
253    * open <em>filename</em>
254    */
 
255  95 toggle public static void main(String[] args)
256    {
257    // setLogging(); // BH - for event debugging in JavaScript
258  95 instance = new Jalview();
259  95 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  131 toggle void doMain(String[] args)
306    {
307  131 if (!Platform.isJS())
308    {
309  131 System.setSecurityManager(null);
310    }
311   
312  131 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  131 bootstrapArgs = BootstrapArgs.getBootstrapArgs(args);
320   
321  131 boolean usingLogfile = false;
322  131 if (!Platform.isJS())
323    {
324    // required to ensure log4j doesn't think it's running in a servlet
325  131 System.setProperty("log4j2.isWebapp", "false");
326   
327    // are we using a logfile?
328  131 String logfilename = System.getProperty("installer.logfile");
329  131 boolean append = Boolean
330    .parseBoolean(System.getProperty("installer.logfile_append"));
331   
332  131 usingLogfile = Console.setLogFile(logfilename, append);
333   
334    // are we being --quiet ? (doesn't matter if using a logfile)
335  131 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  131 if (bootstrapArgs.contains(Arg.HELP)
355    || bootstrapArgs.contains(Arg.VERSION))
356    {
357  0 QUIET = true;
358    }
359    }
360   
361    // set individual session preferences
362  131 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  131 String appdirString = System.getProperty("launcher.appdir");
383  131 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  131 if ((usingLogfile || !quiet()) || !bootstrapArgs.outputToStdout()
397    || bootstrapArgs.contains(Arg.VERSION))
398    {
399  131 if (usingLogfile)
400    {
401  0 Console.outPrintln("-------");
402    }
403  131 Console.outPrint(Cache.getVersionDetailsForConsole());
404  131 if (usingLogfile)
405    {
406  0 Console.outPrintln("-------");
407    }
408    }
409   
410  131 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  131 Properties bootstrapProperties = Cache
417    .bootstrapProperties(bootstrapArgs.getValue(Arg.PROPS));
418   
419    // report Jalview version
420  131 Cache.loadBuildProperties(
421    !quiet() || bootstrapArgs.contains(Arg.VERSION));
422   
423    // stop now if only after --version
424  131 if (bootstrapArgs.contains(Arg.VERSION))
425    {
426  0 Jalview.exit(null, ExitCode.OK);
427    }
428   
429    // old ArgsParser
430  131 ArgsParser aparser = new ArgsParser(args);
431   
432    // old
433  131 boolean headless = false;
434    // new
435  131 boolean headlessArg = false;
436   
437  131 try
438    {
439  131 String logLevel = null;
440  131 if (bootstrapArgs.contains(Arg.TRACE))
441    {
442  0 logLevel = "TRACE";
443    }
444  131 else if (bootstrapArgs.contains(Arg.DEBUG))
445    {
446  10 logLevel = bootstrapArgs.getBoolean(Arg.DEBUG) ? "DEBUG" : "INFO";
447    }
448  131 if (logLevel == null && !(bootstrapProperties == null))
449    {
450  121 logLevel = bootstrapProperties.getProperty(Cache.JALVIEWLOGLEVEL);
451    }
452  131 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  131 Runtime.getRuntime().addShutdownHook(new Thread()
463    {
 
464  109 toggle @Override
465    public void run()
466    {
467  109 Console.debug("Running shutdown hook");
468  108 QuitHandler.startForceQuit();
469  108 boolean closeExternal = Cache
470    .getDefault("DEFAULT_CLOSE_EXTERNAL_VIEWERS", false)
471    || Cache.getDefault("ALWAYS_CLOSE_EXTERNAL_VIEWERS", false);
472  108 StructureViewerBase.setQuitClose(closeExternal);
473  98 if (desktop != null)
474    {
475  58 for (JInternalFrame frame : Desktop.desktop.getAllFrames())
476    {
477  4 if (frame instanceof StructureViewerBase)
478    {
479  1 ((StructureViewerBase) frame).closeViewer(closeExternal);
480    }
481    }
482    }
483   
484  97 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  97 Console.debug("Nothing more to do");
497    }
498  97 Console.debug("Exiting, bye!");
499    // shutdownHook cannot be cancelled, JVM will now halt
500    }
501    });
502   
503  131 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  131 Cache.loadProperties(usrPropsFile);
509  130 if (usrPropsFile != null)
510    {
511  29 Console.outPrintln(
512    "CMD [-props " + usrPropsFile + "] executed successfully!");
513  29 testoutput(bootstrapArgs, Arg.PROPS,
514    "test/jalview/bin/testProps.jvprops", usrPropsFile);
515    }
516   
517    // --argfile=... -- OVERRIDES ALL NON-BOOTSTRAP ARGS
518  130 if (bootstrapArgs.contains(Arg.ARGFILE))
519    {
520  8 argparser = ArgParser.parseArgFiles(
521    bootstrapArgs.getValueList(Arg.ARGFILE),
522    bootstrapArgs.getBoolean(Arg.INITSUBSTITUTIONS),
523    bootstrapArgs);
524    }
525    else
526    {
527  122 argparser = new ArgParser(args,
528    bootstrapArgs.getBoolean(Arg.INITSUBSTITUTIONS),
529    bootstrapArgs);
530    }
531   
532  130 if (!Platform.isJS())
533    /**
534    * Java only
535    *
536    * @j2sIgnore
537    */
538    {
539  130 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  130 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  130 headlessArg = bootstrapArgs.isHeadless();
559  130 if (headlessArg)
560    {
561  32 System.setProperty("java.awt.headless", "true");
562    }
563    // old CLI
564  130 if (aparser.contains("nodisplay") || aparser.contains("nogui")
565    || aparser.contains("headless"))
566    {
567  17 System.setProperty("java.awt.headless", "true");
568  17 headless = true;
569    }
570    // anything else!
571   
572    // allow https handshakes to download intermediate certs if necessary
573  130 System.setProperty("com.sun.security.enableAIAcaIssuers", "true");
574   
575  130 String jabawsUrl = bootstrapArgs.getValue(Arg.JABAWS);
576  130 if (jabawsUrl == null)
577  129 jabawsUrl = aparser.getValue("jabaws");
578  130 if (jabawsUrl != null)
579    {
580  2 try
581    {
582  2 Jws2Discoverer.getDiscoverer().setPreferredUrl(jabawsUrl);
583  2 Console.outPrintln(
584    "CMD [-jabaws " + jabawsUrl + "] executed successfully!");
585  2 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  130 List<String> setprops = new ArrayList<>();
596  130 if (bootstrapArgs.contains(Arg.SETPROP))
597    {
598  0 setprops = bootstrapArgs.getValueList(Arg.SETPROP);
599    }
600    else
601    {
602  130 String sp = aparser.getValue("setprop");
603  130 while (sp != null)
604    {
605  0 setprops.add(sp);
606  0 sp = aparser.getValue("setprop");
607    }
608    }
609  130 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  130 if (System.getProperty("java.awt.headless") != null
632    && System.getProperty("java.awt.headless").equals("true"))
633    {
634  55 headless = true;
635    }
636  130 System.setProperty("http.agent", UserAgent.getUserAgent());
637   
638    // Initialise the logger
639  130 try
640    {
641  130 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  130 desktop = null;
650   
651  130 if (!(headless || headlessArg))
652  75 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  130 boolean soDefault = !Platform.isJS();
659  130 if (Cache.getDefault("USE_FULL_SO", soDefault))
660    {
661  130 SequenceOntologyFactory.setInstance(new SequenceOntology());
662    }
663   
664  130 if (!(headless || headlessArg))
665    {
666  75 Desktop.nosplash = "false".equals(bootstrapArgs.getValue(Arg.SPLASH))
667    || aparser.contains("nosplash")
668    || Cache.getDefault("SPLASH", "true").equals("false");
669  75 desktop = new Desktop();
670  75 desktop.setInBatchMode(true); // indicate we are starting up
671   
672  75 mixedCliWarning();
673   
674  75 try
675    {
676  75 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  75 Cache.setProxyPropertiesFromPreferences();
691   
692  75 desktop.setVisible(true);
693   
694  75 if (!Platform.isJS())
695    /**
696    * Java only
697    *
698    * @j2sIgnore
699    */
700    {
701   
702  75 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  75 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  75 String installerappdirString = System
738    .getProperty("installer.appdir");
739  75 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  75 boolean webservicediscovery = bootstrapArgs
757    .getBoolean(Arg.WEBSERVICEDISCOVERY);
758  75 if (aparser.contains("nowebservicediscovery"))
759  0 webservicediscovery = false;
760  75 if (webservicediscovery)
761    {
762  65 desktop.startServiceDiscovery();
763    }
764    else
765    {
766  10 testoutput(argparser, Arg.WEBSERVICEDISCOVERY);
767    }
768   
769  75 boolean usagestats = !bootstrapArgs.getBoolean(Arg.NOUSAGESTATS);
770  75 if (aparser.contains("nousagestats"))
771  1 usagestats = false;
772  75 if (usagestats)
773    {
774  69 startUsageStats(desktop);
775  69 testoutput(argparser, Arg.NOUSAGESTATS);
776    }
777    else
778    {
779  6 Console.outPrintln("CMD [-nousagestats] executed successfully!");
780  6 testoutput(argparser, Arg.NOUSAGESTATS);
781    }
782   
783  75 boolean questionnaire = bootstrapArgs.getBoolean(Arg.QUESTIONNAIRE);
784  75 if (aparser.contains("noquestionnaire"))
785  1 questionnaire = false;
786  75 if (questionnaire)
787    {
788  67 String url = aparser.getValue("questionnaire");
789  67 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  67 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  36 String defurl = "https://www.jalview.org/cgi-bin/questionnaire.pl";
808  36 Console.debug(
809    "Starting questionnaire with default url: " + defurl);
810  36 desktop.checkForQuestionnaire(defurl);
811    }
812    }
813    }
814    else
815    {
816  8 Console.outPrintln(
817    "CMD [-noquestionnaire] executed successfully!");
818  8 testoutput(argparser, Arg.QUESTIONNAIRE);
819    }
820   
821  75 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  42 desktop.checkForNews();
827    }
828   
829  75 if (!aparser.contains("nohtmltemplates")
830    && Cache.getProperty("NOHTMLTEMPLATES") == null)
831    {
832  75 BioJsHTMLOutput.updateBioJS();
833    }
834    }
835    }
836    else
837    {
838   
839  55 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  55 if (getArgParser().isOldStyle())
850    {
851  17 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  17 Console.warn(warning);
856    }
857   
858    }
859   
860    // Run Commands from cli
861  130 cmds = new Commands(argparser, headlessArg);
862  130 cmds.processArgs();
863  125 boolean commandsSuccess = cmds.argsWereParsed();
864   
865  125 if (commandsSuccess)
866    {
867  77 if (headlessArg)
868    {
869  32 if (argparser.getBoolean(Arg.NOQUIT))
870    {
871  6 Console.warn(
872    "Completed " + Arg.HEADLESS.getName() + " commands, but "
873    + Arg.NOQUIT + " is set so not quitting!");
874    }
875    else
876    {
877  26 Jalview.exit("Successfully completed commands in headless mode",
878    ExitCode.OK);
879    }
880    }
881  51 Console.info("Successfully completed commands");
882    }
883    else
884    {
885  48 if (headlessArg)
886    {
887  0 Jalview.exit("Error when running Commands in headless mode",
888    ExitCode.ERROR_RUNNING_COMMANDS);
889    }
890  48 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  99 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  99 String file = null, data = null;
904   
905  99 FileFormatI format = null;
906   
907  99 DataSourceType protocol = null;
908   
909  99 FileLoader fileLoader = new FileLoader(!headless);
910   
911  99 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  99 groovyscript = aparser.getValue("groovy", true);
915  99 file = aparser.getValue("open", true);
916   
917  99 if (file == null && desktop == null && !commandsSuccess)
918    {
919  0 Jalview.exit("No files to open!", ExitCode.NO_FILES);
920    }
921   
922  99 long progress = -1;
923    // Finally, deal with the remaining input data.
924  99 if (file != null)
925    {
926  18 if (!headless)
927    {
928  1 desktop.setProgressBar(
929    MessageManager
930    .getString("status.processing_commandline_args"),
931    progress = System.currentTimeMillis());
932    }
933  18 Console.outPrintln("CMD [-open " + file + "] executed successfully!");
934   
935  18 if (!Platform.isJS())
936    /**
937    * ignore in JavaScript -- can't just file existence - could load it?
938    *
939    * @j2sIgnore
940    */
941    {
942  18 if (!HttpUtils.startsWithHttpOrHttps(file))
943    {
944  18 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  18 protocol = AppletFormatAdapter.checkProtocol(file);
958   
959  18 try
960    {
961  18 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  18 AlignFrame af = fileLoader.LoadFileWaitTillLoaded(file, protocol,
971    format);
972  18 if (af == null)
973    {
974  0 Console.outPrintln("error");
975    }
976    else
977    {
978  18 setCurrentAlignFrame(af);
979  18 data = aparser.getValue("colour", true);
980  18 if (data != null)
981    {
982  1 data.replaceAll("%20", " ");
983   
984  1 ColourSchemeI cs = ColourSchemeProperty.getColourScheme(
985    af.getViewport(), af.getViewport().getAlignment(), data);
986   
987  1 if (cs != null)
988    {
989  1 Console.outPrintln(
990    "CMD [-colour " + data + "] executed successfully!");
991    }
992  1 af.changeColour(cs);
993    }
994   
995    // Must maintain ability to use the groups flag
996  18 data = aparser.getValue("groups", true);
997  18 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  18 data = aparser.getValue("features", true);
1006  18 if (data != null)
1007    {
1008  1 af.parseFeaturesFile(data,
1009    AppletFormatAdapter.checkProtocol(data));
1010    // Console.outPrintln("Added " + data);
1011  1 Console.outPrintln(
1012    "CMD [-features " + data + "] executed successfully!");
1013    }
1014   
1015  18 data = aparser.getValue("annotations", true);
1016  18 if (data != null)
1017    {
1018  1 af.loadJalviewDataFile(data, null, null, null);
1019    // Console.outPrintln("Added " + data);
1020  1 Console.outPrintln(
1021    "CMD [-annotations " + data + "] executed successfully!");
1022    }
1023    // set or clear the sortbytree flag.
1024  18 if (aparser.contains("sortbytree"))
1025    {
1026  1 af.getViewport().setSortByTree(true);
1027  1 if (af.getViewport().getSortByTree())
1028    {
1029  1 Console.outPrintln("CMD [-sortbytree] executed successfully!");
1030    }
1031    }
1032  18 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  18 if (aparser.contains("nosortbytree"))
1041    {
1042  1 af.getViewport().setSortByTree(false);
1043  1 if (!af.getViewport().getSortByTree())
1044    {
1045  1 Console.outPrintln(
1046    "CMD [-nosortbytree] executed successfully!");
1047    }
1048    }
1049  18 data = aparser.getValue("tree", true);
1050  18 if (data != null)
1051    {
1052  1 try
1053    {
1054  1 Console.outPrintln(
1055    "CMD [-tree " + data + "] executed successfully!");
1056  1 NewickFile nf = new NewickFile(data,
1057    AppletFormatAdapter.checkProtocol(data));
1058  1 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  18 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  18 String imageName = "unnamed.png";
1078  34 while (aparser.getSize() > 1)
1079    {
1080  16 try
1081    {
1082  16 String outputFormat = aparser.nextValue();
1083  16 file = aparser.nextValue();
1084   
1085  16 if (outputFormat.equalsIgnoreCase("png"))
1086    {
1087  1 Console.outPrintln("Creating PNG image: " + file);
1088  1 af.createPNG(new File(file));
1089  1 imageName = (new File(file)).getName();
1090  1 continue;
1091    }
1092  15 else if (outputFormat.equalsIgnoreCase("svg"))
1093    {
1094  1 Console.outPrintln("Creating SVG image: " + file);
1095  1 File imageFile = new File(file);
1096  1 imageName = imageFile.getName();
1097  1 af.createSVG(imageFile);
1098  1 continue;
1099    }
1100  14 else if (outputFormat.equalsIgnoreCase("html"))
1101    {
1102  1 File imageFile = new File(file);
1103  1 imageName = imageFile.getName();
1104  1 HtmlSvgOutput htmlSVG = new HtmlSvgOutput(af.alignPanel);
1105   
1106  1 Console.outPrintln("Creating HTML image: " + file);
1107  1 htmlSVG.exportHTML(file);
1108  1 continue;
1109    }
1110  13 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  13 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  13 else if (outputFormat.equalsIgnoreCase("eps"))
1139    {
1140  5 File outputFile = new File(file);
1141  5 Console.outPrintln(
1142    "Creating EPS file: " + outputFile.getAbsolutePath());
1143  5 af.createEPS(outputFile);
1144  5 continue;
1145    }
1146   
1147  8 FileFormatI outFormat = null;
1148  8 try
1149    {
1150  8 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  8 if (outFormat != null)
1157    {
1158  8 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  8 af.saveAlignment(file, outFormat);
1167  8 if (af.isSaveAlignmentSuccessful())
1168    {
1169  8 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  18 while (aparser.getSize() > 0)
1189    {
1190  0 Console.outPrintln("Unknown arg: " + aparser.nextValue());
1191    }
1192    }
1193    }
1194   
1195  99 AlignFrame startUpAlframe = null;
1196    // We'll only open the default file if the desktop is visible.
1197    // And the user
1198    // ////////////////////
1199   
1200  99 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  99 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  99 if (desktop != null)
1273    {
1274  70 if (progress != -1)
1275    {
1276  1 desktop.setProgressBar(null, progress);
1277    }
1278  70 desktop.setInBatchMode(false);
1279    }
1280   
1281  99 cliWarning();
1282    }
1283   
 
1284  75 toggle private static void setLookAndFeel()
1285    {
1286  75 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  75 String lafProp = System.getProperty("laf");
1299  75 String lafSetting = Cache.getDefault("PREFERRED_LAF", null);
1300  75 String laf = "none";
1301  75 if (lafProp != null)
1302    {
1303  0 laf = lafProp;
1304    }
1305  75 else if (lafSetting != null)
1306    {
1307  0 laf = lafSetting;
1308    }
1309  75 boolean lafSet = false;
1310  75 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  75 case "none":
1362  75 break;
1363  0 default:
1364  0 Console.error("Requested laf=" + laf + " not implemented");
1365    }
1366  75 if (!lafSet)
1367    {
1368    // Flatlaf default for everyone!
1369  75 lafSet = setFlatLookAndFeel();
1370  75 if (!lafSet)
1371    {
1372  0 setSystemLookAndFeel();
1373    }
1374  75 if (Platform.isLinux())
1375    {
1376  75 setLinuxLookAndFeel();
1377    }
1378  75 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  150 toggle private static boolean setFlatLookAndFeel()
1467    {
1468  150 boolean set = false;
1469  150 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  150 if (!set)
1504    {
1505  150 try
1506    {
1507  150 UIManager.setLookAndFeel("com.formdev.flatlaf.FlatLightLaf");
1508  150 set = true;
1509  150 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  150 SwingUtilities.invokeLater(() -> {
1517  150 FlatLightLaf.setup();
1518    });
1519  150 Console.debug("Using FlatLightLaf");
1520  150 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  150 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  150 if (set)
1559    {
1560  150 UIManager.put("TabbedPane.tabType", "card");
1561  150 UIManager.put("TabbedPane.showTabSeparators", true);
1562  150 UIManager.put("TabbedPane.showContentSeparator", true);
1563    // UIManager.put("TabbedPane.tabSeparatorsFullHeight", true);
1564  150 UIManager.put("TabbedPane.tabsOverlapBorder", true);
1565  150 UIManager.put("TabbedPane.hasFullBorder", true);
1566  150 UIManager.put("TabbedPane.tabLayoutPolicy", "scroll");
1567  150 UIManager.put("TabbedPane.scrollButtonsPolicy", "asNeeded");
1568  150 UIManager.put("TabbedPane.smoothScrolling", true);
1569  150 UIManager.put("TabbedPane.tabWidthMode", "compact");
1570  150 UIManager.put("TabbedPane.selectedBackground", Color.white);
1571  150 UIManager.put("TabbedPane.background", new Color(236, 236, 236));
1572  150 UIManager.put("TabbedPane.hoverColor", Color.lightGray);
1573    }
1574   
1575  150 Desktop.setLiveDragMode(Cache.getDefault("FLAT_LIVE_DRAG_MODE", true));
1576  150 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  75 toggle private static boolean setLinuxLookAndFeel()
1599    {
1600  75 boolean set = false;
1601  75 set = setFlatLookAndFeel();
1602  75 if (!set)
1603  0 set = setMetalLookAndFeel();
1604    // avoid GtkLookAndFeel -- not good results especially on HiDPI
1605  75 if (!set)
1606  0 set = setNimbusLookAndFeel();
1607  75 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  69 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  69 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  26 toggle @Override
1675    public void run()
1676    {
1677  26 Console.debug("Not enabling analytics.");
1678    }
1679    }, null, true);
1680  69 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  1115 toggle public static boolean isHeadlessMode()
1805    {
1806  1115 String isheadless = System.getProperty("java.awt.headless");
1807  1115 if (isheadless != null && isheadless.equalsIgnoreCase("true"))
1808    {
1809  220 return true;
1810    }
1811  895 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  1047 toggle public void setCurrentAlignFrame(AlignFrame af)
1838    {
1839  1047 this.currentAlignFrame = af;
1840    }
1841   
 
1842  327 toggle public Commands getCommands()
1843    {
1844  327 return cmds;
1845    }
1846   
 
1847  27 toggle public static void exit(String message, ExitCode ec)
1848    {
1849  27 int exitcode = ec == ExitCode.OK ? 0 : ec.ordinal() + 1;
1850  27 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  27 Console.debug("Using Jalview.exit");
1868  27 if (message != null)
1869    {
1870  27 if (exitcode == 0)
1871    {
1872  27 Console.info(message);
1873    }
1874    else
1875    {
1876  0 Console.error(message);
1877    }
1878    }
1879    }
1880  27 if (exitcode > -1)
1881    {
1882  27 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  149 toggle protected static void testoutput(ArgParser ap, Arg a, String s1,
1917    String s2)
1918    {
1919  149 BootstrapArgs bsa = ap.getBootstrapArgs();
1920  149 if (!bsa.getBoolean(Arg.TESTOUTPUT))
1921  127 return;
1922  22 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  22 boolean isset = a.hasOption(Opt.BOOTSTRAP) ? bsa.contains(a)
1929    : ap.isSet(a);
1930  22 if (!isset)
1931    {
1932  0 Console.warn("Arg '" + a.getName() + "' not set at all");
1933  0 return;
1934    }
1935  22 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  31 toggle protected static void testoutput(BootstrapArgs bsa, Arg a, String s1,
1945    String s2)
1946    {
1947  31 if (!bsa.getBoolean(Arg.TESTOUTPUT))
1948  29 return;
1949  2 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  2 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  2 if (!bsa.contains(a))
1961    {
1962  0 Console.warn("Arg '" + a.getName() + "' not set at all");
1963  0 return;
1964    }
1965  2 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  24 toggle private static void testoutput(boolean yes, Arg a, String s1, String s2)
1973    {
1974  24 if (yes && ((s1 == null && s2 == null)
1975    || (s1 != null && s1.equals(s2))))
1976    {
1977  24 Console.outPrintln("[TESTOUTPUT] arg " + a.argString() + "='" + s1
1978    + "' was set");
1979    }
1980    }
1981   
1982    /*
1983    * testoutput for boolean and unary values
1984    */
 
1985  94 toggle protected static void testoutput(ArgParser ap, Arg a)
1986    {
1987  94 if (ap == null)
1988  0 return;
1989  94 BootstrapArgs bsa = ap.getBootstrapArgs();
1990  94 if (bsa == null)
1991  2 return;
1992  92 if (!bsa.getBoolean(Arg.TESTOUTPUT))
1993  89 return;
1994  3 boolean val = a.hasOption(Opt.BOOTSTRAP) ? bsa.getBoolean(a)
1995    : ap.getBoolean(a);
1996  3 boolean isset = a.hasOption(Opt.BOOTSTRAP) ? bsa.contains(a)
1997    : ap.isSet(a);
1998  3 if (!isset)
1999    {
2000  0 Console.warn("Arg '" + a.getName() + "' not set at all");
2001  0 return;
2002    }
2003  3 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  3 toggle private static void testoutput(boolean yes, Arg a)
2025    {
2026  3 String message = null;
2027  3 if (a.hasOption(Opt.BOOLEAN))
2028    {
2029  2 message = (yes ? a.argString() : a.negateArgString()) + " was set";
2030    }
2031  1 else if (a.hasOption(Opt.UNARY))
2032    {
2033  1 message = a.argString() + (yes ? " was set" : " was not set");
2034    }
2035  3 Console.outPrintln("[TESTOUTPUT] arg " + message);
2036    }
2037   
 
2038  533 toggle public ArgParser getArgParser()
2039    {
2040  533 return argparser;
2041    }
2042   
 
2043  1102 toggle public BootstrapArgs getBootstrapArgs()
2044    {
2045  1102 return bootstrapArgs;
2046    }
2047   
 
2048  27 toggle public static boolean isBatchMode()
2049    {
2050  27 return getInstance() != null && (getInstance().desktop == null
2051    || getInstance().desktop.isInBatchMode());
2052    }
2053   
2054    /**
2055    * Warning about old or mixed command line arguments
2056    */
 
2057  75 toggle private void mixedCliWarning()
2058    {
2059  75 Jalview j = Jalview.getInstance();
2060  75 boolean mixedStyle = j.getArgParser() != null
2061    && j.getArgParser().isMixedStyle();
2062  75 String title = MessageManager.getString("label.command_line_arguments");
2063  75 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  99 toggle private void cliWarning()
2080    {
2081  99 Jalview j = Jalview.getInstance();
2082  99 Commands c = j.getCommands();
2083  99 boolean oldStyle = j.getArgParser() != null
2084    && j.getArgParser().isOldStyle();
2085  99 String title = MessageManager.getString("label.command_line_arguments");
2086  99 if (oldStyle)
2087    {
2088  18 String warning = MessageManager
2089    .getString("warning.using_old_command_line_arguments");
2090  18 String url = "<a href=\"https://www.jalview.org/help/html/features/commandline.html\">https://www.jalview.org/help/html/features/commandline.html</a>";
2091  18 if (Desktop.instance != null)
2092    {
2093  1 String cont = MessageManager.getString("label.continue");
2094   
2095  1 Desktop.instance.nonBlockingDialog(title, warning, url, cont,
2096    JvOptionPane.WARNING_MESSAGE, false, true, true, 30000);
2097    }
2098    }
2099  98 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    }