2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
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.
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.
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.
23 import java.awt.Color;
24 import java.io.BufferedReader;
26 import java.io.FileOutputStream;
27 import java.io.IOException;
28 import java.io.InputStreamReader;
29 import java.io.OutputStream;
30 import java.io.OutputStreamWriter;
31 import java.io.PrintStream;
32 import java.io.PrintWriter;
33 import java.net.MalformedURLException;
35 import java.net.URISyntaxException;
37 import java.security.AllPermission;
38 import java.security.CodeSource;
39 import java.security.PermissionCollection;
40 import java.security.Permissions;
41 import java.security.Policy;
42 import java.util.ArrayList;
43 import java.util.HashMap;
44 import java.util.List;
45 import java.util.Locale;
47 import java.util.Properties;
48 import java.util.Vector;
49 import java.util.logging.ConsoleHandler;
50 import java.util.logging.Level;
51 import java.util.logging.Logger;
52 import java.util.stream.Collectors;
54 import javax.swing.JDialog;
55 import javax.swing.JFrame;
56 import javax.swing.JInternalFrame;
57 import javax.swing.JOptionPane;
58 import javax.swing.SwingUtilities;
59 import javax.swing.UIManager;
60 import javax.swing.UIManager.LookAndFeelInfo;
61 import javax.swing.UnsupportedLookAndFeelException;
63 import com.formdev.flatlaf.FlatLightLaf;
64 import com.formdev.flatlaf.themes.FlatMacLightLaf;
65 import com.formdev.flatlaf.util.SystemInfo;
66 import com.threerings.getdown.util.LaunchUtil;
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.ext.so.SequenceOntology;
77 import jalview.gui.AlignFrame;
78 import jalview.gui.Desktop;
79 import jalview.gui.PromptUserConfig;
80 import jalview.gui.QuitHandler;
81 import jalview.gui.QuitHandler.QResponse;
82 import jalview.gui.StructureViewerBase;
83 import jalview.io.AppletFormatAdapter;
84 import jalview.io.BioJsHTMLOutput;
85 import jalview.io.DataSourceType;
86 import jalview.io.FileFormat;
87 import jalview.io.FileFormatException;
88 import jalview.io.FileFormatI;
89 import jalview.io.FileFormats;
90 import jalview.io.FileLoader;
91 import jalview.io.HtmlSvgOutput;
92 import jalview.io.IdentifyFile;
93 import jalview.io.NewickFile;
94 import jalview.io.exceptions.ImageOutputException;
95 import jalview.io.gff.SequenceOntologyFactory;
96 import jalview.schemes.ColourSchemeI;
97 import jalview.schemes.ColourSchemeProperty;
98 import jalview.util.ChannelProperties;
99 import jalview.util.HttpUtils;
100 import jalview.util.LaunchUtils;
101 import jalview.util.MessageManager;
102 import jalview.util.Platform;
103 import jalview.ws.jws2.Jws2Discoverer;
106 * Main class for Jalview Application <br>
108 * start with: java -classpath "$PATH_TO_LIB$/*:$PATH_TO_CLASSES$" \
109 * jalview.bin.Jalview
111 * or on Windows: java -classpath "$PATH_TO_LIB$/*;$PATH_TO_CLASSES$" \
112 * jalview.bin.Jalview jalview.bin.Jalview
114 * (ensure -classpath arg is quoted to avoid shell expansion of '*' and do not
115 * embellish '*' to e.g. '*.jar')
118 * @version $Revision$
124 Platform.getURLCommandArguments();
125 Platform.addJ2SDirectDatabaseCall("https://www.jalview.org");
126 Platform.addJ2SDirectDatabaseCall("http://www.jalview.org");
127 Platform.addJ2SDirectDatabaseCall("http://www.compbio.dundee.ac.uk");
128 Platform.addJ2SDirectDatabaseCall("https://www.compbio.dundee.ac.uk");
132 * singleton instance of this class
134 private static Jalview instance;
136 private Desktop desktop;
138 protected Commands cmds;
140 public static AlignFrame currentAlignFrame;
142 public ArgParser argparser = null;
144 public BootstrapArgs bootstrapArgs = null;
146 private boolean QUIET = false;
148 public static boolean quiet()
150 return Jalview.getInstance() != null && Jalview.getInstance().QUIET;
155 if (!Platform.isJS())
162 // grab all the rights we can for the JVM
163 Policy.setPolicy(new Policy()
166 public PermissionCollection getPermissions(CodeSource codesource)
168 Permissions perms = new Permissions();
169 perms.add(new AllPermission());
174 public void refresh()
182 * keep track of feature fetching tasks.
190 * TODO: generalise to track all jalview events to orchestrate batch processing
194 private int queued = 0;
196 private int running = 0;
198 public FeatureFetcher()
203 public void addFetcher(final AlignFrame af,
204 final Vector<String> dasSources)
206 final long id = System.currentTimeMillis();
208 final FeatureFetcher us = this;
209 new Thread(new Runnable()
221 af.setProgressBar(MessageManager
222 .getString("status.das_features_being_retrived"), id);
223 af.featureSettings_actionPerformed(null);
224 af.setProgressBar(null, id);
233 public synchronized boolean allFinished()
235 return queued == 0 && running == 0;
240 public static Jalview getInstance()
246 * main class for Jalview application
249 * open <em>filename</em>
251 public static void main(String[] args)
253 // setLogging(); // BH - for event debugging in JavaScript
254 instance = new Jalview();
255 instance.doMain(args);
258 private static void logClass(String name)
260 // BH - for event debugging in JavaScript
261 ConsoleHandler consoleHandler = new ConsoleHandler();
262 consoleHandler.setLevel(Level.ALL);
263 Logger logger = Logger.getLogger(name);
264 logger.setLevel(Level.ALL);
265 logger.addHandler(consoleHandler);
268 @SuppressWarnings("unused")
269 private static void setLogging()
277 Console.outPrintln("not in js");
280 // BH - for event debugging in JavaScript (Java mode only)
281 if (!Platform.isJS())
288 Logger.getLogger("").setLevel(Level.ALL);
289 logClass("java.awt.EventDispatchThread");
290 logClass("java.awt.EventQueue");
291 logClass("java.awt.Component");
292 logClass("java.awt.focus.Component");
293 logClass("java.awt.focus.DefaultKeyboardFocusManager");
301 void doMain(String[] args)
303 if (!Platform.isJS())
305 System.setSecurityManager(null);
308 if (args == null || args.length == 0 || (args.length == 1
309 && (args[0] == null || args[0].length() == 0)))
311 args = new String[] {};
314 // get args needed before proper ArgParser
315 bootstrapArgs = BootstrapArgs.getBootstrapArgs(args);
317 if (!Platform.isJS())
319 // are we being --quiet ?
320 if (bootstrapArgs.contains(Arg.QUIET))
323 OutputStream devNull = new OutputStream()
327 public void write(int b)
332 System.setOut(new PrintStream(devNull));
333 // redirecting stderr not working
334 if (bootstrapArgs.getList(Arg.QUIET).size() > 1)
336 System.setErr(new PrintStream(devNull));
340 if (bootstrapArgs.contains(Arg.HELP)
341 || bootstrapArgs.contains(Arg.VERSION))
347 // set individual session preferences
348 if (bootstrapArgs.contains(Arg.P))
350 for (String kev : bootstrapArgs.getValueList(Arg.P))
356 int equalsIndex = kev.indexOf(ArgParser.EQUALS);
357 if (equalsIndex > -1)
359 String key = kev.substring(0, equalsIndex);
360 String val = kev.substring(equalsIndex + 1);
361 Cache.setSessionProperty(key, val);
366 // Move any new getdown-launcher-new.jar into place over old
367 // getdown-launcher.jar
368 String appdirString = System.getProperty("getdownappdir");
369 if (appdirString != null && appdirString.length() > 0)
371 final File appdir = new File(appdirString);
378 LaunchUtil.upgradeGetdown(
379 new File(appdir, "getdown-launcher-old.jar"),
380 new File(appdir, "getdown-launcher.jar"),
381 new File(appdir, "getdown-launcher-new.jar"));
386 if (!quiet() || !bootstrapArgs.outputToStdout()
387 || bootstrapArgs.contains(Arg.VERSION))
390 "Java version: " + System.getProperty("java.version"));
391 Console.outPrintln("Java home: " + System.getProperty("java.home"));
392 Console.outPrintln("Java arch: " + System.getProperty("os.arch") + " "
393 + System.getProperty("os.name") + " "
394 + System.getProperty("os.version"));
396 String val = System.getProperty("sys.install4jVersion");
399 Console.outPrintln("Install4j version: " + val);
401 val = System.getProperty("installer_template_version");
404 Console.outPrintln("Install4j template version: " + val);
406 val = System.getProperty("launcher_version");
409 Console.outPrintln("Launcher version: " + val);
413 if (Platform.isLinux() && LaunchUtils.getJavaVersion() < 11)
415 System.setProperty("flatlaf.uiScale", "1");
418 // get bootstrap properties (mainly for the logger level)
419 Properties bootstrapProperties = Cache
420 .bootstrapProperties(bootstrapArgs.getValue(Arg.PROPS));
422 // report Jalview version
423 Cache.loadBuildProperties(
424 !quiet() || bootstrapArgs.contains(Arg.VERSION));
426 // stop now if only after --version
427 if (bootstrapArgs.contains(Arg.VERSION))
429 Jalview.exit(null, 0);
433 ArgsParser aparser = new ArgsParser(args);
436 boolean headless = false;
438 boolean headlessArg = false;
442 String logLevel = null;
443 if (bootstrapArgs.contains(Arg.TRACE))
447 else if (bootstrapArgs.contains(Arg.DEBUG))
451 if (logLevel == null && !(bootstrapProperties == null))
453 logLevel = bootstrapProperties.getProperty(Cache.JALVIEWLOGLEVEL);
455 Console.initLogger(logLevel);
456 } catch (NoClassDefFoundError error)
458 error.printStackTrace();
459 String message = "\nEssential logging libraries not found."
460 + "\nUse: java -classpath \"$PATH_TO_LIB$/*:$PATH_TO_CLASSES$\" jalview.bin.Jalview";
461 Jalview.exit(message, 0);
464 // register SIGTERM listener
465 Runtime.getRuntime().addShutdownHook(new Thread()
470 Console.debug("Running shutdown hook");
471 QuitHandler.startForceQuit();
472 boolean closeExternal = Cache
473 .getDefault("DEFAULT_CLOSE_EXTERNAL_VIEWERS", false)
474 || Cache.getDefault("ALWAYS_CLOSE_EXTERNAL_VIEWERS", false);
475 StructureViewerBase.setQuitClose(closeExternal);
478 for (JInternalFrame frame : Desktop.desktop.getAllFrames())
480 if (frame instanceof StructureViewerBase)
482 ((StructureViewerBase) frame).closeViewer(closeExternal);
487 if (QuitHandler.gotQuitResponse() == QResponse.CANCEL_QUIT)
489 // Got to here by a SIGTERM signal.
490 // Note we will not actually cancel the quit from here -- it's too
491 // late -- but we can wait for saving files and close external viewers
493 // Close viewers/Leave viewers open
494 Console.debug("Checking for saving files");
495 QuitHandler.getQuitResponse(false);
499 Console.debug("Nothing more to do");
501 Console.debug("Exiting, bye!");
502 // shutdownHook cannot be cancelled, JVM will now halt
506 String usrPropsFile = bootstrapArgs.contains(Arg.PROPS)
507 ? bootstrapArgs.getValue(Arg.PROPS)
508 : aparser.getValue("props");
509 // if usrPropsFile == null, loadProperties will use the Channel
511 Cache.loadProperties(usrPropsFile);
512 if (usrPropsFile != null)
515 "CMD [-props " + usrPropsFile + "] executed successfully!");
516 testoutput(bootstrapArgs, Arg.PROPS,
517 "test/jalview/bin/testProps.jvprops", usrPropsFile);
520 // --argfile=... -- OVERRIDES ALL NON-BOOTSTRAP ARGS
521 if (bootstrapArgs.contains(Arg.ARGFILE))
523 argparser = ArgParser.parseArgFiles(
524 bootstrapArgs.getValueList(Arg.ARGFILE),
525 bootstrapArgs.getBoolean(Arg.INITSUBSTITUTIONS),
530 argparser = new ArgParser(args,
531 bootstrapArgs.getBoolean(Arg.INITSUBSTITUTIONS),
535 if (!Platform.isJS())
542 if (bootstrapArgs.contains(Arg.HELP))
544 List<Map.Entry<Type, String>> helpArgs = bootstrapArgs
546 Console.outPrintln(Arg.usage(helpArgs.stream().map(e -> e.getKey())
547 .collect(Collectors.toList())));
548 Jalview.exit(null, 0);
550 if (aparser.contains("help") || aparser.contains("h"))
553 * Now using new usage statement.
556 Console.outPrintln(Arg.usage());
557 Jalview.exit(null, 0);
561 headlessArg = bootstrapArgs.isHeadless();
564 System.setProperty("java.awt.headless", "true");
567 if (aparser.contains("nodisplay") || aparser.contains("nogui")
568 || aparser.contains("headless"))
570 System.setProperty("java.awt.headless", "true");
575 // allow https handshakes to download intermediate certs if necessary
576 System.setProperty("com.sun.security.enableAIAcaIssuers", "true");
578 String jabawsUrl = bootstrapArgs.getValue(Arg.JABAWS);
579 if (jabawsUrl == null)
580 jabawsUrl = aparser.getValue("jabaws");
581 if (jabawsUrl != null)
585 Jws2Discoverer.getDiscoverer().setPreferredUrl(jabawsUrl);
587 "CMD [-jabaws " + jabawsUrl + "] executed successfully!");
588 testoutput(bootstrapArgs, Arg.JABAWS,
589 "http://www.compbio.dundee.ac.uk/jabaws", jabawsUrl);
590 } catch (MalformedURLException e)
592 jalview.bin.Console.errPrintln(
593 "Invalid jabaws parameter: " + jabawsUrl + " ignored");
598 List<String> setprops = new ArrayList<>();
599 if (bootstrapArgs.contains(Arg.SETPROP))
601 setprops = bootstrapArgs.getValueList(Arg.SETPROP);
605 String sp = aparser.getValue("setprop");
609 sp = aparser.getValue("setprop");
612 for (String setprop : setprops)
614 int p = setprop.indexOf('=');
618 .println("Ignoring invalid setprop argument : " + setprop);
623 .errPrintln("Executing setprop argument: " + setprop);
626 Cache.setProperty(setprop.substring(0, p),
627 setprop.substring(p + 1));
629 // DISABLED FOR SECURITY REASONS
630 // TODO: add a property to allow properties to be overriden by cli args
631 // Cache.setProperty(setprop.substring(0,p), setprop.substring(p+1));
634 if (System.getProperty("java.awt.headless") != null
635 && System.getProperty("java.awt.headless").equals("true"))
639 System.setProperty("http.agent", HttpUtils.getUserAgent());
643 Console.initLogger();
646 NoClassDefFoundError error)
648 error.printStackTrace();
649 String message = "\nEssential logging libraries not found."
650 + "\nUse: java -classpath \"$PATH_TO_LIB$/*:$PATH_TO_CLASSES$\" jalview.bin.Jalview";
651 Jalview.exit(message, 0);
655 if (!(headless || headlessArg))
659 * configure 'full' SO model if preferences say to, else use the default (full SO)
660 * - as JS currently doesn't have OBO parsing, it must use 'Lite' version
662 boolean soDefault = !Platform.isJS();
663 if (Cache.getDefault("USE_FULL_SO", soDefault))
665 SequenceOntologyFactory.setInstance(new SequenceOntology());
668 if (!(headless || headlessArg))
670 Desktop.nosplash = "false".equals(bootstrapArgs.getValue(Arg.SPLASH))
671 || aparser.contains("nosplash")
672 || Cache.getDefault("SPLASH", "true").equals("false");
673 desktop = new Desktop();
674 desktop.setInBatchMode(true); // indicate we are starting up
678 JalviewTaskbar.setTaskbar(this);
679 } catch (Exception e)
681 Console.info("Cannot set Taskbar");
682 Console.error(e.getMessage());
683 // e.printStackTrace();
684 } catch (Throwable t)
686 Console.info("Cannot set Taskbar");
687 Console.error(t.getMessage());
688 // t.printStackTrace();
691 // set Proxy settings before all the internet calls
692 Cache.setProxyPropertiesFromPreferences();
694 desktop.setVisible(true);
696 if (!Platform.isJS())
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.
708 if (!LaunchUtils.checkJavaVersion())
710 Console.warn("The Java version being used (Java "
711 + LaunchUtils.getJavaVersion()
712 + ") may lead to problems. This installation of Jalview should be used with Java "
713 + LaunchUtils.getJavaCompileVersion() + ".");
716 .getBooleanUserPreference("IGNORE_JVM_WARNING_POPUP"))
719 MessageManager.getString("label.continue") };
720 JOptionPane.showOptionDialog(null,
721 MessageManager.formatMessage(
722 "warning.wrong_jvm_version_message",
723 LaunchUtils.getJavaVersion(),
724 LaunchUtils.getJavaCompileVersion()),
726 .getString("warning.wrong_jvm_version_title"),
727 JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE,
728 null, options, options[0]);
732 boolean webservicediscovery = bootstrapArgs
733 .getBoolean(Arg.WEBSERVICEDISCOVERY);
734 if (aparser.contains("nowebservicediscovery"))
735 webservicediscovery = false;
736 if (webservicediscovery)
738 desktop.startServiceDiscovery();
742 testoutput(argparser, Arg.WEBSERVICEDISCOVERY);
745 boolean usagestats = !bootstrapArgs.getBoolean(Arg.NOUSAGESTATS);
746 if (aparser.contains("nousagestats"))
750 startUsageStats(desktop);
751 testoutput(argparser, Arg.NOUSAGESTATS);
755 Console.outPrintln("CMD [-nousagestats] executed successfully!");
756 testoutput(argparser, Arg.NOUSAGESTATS);
759 boolean questionnaire = bootstrapArgs.getBoolean(Arg.QUESTIONNAIRE);
760 if (aparser.contains("noquestionnaire"))
761 questionnaire = false;
764 String url = aparser.getValue("questionnaire");
767 // Start the desktop questionnaire prompter with the specified
769 Console.debug("Starting questionnaire url at " + url);
770 desktop.checkForQuestionnaire(url);
771 Console.outPrintln("CMD questionnaire[-" + url
772 + "] executed successfully!");
776 if (Cache.getProperty("NOQUESTIONNAIRES") == null)
778 // Start the desktop questionnaire prompter with the specified
781 // "http://anaplog.compbio.dundee.ac.uk/cgi-bin/questionnaire.pl";
783 String defurl = "https://www.jalview.org/cgi-bin/questionnaire.pl";
785 "Starting questionnaire with default url: " + defurl);
786 desktop.checkForQuestionnaire(defurl);
793 "CMD [-noquestionnaire] executed successfully!");
794 testoutput(argparser, Arg.QUESTIONNAIRE);
797 if ((!aparser.contains("nonews")
798 && Cache.getProperty("NONEWS") == null
799 && !"false".equals(bootstrapArgs.getValue(Arg.NEWS)))
800 || "true".equals(bootstrapArgs.getValue(Arg.NEWS)))
802 desktop.checkForNews();
805 if (!aparser.contains("nohtmltemplates")
806 && Cache.getProperty("NOHTMLTEMPLATES") == null)
808 BioJsHTMLOutput.updateBioJS();
812 // Run Commands from cli
813 cmds = new Commands(argparser, headlessArg);
814 boolean commandsSuccess = cmds.argsWereParsed();
820 if (argparser.getBoolean(Arg.NOQUIT))
823 "Completed " + Arg.HEADLESS.getName() + " commands, but "
824 + Arg.NOQUIT + " is set so not quitting!");
828 Jalview.exit("Successfully completed commands in headless mode",
832 Console.info("Successfully completed commands");
838 Jalview.exit("Error when running Commands in headless mode", 1);
840 Console.warn("Error when running commands");
843 // Check if JVM and compile version might cause problems and log if it
845 if (headless && !Platform.isJS() && !LaunchUtils.checkJavaVersion())
847 Console.warn("The Java version being used (Java "
848 + LaunchUtils.getJavaVersion()
849 + ") may lead to problems. This installation of Jalview should be used with Java "
850 + LaunchUtils.getJavaCompileVersion() + ".");
853 String file = null, data = null;
855 FileFormatI format = null;
857 DataSourceType protocol = null;
859 FileLoader fileLoader = new FileLoader(!headless);
861 String groovyscript = null; // script to execute after all loading is
862 // completed one way or another
863 // extract groovy argument and execute if necessary
864 groovyscript = aparser.getValue("groovy", true);
865 file = aparser.getValue("open", true);
867 if (file == null && desktop == null && !commandsSuccess)
869 Jalview.exit("No files to open!", 1);
873 // Finally, deal with the remaining input data.
878 desktop.setProgressBar(
880 .getString("status.processing_commandline_args"),
881 progress = System.currentTimeMillis());
883 Console.outPrintln("CMD [-open " + file + "] executed successfully!");
885 if (!Platform.isJS())
887 * ignore in JavaScript -- can't just file existence - could load it?
892 if (!HttpUtils.startsWithHttpOrHttps(file))
894 if (!(new File(file)).exists())
899 "Can't find file '" + file + "' in headless mode", 1);
901 Console.warn("Can't find file'" + file + "'");
906 protocol = AppletFormatAdapter.checkProtocol(file);
910 format = new IdentifyFile().identify(file, protocol);
911 } catch (FileFormatException e1)
916 AlignFrame af = fileLoader.LoadFileWaitTillLoaded(file, protocol,
920 Console.outPrintln("error");
924 setCurrentAlignFrame(af);
925 data = aparser.getValue("colour", true);
928 data.replaceAll("%20", " ");
930 ColourSchemeI cs = ColourSchemeProperty.getColourScheme(
931 af.getViewport(), af.getViewport().getAlignment(), data);
936 "CMD [-colour " + data + "] executed successfully!");
941 // Must maintain ability to use the groups flag
942 data = aparser.getValue("groups", true);
945 af.parseFeaturesFile(data,
946 AppletFormatAdapter.checkProtocol(data));
947 // Console.outPrintln("Added " + data);
949 "CMD groups[-" + data + "] executed successfully!");
951 data = aparser.getValue("features", true);
954 af.parseFeaturesFile(data,
955 AppletFormatAdapter.checkProtocol(data));
956 // Console.outPrintln("Added " + data);
958 "CMD [-features " + data + "] executed successfully!");
961 data = aparser.getValue("annotations", true);
964 af.loadJalviewDataFile(data, null, null, null);
965 // Console.outPrintln("Added " + data);
967 "CMD [-annotations " + data + "] executed successfully!");
969 // set or clear the sortbytree flag.
970 if (aparser.contains("sortbytree"))
972 af.getViewport().setSortByTree(true);
973 if (af.getViewport().getSortByTree())
975 Console.outPrintln("CMD [-sortbytree] executed successfully!");
978 if (aparser.contains("no-annotation"))
980 af.getViewport().setShowAnnotation(false);
981 if (!af.getViewport().isShowAnnotation())
983 Console.outPrintln("CMD no-annotation executed successfully!");
986 if (aparser.contains("nosortbytree"))
988 af.getViewport().setSortByTree(false);
989 if (!af.getViewport().getSortByTree())
992 "CMD [-nosortbytree] executed successfully!");
995 data = aparser.getValue("tree", true);
1001 "CMD [-tree " + data + "] executed successfully!");
1002 NewickFile nf = new NewickFile(data,
1003 AppletFormatAdapter.checkProtocol(data));
1005 .setCurrentTree(af.showNewickTree(nf, data).getTree());
1006 } catch (IOException ex)
1008 jalview.bin.Console.errPrintln("Couldn't add tree " + data);
1009 ex.printStackTrace(System.err);
1013 if (groovyscript != null)
1015 // Execute the groovy script after we've done all the rendering stuff
1016 // and before any images or figures are generated.
1017 Console.outPrintln("Executing script " + groovyscript);
1018 executeGroovyScript(groovyscript, af);
1019 Console.outPrintln("CMD groovy[" + groovyscript
1020 + "] executed successfully!");
1021 groovyscript = null;
1023 String imageName = "unnamed.png";
1024 while (aparser.getSize() > 1)
1028 String outputFormat = aparser.nextValue();
1029 file = aparser.nextValue();
1031 if (outputFormat.equalsIgnoreCase("png"))
1033 Console.outPrintln("Creating PNG image: " + file);
1034 af.createPNG(new File(file));
1035 imageName = (new File(file)).getName();
1038 else if (outputFormat.equalsIgnoreCase("svg"))
1040 Console.outPrintln("Creating SVG image: " + file);
1041 File imageFile = new File(file);
1042 imageName = imageFile.getName();
1043 af.createSVG(imageFile);
1046 else if (outputFormat.equalsIgnoreCase("html"))
1048 File imageFile = new File(file);
1049 imageName = imageFile.getName();
1050 HtmlSvgOutput htmlSVG = new HtmlSvgOutput(af.alignPanel);
1052 Console.outPrintln("Creating HTML image: " + file);
1053 htmlSVG.exportHTML(file);
1056 else if (outputFormat.equalsIgnoreCase("biojsmsa"))
1060 jalview.bin.Console.errPrintln(
1061 "The output html file must not be null");
1066 BioJsHTMLOutput.refreshVersionInfo(
1067 BioJsHTMLOutput.BJS_TEMPLATES_LOCAL_DIRECTORY);
1068 } catch (URISyntaxException e)
1070 e.printStackTrace();
1072 BioJsHTMLOutput bjs = new BioJsHTMLOutput(af.alignPanel);
1074 "Creating BioJS MSA Viwer HTML file: " + file);
1075 bjs.exportHTML(file);
1078 else if (outputFormat.equalsIgnoreCase("imgMap"))
1080 Console.outPrintln("Creating image map: " + file);
1081 af.createImageMap(new File(file), imageName);
1084 else if (outputFormat.equalsIgnoreCase("eps"))
1086 File outputFile = new File(file);
1088 "Creating EPS file: " + outputFile.getAbsolutePath());
1089 af.createEPS(outputFile);
1093 FileFormatI outFormat = null;
1096 outFormat = FileFormats.getInstance().forName(outputFormat);
1097 } catch (Exception formatP)
1099 Console.outPrintln("Couldn't parse " + outFormat
1100 + " as a valid Jalview format string.");
1102 if (outFormat != null)
1104 if (!outFormat.isWritable())
1107 "This version of Jalview does not support alignment export as "
1112 af.saveAlignment(file, outFormat);
1113 if (af.isSaveAlignmentSuccessful())
1115 Console.outPrintln("Written alignment in "
1116 + outFormat.getName() + " format to " + file);
1120 Console.outPrintln("Error writing file " + file + " in "
1121 + outFormat.getName() + " format!!");
1125 } catch (ImageOutputException ioexc)
1128 "Unexpected error whilst exporting image to " + file);
1129 ioexc.printStackTrace();
1134 while (aparser.getSize() > 0)
1136 Console.outPrintln("Unknown arg: " + aparser.nextValue());
1141 AlignFrame startUpAlframe = null;
1142 // We'll only open the default file if the desktop is visible.
1144 // ////////////////////
1146 if (!Platform.isJS() && !headless && file == null
1147 && Cache.getDefault("SHOW_STARTUP_FILE", true)
1148 && !cmds.commandArgsProvided()
1149 && !bootstrapArgs.getBoolean(Arg.NOSTARTUPFILE))
1150 // don't open the startup file if command line args have been processed
1151 // (&& !Commands.commandArgsProvided())
1158 file = Cache.getDefault("STARTUP_FILE",
1159 Cache.getDefault("www.jalview.org", "https://www.jalview.org")
1160 + "/examples/exampleFile_2_7.jvp");
1161 if (file.equals("http://www.jalview.org/examples/exampleFile_2_3.jar")
1163 "http://www.jalview.org/examples/exampleFile_2_7.jar"))
1165 file.replace("http:", "https:");
1166 // hardwire upgrade of the startup file
1167 file.replace("_2_3", "_2_7");
1168 file.replace("2_7.jar", "2_7.jvp");
1169 // and remove the stale setting
1170 Cache.removeProperty("STARTUP_FILE");
1173 protocol = AppletFormatAdapter.checkProtocol(file);
1175 if (file.endsWith(".jar"))
1177 format = FileFormat.Jalview;
1183 format = new IdentifyFile().identify(file, protocol);
1184 } catch (FileFormatException e)
1190 startUpAlframe = fileLoader.LoadFileWaitTillLoaded(file, protocol,
1192 // don't ask to save when quitting if only the startup file has been
1194 Console.debug("Resetting up-to-date flag for startup file");
1195 startUpAlframe.getViewport().setSavedUpToDate(true);
1196 // extract groovy arguments before anything else.
1199 // Once all other stuff is done, execute any groovy scripts (in order)
1200 if (groovyscript != null)
1202 if (Cache.groovyJarsPresent())
1204 Console.outPrintln("Executing script " + groovyscript);
1205 executeGroovyScript(groovyscript, startUpAlframe);
1209 jalview.bin.Console.errPrintln(
1210 "Sorry. Groovy Support is not available, so ignoring the provided groovy script "
1214 // and finally, turn off batch mode indicator - if the desktop still exists
1215 if (desktop != null)
1219 desktop.setProgressBar(null, progress);
1221 desktop.setInBatchMode(false);
1225 private static void setLookAndFeel()
1227 if (!Platform.isJS())
1234 // property laf = "crossplatform", "system", "gtk", "metal", "nimbus",
1236 // If not set (or chosen laf fails), use the normal SystemLaF and if on
1238 // try Quaqua/Vaqua.
1239 String lafProp = System.getProperty("laf");
1240 String lafSetting = Cache.getDefault("PREFERRED_LAF", null);
1241 String laf = "none";
1242 if (lafProp != null)
1246 else if (lafSetting != null)
1250 boolean lafSet = false;
1253 case "crossplatform":
1254 lafSet = setCrossPlatformLookAndFeel();
1257 Console.error("Could not set requested laf=" + laf);
1261 lafSet = setSystemLookAndFeel();
1264 Console.error("Could not set requested laf=" + laf);
1268 lafSet = setGtkLookAndFeel();
1271 Console.error("Could not set requested laf=" + laf);
1275 lafSet = setMetalLookAndFeel();
1278 Console.error("Could not set requested laf=" + laf);
1282 lafSet = setNimbusLookAndFeel();
1285 Console.error("Could not set requested laf=" + laf);
1289 lafSet = setFlatLookAndFeel();
1292 Console.error("Could not set requested laf=" + laf);
1296 lafSet = setMacLookAndFeel();
1299 Console.error("Could not set requested laf=" + laf);
1305 Console.error("Requested laf=" + laf + " not implemented");
1309 // Flatlaf default for everyone!
1310 lafSet = setFlatLookAndFeel();
1313 setSystemLookAndFeel();
1315 if (Platform.isLinux())
1317 setLinuxLookAndFeel();
1319 if (Platform.isMac())
1321 setMacLookAndFeel();
1327 private static boolean setCrossPlatformLookAndFeel()
1329 boolean set = false;
1332 UIManager.setLookAndFeel(
1333 UIManager.getCrossPlatformLookAndFeelClassName());
1335 } catch (Exception ex)
1337 Console.error("Unexpected Look and Feel Exception");
1338 Console.error(ex.getMessage());
1339 Console.debug(Cache.getStackTraceString(ex));
1344 private static boolean setSystemLookAndFeel()
1346 boolean set = false;
1349 UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
1351 } catch (Exception ex)
1353 Console.error("Unexpected Look and Feel Exception");
1354 Console.error(ex.getMessage());
1355 Console.debug(Cache.getStackTraceString(ex));
1360 private static boolean setSpecificLookAndFeel(String name,
1361 String className, boolean nameStartsWith)
1363 boolean set = false;
1366 for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels())
1368 if (info.getName() != null && nameStartsWith
1369 ? info.getName().toLowerCase(Locale.ROOT)
1370 .startsWith(name.toLowerCase(Locale.ROOT))
1371 : info.getName().toLowerCase(Locale.ROOT)
1372 .equals(name.toLowerCase(Locale.ROOT)))
1374 className = info.getClassName();
1378 UIManager.setLookAndFeel(className);
1380 } catch (Exception ex)
1382 Console.error("Unexpected Look and Feel Exception");
1383 Console.error(ex.getMessage());
1384 Console.debug(Cache.getStackTraceString(ex));
1389 private static boolean setGtkLookAndFeel()
1391 return setSpecificLookAndFeel("gtk",
1392 "com.sun.java.swing.plaf.gtk.GTKLookAndFeel", true);
1395 private static boolean setMetalLookAndFeel()
1397 return setSpecificLookAndFeel("metal",
1398 "javax.swing.plaf.metal.MetalLookAndFeel", false);
1401 private static boolean setNimbusLookAndFeel()
1403 return setSpecificLookAndFeel("nimbus",
1404 "javax.swing.plaf.nimbus.NimbusLookAndFeel", false);
1407 private static boolean setFlatLookAndFeel()
1409 boolean set = false;
1410 if (SystemInfo.isMacOS)
1414 UIManager.setLookAndFeel(
1415 "com.formdev.flatlaf.themes.FlatMacLightLaf");
1417 Console.debug("Using FlatMacLightLaf");
1418 } catch (ClassNotFoundException | InstantiationException
1419 | IllegalAccessException | UnsupportedLookAndFeelException e)
1421 Console.debug("Exception loading FlatLightLaf", e);
1423 System.setProperty("apple.laf.useScreenMenuBar", "true");
1424 System.setProperty("apple.awt.application.name",
1425 ChannelProperties.getProperty("app_name"));
1426 System.setProperty("apple.awt.application.appearance", "system");
1427 if (SystemInfo.isMacFullWindowContentSupported
1428 && Desktop.desktop != null)
1430 Console.debug("Setting transparent title bar");
1431 Desktop.desktop.getRootPane()
1432 .putClientProperty("apple.awt.fullWindowContent", true);
1433 Desktop.desktop.getRootPane()
1434 .putClientProperty("apple.awt.transparentTitleBar", true);
1435 Desktop.desktop.getRootPane()
1436 .putClientProperty("apple.awt.fullscreenable", true);
1438 SwingUtilities.invokeLater(() -> {
1439 FlatMacLightLaf.setup();
1441 Console.debug("Using FlatMacLightLaf");
1448 UIManager.setLookAndFeel("com.formdev.flatlaf.FlatLightLaf");
1450 Console.debug("Using FlatLightLaf");
1451 } catch (ClassNotFoundException | InstantiationException
1452 | IllegalAccessException | UnsupportedLookAndFeelException e)
1454 Console.debug("Exception loading FlatLightLaf", e);
1456 // Windows specific properties here
1457 SwingUtilities.invokeLater(() -> {
1458 FlatLightLaf.setup();
1460 Console.debug("Using FlatLightLaf");
1463 else if (SystemInfo.isLinux)
1467 UIManager.setLookAndFeel("com.formdev.flatlaf.FlatLightLaf");
1469 Console.debug("Using FlatLightLaf");
1470 } catch (ClassNotFoundException | InstantiationException
1471 | IllegalAccessException | UnsupportedLookAndFeelException e)
1473 Console.debug("Exception loading FlatLightLaf", e);
1475 // enable custom window decorations
1476 JFrame.setDefaultLookAndFeelDecorated(true);
1477 JDialog.setDefaultLookAndFeelDecorated(true);
1478 SwingUtilities.invokeLater(() -> {
1479 FlatLightLaf.setup();
1481 Console.debug("Using FlatLightLaf");
1489 UIManager.setLookAndFeel("com.formdev.flatlaf.FlatLightLaf");
1491 Console.debug("Using FlatLightLaf");
1492 } catch (ClassNotFoundException | InstantiationException
1493 | IllegalAccessException | UnsupportedLookAndFeelException e)
1495 Console.debug("Exception loading FlatLightLaf", e);
1501 UIManager.put("TabbedPane.tabType", "card");
1502 UIManager.put("TabbedPane.showTabSeparators", true);
1503 UIManager.put("TabbedPane.showContentSeparator", true);
1504 // UIManager.put("TabbedPane.tabSeparatorsFullHeight", true);
1505 UIManager.put("TabbedPane.tabsOverlapBorder", true);
1506 UIManager.put("TabbedPane.hasFullBorder", true);
1507 UIManager.put("TabbedPane.tabLayoutPolicy", "scroll");
1508 UIManager.put("TabbedPane.scrollButtonsPolicy", "asNeeded");
1509 UIManager.put("TabbedPane.smoothScrolling", true);
1510 UIManager.put("TabbedPane.tabWidthMode", "compact");
1511 UIManager.put("TabbedPane.selectedBackground", Color.white);
1512 UIManager.put("TabbedPane.background", new Color(236, 236, 236));
1513 UIManager.put("TabbedPane.hoverColor", Color.lightGray);
1516 Desktop.setLiveDragMode(Cache.getDefault("FLAT_LIVE_DRAG_MODE", true));
1520 private static boolean setMacLookAndFeel()
1522 boolean set = false;
1523 System.setProperty("com.apple.mrj.application.apple.menu.about.name",
1524 ChannelProperties.getProperty("app_name"));
1525 System.setProperty("apple.laf.useScreenMenuBar", "true");
1527 * broken native LAFs on (ARM?) macbooks
1528 set = setQuaquaLookAndFeel();
1529 if ((!set) || !UIManager.getLookAndFeel().getClass().toString()
1530 .toLowerCase(Locale.ROOT).contains("quaqua"))
1532 set = setVaquaLookAndFeel();
1535 set = setFlatLookAndFeel();
1539 private static boolean setLinuxLookAndFeel()
1541 boolean set = false;
1542 set = setFlatLookAndFeel();
1544 set = setMetalLookAndFeel();
1545 // avoid GtkLookAndFeel -- not good results especially on HiDPI
1547 set = setNimbusLookAndFeel();
1552 private static void showUsage()
1554 jalview.bin.Console.outPrintln(
1555 "Usage: jalview -open [FILE] [OUTPUT_FORMAT] [OUTPUT_FILE]\n\n"
1556 + "-nodisplay\tRun Jalview without User Interface.\n"
1557 + "-props FILE\tUse the given Jalview properties file instead of users default.\n"
1558 + "-colour COLOURSCHEME\tThe colourscheme to be applied to the alignment\n"
1559 + "-annotations FILE\tAdd precalculated annotations to the alignment.\n"
1560 + "-tree FILE\tLoad the given newick format tree file onto the alignment\n"
1561 + "-features FILE\tUse the given file to mark features on the alignment.\n"
1562 + "-fasta FILE\tCreate alignment file FILE in Fasta format.\n"
1563 + "-clustal FILE\tCreate alignment file FILE in Clustal format.\n"
1564 + "-pfam FILE\tCreate alignment file FILE in PFAM format.\n"
1565 + "-msf FILE\tCreate alignment file FILE in MSF format.\n"
1566 + "-pileup FILE\tCreate alignment file FILE in Pileup format\n"
1567 + "-pir FILE\tCreate alignment file FILE in PIR format.\n"
1568 + "-blc FILE\tCreate alignment file FILE in BLC format.\n"
1569 + "-json FILE\tCreate alignment file FILE in JSON format.\n"
1570 + "-jalview FILE\tCreate alignment file FILE in Jalview format.\n"
1571 + "-png FILE\tCreate PNG image FILE from alignment.\n"
1572 + "-svg FILE\tCreate SVG image FILE from alignment.\n"
1573 + "-html FILE\tCreate HTML file from alignment.\n"
1574 + "-biojsMSA FILE\tCreate BioJS MSA Viewer HTML file from alignment.\n"
1575 + "-imgMap FILE\tCreate HTML file FILE with image map of PNG image.\n"
1576 + "-eps FILE\tCreate EPS file FILE from alignment.\n"
1577 + "-questionnaire URL\tQueries the given URL for information about any Jalview user questionnaires.\n"
1578 + "-noquestionnaire\tTurn off questionnaire check.\n"
1579 + "-nonews\tTurn off check for Jalview news.\n"
1580 + "-nousagestats\tTurn off analytics tracking for this session.\n"
1581 + "-sortbytree OR -nosortbytree\tEnable or disable sorting of the given alignment by the given tree\n"
1583 // "-setprop PROPERTY=VALUE\tSet the given Jalview property,
1584 // after all other properties files have been read\n\t
1585 // (quote the 'PROPERTY=VALUE' pair to ensure spaces are
1586 // passed in correctly)"
1587 + "-jabaws URL\tSpecify URL for Jabaws services (e.g. for a local installation).\n"
1588 + "-fetchfrom nickname\tQuery nickname for features for the alignments and display them.\n"
1589 + "-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"
1590 + "-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"
1591 + "-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"
1592 + "\n~Read documentation in Application or visit https://www.jalview.org for description of Features and Annotations file~\n\n");
1596 private static void startUsageStats(final Desktop desktop)
1599 * start a User Config prompt asking if we can log usage statistics.
1601 PromptUserConfig prompter = new PromptUserConfig(Desktop.desktop,
1603 MessageManager.getString("prompt.plausible_analytics_title"),
1604 MessageManager.getString("prompt.plausible_analytics"),
1610 Console.debug("Initialising analytics for usage stats.");
1611 Cache.initAnalytics();
1612 Console.debug("Tracking enabled.");
1619 Console.debug("Not enabling analytics.");
1622 desktop.addDialogThread(prompter);
1626 * Locate the given string as a file and pass it to the groovy interpreter.
1628 * @param groovyscript
1629 * the script to execute
1630 * @param jalviewContext
1631 * the Jalview Desktop object passed in to the groovy binding as the
1634 protected void executeGroovyScript(String groovyscript, AlignFrame af)
1637 * for scripts contained in files
1644 if (groovyscript.trim().equals("STDIN"))
1646 // read from stdin into a tempfile and execute it
1649 tfile = File.createTempFile("jalview", "groovy");
1650 PrintWriter outfile = new PrintWriter(
1651 new OutputStreamWriter(new FileOutputStream(tfile)));
1652 BufferedReader br = new BufferedReader(
1653 new InputStreamReader(System.in));
1655 while ((line = br.readLine()) != null)
1657 outfile.write(line + "\n");
1663 } catch (Exception ex)
1666 .errPrintln("Failed to read from STDIN into tempfile "
1667 + ((tfile == null) ? "(tempfile wasn't created)"
1668 : tfile.toString()));
1669 ex.printStackTrace();
1674 sfile = tfile.toURI().toURL();
1675 } catch (Exception x)
1677 jalview.bin.Console.errPrintln(
1678 "Unexpected Malformed URL Exception for temporary file created from STDIN: "
1680 x.printStackTrace();
1688 sfile = new URI(groovyscript).toURL();
1689 } catch (Exception x)
1691 tfile = new File(groovyscript);
1692 if (!tfile.exists())
1694 jalview.bin.Console.errPrintln(
1695 "File '" + groovyscript + "' does not exist.");
1698 if (!tfile.canRead())
1700 jalview.bin.Console.errPrintln(
1701 "File '" + groovyscript + "' cannot be read.");
1704 if (tfile.length() < 1)
1707 .errPrintln("File '" + groovyscript + "' is empty.");
1712 sfile = tfile.getAbsoluteFile().toURI().toURL();
1713 } catch (Exception ex)
1715 jalview.bin.Console.errPrintln("Failed to create a file URL for "
1716 + tfile.getAbsoluteFile());
1723 Map<String, java.lang.Object> vbinding = new HashMap<>();
1724 vbinding.put("Jalview", this);
1727 vbinding.put("currentAlFrame", af);
1729 Binding gbinding = new Binding(vbinding);
1730 GroovyScriptEngine gse = new GroovyScriptEngine(new URL[] { sfile });
1731 gse.run(sfile.toString(), gbinding);
1732 if ("STDIN".equals(groovyscript))
1734 // delete temp file that we made -
1735 // only if it was successfully executed
1738 } catch (Exception e)
1741 .errPrintln("Exception Whilst trying to execute file " + sfile
1742 + " as a groovy script.");
1743 e.printStackTrace(System.err);
1748 public static boolean isHeadlessMode()
1750 String isheadless = System.getProperty("java.awt.headless");
1751 if (isheadless != null && isheadless.equalsIgnoreCase("true"))
1758 public AlignFrame[] getAlignFrames()
1760 return desktop == null ? new AlignFrame[] { getCurrentAlignFrame() }
1761 : Desktop.getAlignFrames();
1766 * jalview.bin.Jalview.quit() will just run the non-GUI shutdownHook and exit
1770 // System.exit will run the shutdownHook first
1771 Jalview.exit("Quitting now. Bye!", 0);
1774 public static AlignFrame getCurrentAlignFrame()
1776 return Jalview.currentAlignFrame;
1779 public static void setCurrentAlignFrame(AlignFrame currentAlignFrame)
1781 Jalview.currentAlignFrame = currentAlignFrame;
1784 protected Commands getCommands()
1789 public static void exit(String message, int exitcode)
1791 if (Console.log == null)
1793 // Don't start the logger just to exit!
1794 if (message != null)
1798 Console.outPrintln(message);
1802 jalview.bin.Console.errPrintln(message);
1808 Console.debug("Using Jalview.exit");
1809 if (message != null)
1813 Console.info(message);
1817 Console.error(message);
1823 System.exit(exitcode);
1827 /******************************
1829 * TEST OUTPUT METHODS
1831 ******************************/
1833 * method for reporting string values parsed/processed during tests
1836 protected static void testoutput(ArgParser ap, Arg a, String s1,
1839 BootstrapArgs bsa = ap.getBootstrapArgs();
1840 if (!bsa.getBoolean(Arg.TESTOUTPUT))
1842 if (!((s1 == null && s2 == null) || (s1 != null && s1.equals(s2))))
1844 Console.debug("testoutput with unmatching values '" + s1 + "' and '"
1845 + s2 + "' for arg " + a.argString());
1848 boolean isset = a.hasOption(Opt.BOOTSTRAP) ? bsa.contains(a)
1852 Console.warn("Arg '" + a.getName() + "' not set at all");
1855 testoutput(true, a, s1, s2);
1859 * method for reporting string values parsed/processed during tests
1862 protected static void testoutput(BootstrapArgs bsa, Arg a, String s1,
1865 if (!bsa.getBoolean(Arg.TESTOUTPUT))
1867 if (!((s1 == null && s2 == null) || (s1 != null && s1.equals(s2))))
1869 Console.debug("testoutput with unmatching values '" + s1 + "' and '"
1870 + s2 + "' for arg " + a.argString());
1873 if (!a.hasOption(Opt.BOOTSTRAP))
1875 Console.error("Non-bootstrap Arg '" + a.getName()
1876 + "' given to testoutput(BootstrapArgs bsa, Arg a, String s1, String s2) with only BootstrapArgs");
1878 if (!bsa.contains(a))
1880 Console.warn("Arg '" + a.getName() + "' not set at all");
1883 testoutput(true, a, s1, s2);
1887 * report value set for string values parsed/processed during tests
1889 private static void testoutput(boolean yes, Arg a, String s1, String s2)
1891 if (yes && ((s1 == null && s2 == null)
1892 || (s1 != null && s1.equals(s2))))
1894 Console.outPrintln("[TESTOUTPUT] arg " + a.argString() + "='" + s1
1900 * testoutput for boolean and unary values
1902 protected static void testoutput(ArgParser ap, Arg a)
1906 BootstrapArgs bsa = ap.getBootstrapArgs();
1909 if (!bsa.getBoolean(Arg.TESTOUTPUT))
1911 boolean val = a.hasOption(Opt.BOOTSTRAP) ? bsa.getBoolean(a)
1913 boolean isset = a.hasOption(Opt.BOOTSTRAP) ? bsa.contains(a)
1917 Console.warn("Arg '" + a.getName() + "' not set at all");
1923 protected static void testoutput(BootstrapArgs bsa, Arg a)
1925 if (!bsa.getBoolean(Arg.TESTOUTPUT))
1927 if (!a.hasOption(Opt.BOOTSTRAP))
1929 Console.warn("Non-bootstrap Arg '" + a.getName()
1930 + "' given to testoutput(BootstrapArgs bsa, Arg a) with only BootstrapArgs");
1933 if (!bsa.contains(a))
1935 Console.warn("Arg '" + a.getName() + "' not set at all");
1938 testoutput(bsa.getBoolean(a), a);
1941 private static void testoutput(boolean yes, Arg a)
1943 String message = null;
1944 if (a.hasOption(Opt.BOOLEAN))
1946 message = (yes ? a.argString() : a.negateArgString()) + " was set";
1948 else if (a.hasOption(Opt.UNARY))
1950 message = a.argString() + (yes ? " was set" : " was not set");
1952 Console.outPrintln("[TESTOUTPUT] arg " + message);