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.io.BufferedReader;
25 import java.io.FileOutputStream;
26 import java.io.IOException;
27 import java.io.InputStreamReader;
28 import java.io.OutputStreamWriter;
29 import java.io.PrintWriter;
30 import java.net.MalformedURLException;
32 import java.net.URISyntaxException;
34 import java.security.AllPermission;
35 import java.security.CodeSource;
36 import java.security.PermissionCollection;
37 import java.security.Permissions;
38 import java.security.Policy;
39 import java.util.HashMap;
41 import java.util.Vector;
43 import javax.swing.UIManager;
44 import javax.swing.UIManager.LookAndFeelInfo;
46 import com.threerings.getdown.util.LaunchUtil;
48 import groovy.lang.Binding;
49 import groovy.util.GroovyScriptEngine;
50 import jalview.ext.so.SequenceOntology;
51 import jalview.gui.AlignFrame;
52 import jalview.gui.Desktop;
53 import jalview.gui.PromptUserConfig;
54 import jalview.io.AppletFormatAdapter;
55 import jalview.io.BioJsHTMLOutput;
56 import jalview.io.DataSourceType;
57 import jalview.io.FileFormat;
58 import jalview.io.FileFormatException;
59 import jalview.io.FileFormatI;
60 import jalview.io.FileFormats;
61 import jalview.io.FileLoader;
62 import jalview.io.HtmlSvgOutput;
63 import jalview.io.IdentifyFile;
64 import jalview.io.NewickFile;
65 import jalview.io.gff.SequenceOntologyFactory;
66 import jalview.schemes.ColourSchemeI;
67 import jalview.schemes.ColourSchemeProperty;
68 import jalview.util.HttpUtils;
69 import jalview.util.MessageManager;
70 import jalview.util.Platform;
71 import jalview.ws.jws2.Jws2Discoverer;
74 * Main class for Jalview Application <br>
76 * start with: java -classpath "$PATH_TO_LIB$/*:$PATH_TO_CLASSES$" \
79 * or on Windows: java -classpath "$PATH_TO_LIB$/*;$PATH_TO_CLASSES$" \
80 * jalview.bin.Jalview jalview.bin.Jalview
82 * (ensure -classpath arg is quoted to avoid shell expansion of '*' and do not
83 * embellish '*' to e.g. '*.jar')
91 * singleton instance of this class
93 private static Jalview instance;
95 private Desktop desktop;
97 public static AlignFrame currentAlignFrame;
101 // grab all the rights we can the JVM
102 Policy.setPolicy(new Policy()
105 public PermissionCollection getPermissions(CodeSource codesource)
107 Permissions perms = new Permissions();
108 perms.add(new AllPermission());
113 public void refresh()
120 * keep track of feature fetching tasks.
128 * TODO: generalise to track all jalview events to orchestrate batch processing
132 private int queued = 0;
134 private int running = 0;
136 public FeatureFetcher()
141 public void addFetcher(final AlignFrame af,
142 final Vector<String> dasSources)
144 final long id = System.currentTimeMillis();
146 final FeatureFetcher us = this;
147 new Thread(new Runnable()
159 af.setProgressBar(MessageManager
160 .getString("status.das_features_being_retrived"), id);
161 af.featureSettings_actionPerformed(null);
162 af.setProgressBar(null, id);
171 public synchronized boolean allFinished()
173 return queued == 0 && running == 0;
178 public static Jalview getInstance()
184 * main class for Jalview application
187 * open <em>filename</em>
189 public static void main(String[] args)
191 instance = new Jalview();
192 instance.doMain(args);
198 void doMain(String[] args)
200 System.setSecurityManager(null);
202 .println("Java version: " + System.getProperty("java.version"));
203 System.out.println("Java Home: " + System.getProperty("java.home"));
204 System.out.println(System.getProperty("os.arch") + " "
205 + System.getProperty("os.name") + " "
206 + System.getProperty("os.version"));
207 String val = System.getProperty("sys.install4jVersion");
210 System.out.println("Install4j version: " + val);
212 val = System.getProperty("installer_template_version");
215 System.out.println("Install4j template version: " + val);
217 val = System.getProperty("launcher_version");
220 System.out.println("Launcher version: " + val);
223 // report Jalview version
224 Cache.loadBuildProperties(true);
226 ArgsParser aparser = new ArgsParser(args);
227 boolean headless = false;
229 if (aparser.contains("help") || aparser.contains("h"))
234 if (aparser.contains("nodisplay") || aparser.contains("nogui")
235 || aparser.contains("headless"))
237 System.setProperty("java.awt.headless", "true");
240 String usrPropsFile = aparser.getValue("props");
241 Cache.loadProperties(usrPropsFile); // must do this before
242 if (usrPropsFile != null)
245 "CMD [-props " + usrPropsFile + "] executed successfully!");
250 // allow https handshakes to download intermediate certs if necessary
251 System.setProperty("com.sun.security.enableAIAcaIssuers", "true");
253 final String jabawsUrl = aparser.getValue("jabaws");
254 if (jabawsUrl != null)
258 Jws2Discoverer.getDiscoverer().setPreferredUrl(jabawsUrl);
260 "CMD [-jabaws " + jabawsUrl + "] executed successfully!");
261 } catch (MalformedURLException e)
264 "Invalid jabaws parameter: " + jabawsUrl + " ignored");
268 String defs = aparser.getValue("setprop");
271 int p = defs.indexOf('=');
274 System.err.println("Ignoring invalid setprop argument : " + defs);
278 System.out.println("Executing setprop argument: " + defs);
279 // DISABLED FOR SECURITY REASONS
280 // TODO: add a property to allow properties to be overriden by cli args
281 // Cache.setProperty(defs.substring(0,p), defs.substring(p+1));
283 defs = aparser.getValue("setprop");
285 if (System.getProperty("java.awt.headless") != null
286 && System.getProperty("java.awt.headless").equals("true"))
290 System.setProperty("http.agent",
291 "Jalview Desktop/" + Cache.getDefault("VERSION", "Unknown"));
295 } catch (NoClassDefFoundError error)
297 error.printStackTrace();
298 System.out.println("\nEssential logging libraries not found."
299 + "\nUse: java -classpath \"$PATH_TO_LIB$/*:$PATH_TO_CLASSES$\" jalview.bin.Jalview");
308 * configure 'full' SO model if preferences say to, else use the default (SO
311 if (Cache.getDefault("USE_FULL_SO", true))
313 SequenceOntologyFactory.setInstance(new SequenceOntology());
319 desktop = new Desktop();
320 desktop.setInBatchMode(true); // indicate we are starting up
324 JalviewTaskbar.setTaskbar(this);
325 } catch (Exception e)
327 Cache.log.info("Cannot set Taskbar");
328 Cache.log.error(e.getMessage());
329 // e.printStackTrace();
330 } catch (Throwable t)
332 Cache.log.info("Cannot set Taskbar");
333 Cache.log.error(t.getMessage());
334 // t.printStackTrace();
337 desktop.setVisible(true);
338 desktop.startServiceDiscovery();
339 if (!aparser.contains("nousagestats"))
341 startUsageStats(desktop);
345 System.err.println("CMD [-nousagestats] executed successfully!");
348 if (!aparser.contains("noquestionnaire"))
350 String url = aparser.getValue("questionnaire");
353 // Start the desktop questionnaire prompter with the specified
355 Cache.log.debug("Starting questionnaire url at " + url);
356 desktop.checkForQuestionnaire(url);
358 "CMD questionnaire[-" + url + "] executed successfully!");
362 if (Cache.getProperty("NOQUESTIONNAIRES") == null)
364 // Start the desktop questionnaire prompter with the specified
367 // "http://anaplog.compbio.dundee.ac.uk/cgi-bin/questionnaire.pl";
369 String defurl = "https://www.jalview.org/cgi-bin/questionnaire.pl";
371 "Starting questionnaire with default url: " + defurl);
372 desktop.checkForQuestionnaire(defurl);
378 System.err.println("CMD [-noquestionnaire] executed successfully!");
381 if (!aparser.contains("nonews")
382 || Cache.getProperty("NONEWS") == null)
384 desktop.checkForNews();
387 if (!aparser.contains("nohtmltemplates")
388 || Cache.getProperty("NOHTMLTEMPLATES") == null)
390 BioJsHTMLOutput.updateBioJS();
394 // Move any new getdown-launcher-new.jar into place over old
395 // getdown-launcher.jar
396 String appdirString = System.getProperty("getdownappdir");
397 if (appdirString != null && appdirString.length() > 0)
399 final File appdir = new File(appdirString);
405 LaunchUtil.upgradeGetdown(
406 new File(appdir, "getdown-launcher-old.jar"),
407 new File(appdir, "getdown-launcher.jar"),
408 new File(appdir, "getdown-launcher-new.jar"));
413 String file = null, data = null;
414 FileFormatI format = null;
415 DataSourceType protocol = null;
416 FileLoader fileLoader = new FileLoader(!headless);
418 String groovyscript = null; // script to execute after all loading is
419 // completed one way or another
420 // extract groovy argument and execute if necessary
421 groovyscript = aparser.getValue("groovy", true);
422 file = aparser.getValue("open", true);
424 if (file == null && desktop == null)
426 System.out.println("No files to open!");
430 // Finally, deal with the remaining input data.
435 desktop.setProgressBar(
437 .getString("status.processing_commandline_args"),
438 progress = System.currentTimeMillis());
440 System.out.println("CMD [-open " + file + "] executed successfully!");
442 protocol = AppletFormatAdapter.checkProtocol(file);
444 if (protocol == DataSourceType.FILE)
446 if (!(new File(file)).exists())
448 System.out.println("Can't find " + file);
458 format = new IdentifyFile().identify(file, protocol);
459 } catch (FileFormatException e1)
464 AlignFrame af = fileLoader.LoadFileWaitTillLoaded(file, protocol,
468 System.out.println("error");
472 setCurrentAlignFrame(af);
473 data = aparser.getValue("colour", true);
476 data.replaceAll("%20", " ");
478 ColourSchemeI cs = ColourSchemeProperty.getColourScheme(
479 af.getViewport(), af.getViewport().getAlignment(), data);
484 "CMD [-color " + data + "] executed successfully!");
489 // Must maintain ability to use the groups flag
490 data = aparser.getValue("groups", true);
493 af.parseFeaturesFile(data,
494 AppletFormatAdapter.checkProtocol(data));
495 // System.out.println("Added " + data);
497 "CMD groups[-" + data + "] executed successfully!");
499 data = aparser.getValue("features", true);
502 af.parseFeaturesFile(data,
503 AppletFormatAdapter.checkProtocol(data));
504 // System.out.println("Added " + data);
506 "CMD [-features " + data + "] executed successfully!");
509 data = aparser.getValue("annotations", true);
512 af.loadJalviewDataFile(data, null, null, null);
513 // System.out.println("Added " + data);
515 "CMD [-annotations " + data + "] executed successfully!");
517 // set or clear the sortbytree flag.
518 if (aparser.contains("sortbytree"))
520 af.getViewport().setSortByTree(true);
521 if (af.getViewport().getSortByTree())
523 System.out.println("CMD [-sortbytree] executed successfully!");
526 if (aparser.contains("no-annotation"))
528 af.getViewport().setShowAnnotation(false);
529 if (!af.getViewport().isShowAnnotation())
531 System.out.println("CMD no-annotation executed successfully!");
534 if (aparser.contains("nosortbytree"))
536 af.getViewport().setSortByTree(false);
537 if (!af.getViewport().getSortByTree())
540 .println("CMD [-nosortbytree] executed successfully!");
543 data = aparser.getValue("tree", true);
549 "CMD [-tree " + data + "] executed successfully!");
550 NewickFile nf = new NewickFile(data,
551 AppletFormatAdapter.checkProtocol(data));
553 .setCurrentTree(af.showNewickTree(nf, data).getTree());
554 } catch (IOException ex)
556 System.err.println("Couldn't add tree " + data);
557 ex.printStackTrace(System.err);
560 // TODO - load PDB structure(s) to alignment JAL-629
561 // (associate with identical sequence in alignment, or a specified
563 if (groovyscript != null)
565 // Execute the groovy script after we've done all the rendering stuff
566 // and before any images or figures are generated.
567 System.out.println("Executing script " + groovyscript);
568 executeGroovyScript(groovyscript, af);
569 System.out.println("CMD groovy[" + groovyscript
570 + "] executed successfully!");
573 String imageName = "unnamed.png";
574 while (aparser.getSize() > 1)
576 String outputFormat = aparser.nextValue();
577 file = aparser.nextValue();
579 if (outputFormat.equalsIgnoreCase("png"))
581 af.createPNG(new File(file));
582 imageName = (new File(file)).getName();
583 System.out.println("Creating PNG image: " + file);
586 else if (outputFormat.equalsIgnoreCase("svg"))
588 File imageFile = new File(file);
589 imageName = imageFile.getName();
590 af.createSVG(imageFile);
591 System.out.println("Creating SVG image: " + file);
594 else if (outputFormat.equalsIgnoreCase("html"))
596 File imageFile = new File(file);
597 imageName = imageFile.getName();
598 HtmlSvgOutput htmlSVG = new HtmlSvgOutput(af.alignPanel);
599 htmlSVG.exportHTML(file);
601 System.out.println("Creating HTML image: " + file);
604 else if (outputFormat.equalsIgnoreCase("biojsmsa"))
608 System.err.println("The output html file must not be null");
613 BioJsHTMLOutput.refreshVersionInfo(
614 BioJsHTMLOutput.BJS_TEMPLATES_LOCAL_DIRECTORY);
615 } catch (URISyntaxException e)
619 BioJsHTMLOutput bjs = new BioJsHTMLOutput(af.alignPanel);
620 bjs.exportHTML(file);
622 .println("Creating BioJS MSA Viwer HTML file: " + file);
625 else if (outputFormat.equalsIgnoreCase("imgMap"))
627 af.createImageMap(new File(file), imageName);
628 System.out.println("Creating image map: " + file);
631 else if (outputFormat.equalsIgnoreCase("eps"))
633 File outputFile = new File(file);
635 "Creating EPS file: " + outputFile.getAbsolutePath());
636 af.createEPS(outputFile);
639 FileFormatI outFormat = null;
642 outFormat = FileFormats.getInstance().forName(outputFormat);
643 } catch (Exception formatP)
645 System.out.println("Couldn't parse " + outFormat
646 + " as a valid Jalview format string.");
648 if (outFormat != null)
650 if (!outFormat.isWritable())
653 "This version of Jalview does not support alignment export as "
658 if (af.saveAlignment(file, outFormat))
660 System.out.println("Written alignment in " + format
661 + " format to " + file);
665 System.out.println("Error writing file " + file + " in "
666 + format + " format!!");
672 while (aparser.getSize() > 0)
674 System.out.println("Unknown arg: " + aparser.nextValue());
678 AlignFrame startUpAlframe = null;
679 // We'll only open the default file if the desktop is visible.
681 // ////////////////////
683 if (!headless && file == null
684 && jalview.bin.Cache.getDefault("SHOW_STARTUP_FILE", true))
686 file = jalview.bin.Cache.getDefault("STARTUP_FILE",
687 jalview.bin.Cache.getDefault("www.jalview.org",
688 "https://www.jalview.org")
689 + "/examples/exampleFile_2_7.jvp");
690 if (file.equals("http://www.jalview.org/examples/exampleFile_2_3.jar")
692 "http://www.jalview.org/examples/exampleFile_2_7.jar"))
694 file.replace("http:", "https:");
695 // hardwire upgrade of the startup file
696 file.replace("_2_3", "_2_7");
697 file.replace("2_7.jar", "2_7.jvp");
698 // and remove the stale setting
699 jalview.bin.Cache.removeProperty("STARTUP_FILE");
702 protocol = AppletFormatAdapter.checkProtocol(file);
704 if (file.endsWith(".jar"))
706 format = FileFormat.Jalview;
712 format = new IdentifyFile().identify(file, protocol);
713 } catch (FileFormatException e)
719 startUpAlframe = fileLoader.LoadFileWaitTillLoaded(file, protocol,
721 // extract groovy arguments before anything else.
724 // Once all other stuff is done, execute any groovy scripts (in order)
725 if (groovyscript != null)
727 if (Cache.groovyJarsPresent())
729 System.out.println("Executing script " + groovyscript);
730 executeGroovyScript(groovyscript, startUpAlframe);
735 "Sorry. Groovy Support is not available, so ignoring the provided groovy script "
739 // and finally, turn off batch mode indicator - if the desktop still exists
744 desktop.setProgressBar(null, progress);
746 desktop.setInBatchMode(false);
750 private static void setLookAndFeel()
752 // property laf = "crossplatform", "system", "gtk", "metal", "nimbus" or
754 // If not set (or chosen laf fails), use the normal SystemLaF and if on Mac,
756 String lafProp = System.getProperty("laf");
757 String lafSetting = Cache.getDefault("PREFERRED_LAF", null);
763 else if (lafSetting != null)
767 boolean lafSet = false;
770 case "crossplatform":
771 lafSet = setCrossPlatformLookAndFeel();
774 Cache.log.error("Could not set requested laf=" + laf);
778 lafSet = setSystemLookAndFeel();
781 Cache.log.error("Could not set requested laf=" + laf);
785 lafSet = setGtkLookAndFeel();
788 Cache.log.error("Could not set requested laf=" + laf);
792 lafSet = setMetalLookAndFeel();
795 Cache.log.error("Could not set requested laf=" + laf);
799 lafSet = setNimbusLookAndFeel();
802 Cache.log.error("Could not set requested laf=" + laf);
806 lafSet = setQuaquaLookAndFeel();
809 Cache.log.error("Could not set requested laf=" + laf);
813 lafSet = setVaquaLookAndFeel();
816 Cache.log.error("Could not set requested laf=" + laf);
820 lafSet = setMacLookAndFeel();
823 Cache.log.error("Could not set requested laf=" + laf);
829 Cache.log.error("Requested laf=" + laf + " not implemented");
833 setSystemLookAndFeel();
834 if (Platform.isLinux())
836 setMetalLookAndFeel();
838 if (Platform.isAMac())
845 private static boolean setCrossPlatformLookAndFeel()
847 return setGenericLookAndFeel(false);
850 private static boolean setSystemLookAndFeel()
852 return setGenericLookAndFeel(true);
855 private static boolean setGenericLookAndFeel(boolean system)
860 UIManager.setLookAndFeel(
861 system ? UIManager.getSystemLookAndFeelClassName()
862 : UIManager.getCrossPlatformLookAndFeelClassName());
864 } catch (Exception ex)
866 Cache.log.error("Unexpected Look and Feel Exception");
867 Cache.log.error(ex.getMessage());
868 Cache.log.debug(Cache.getStackTraceString(ex));
873 private static boolean setSpecificLookAndFeel(String name,
874 String className, boolean nameStartsWith)
879 for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels())
881 if (info.getName() != null && nameStartsWith
882 ? info.getName().toLowerCase()
883 .startsWith(name.toLowerCase())
884 : info.getName().toLowerCase().equals(name.toLowerCase()))
886 className = info.getClassName();
890 UIManager.setLookAndFeel(className);
892 } catch (Exception ex)
894 Cache.log.error("Unexpected Look and Feel Exception");
895 Cache.log.error(ex.getMessage());
896 Cache.log.debug(Cache.getStackTraceString(ex));
901 private static boolean setGtkLookAndFeel()
903 return setSpecificLookAndFeel("gtk",
904 "com.sun.java.swing.plaf.gtk.GTKLookAndFeel", true);
907 private static boolean setMetalLookAndFeel()
909 return setSpecificLookAndFeel("metal",
910 "javax.swing.plaf.metal.MetalLookAndFeel", false);
913 private static boolean setNimbusLookAndFeel()
915 return setSpecificLookAndFeel("nimbus",
916 "javax.swing.plaf.nimbus.NimbusLookAndFeel", false);
919 private static boolean setQuaquaLookAndFeel()
921 return setSpecificLookAndFeel("quaqua",
922 ch.randelshofer.quaqua.QuaquaManager.getLookAndFeel().getClass()
927 private static boolean setVaquaLookAndFeel()
929 return setSpecificLookAndFeel("vaqua",
930 "org.violetlib.aqua.AquaLookAndFeel", false);
933 private static boolean setMacLookAndFeel()
936 System.setProperty("com.apple.mrj.application.apple.menu.about.name",
938 System.setProperty("apple.laf.useScreenMenuBar", "true");
939 set = setQuaquaLookAndFeel();
940 if ((!set) || !UIManager.getLookAndFeel().getClass().toString()
941 .toLowerCase().contains("quaqua"))
943 set = setVaquaLookAndFeel();
948 private static void showUsage()
951 "Usage: jalview -open [FILE] [OUTPUT_FORMAT] [OUTPUT_FILE]\n\n"
952 + "-nodisplay\tRun Jalview without User Interface.\n"
953 + "-props FILE\tUse the given Jalview properties file instead of users default.\n"
954 + "-colour COLOURSCHEME\tThe colourscheme to be applied to the alignment\n"
955 + "-annotations FILE\tAdd precalculated annotations to the alignment.\n"
956 + "-tree FILE\tLoad the given newick format tree file onto the alignment\n"
957 + "-features FILE\tUse the given file to mark features on the alignment.\n"
958 + "-fasta FILE\tCreate alignment file FILE in Fasta format.\n"
959 + "-clustal FILE\tCreate alignment file FILE in Clustal format.\n"
960 + "-pfam FILE\tCreate alignment file FILE in PFAM format.\n"
961 + "-msf FILE\tCreate alignment file FILE in MSF format.\n"
962 + "-pileup FILE\tCreate alignment file FILE in Pileup format\n"
963 + "-pir FILE\tCreate alignment file FILE in PIR format.\n"
964 + "-blc FILE\tCreate alignment file FILE in BLC format.\n"
965 + "-json FILE\tCreate alignment file FILE in JSON format.\n"
966 + "-jalview FILE\tCreate alignment file FILE in Jalview format.\n"
967 + "-png FILE\tCreate PNG image FILE from alignment.\n"
968 + "-svg FILE\tCreate SVG image FILE from alignment.\n"
969 + "-html FILE\tCreate HTML file from alignment.\n"
970 + "-biojsMSA FILE\tCreate BioJS MSA Viewer HTML file from alignment.\n"
971 + "-imgMap FILE\tCreate HTML file FILE with image map of PNG image.\n"
972 + "-eps FILE\tCreate EPS file FILE from alignment.\n"
973 + "-questionnaire URL\tQueries the given URL for information about any Jalview user questionnaires.\n"
974 + "-noquestionnaire\tTurn off questionnaire check.\n"
975 + "-nonews\tTurn off check for Jalview news.\n"
976 + "-nousagestats\tTurn off google analytics tracking for this session.\n"
977 + "-sortbytree OR -nosortbytree\tEnable or disable sorting of the given alignment by the given tree\n"
979 // "-setprop PROPERTY=VALUE\tSet the given Jalview property,
980 // after all other properties files have been read\n\t
981 // (quote the 'PROPERTY=VALUE' pair to ensure spaces are
982 // passed in correctly)"
983 + "-jabaws URL\tSpecify URL for Jabaws services (e.g. for a local installation).\n"
984 + "-fetchfrom nickname\tQuery nickname for features for the alignments and display them.\n"
985 + "-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"
986 + "-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"
987 + "-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"
988 + "\n~Read documentation in Application or visit https://www.jalview.org for description of Features and Annotations file~\n\n");
991 private static void startUsageStats(final Desktop desktop)
994 * start a User Config prompt asking if we can log usage statistics.
996 PromptUserConfig prompter = new PromptUserConfig(Desktop.desktop,
997 "USAGESTATS", "Jalview Usage Statistics",
998 "Do you want to help make Jalview better by enabling "
999 + "the collection of usage statistics with Google Analytics ?"
1000 + "\n\n(you can enable or disable usage tracking in the preferences)",
1007 "Initialising googletracker for usage stats.");
1008 Cache.initGoogleTracker();
1009 Cache.log.debug("Tracking enabled.");
1016 Cache.log.debug("Not enabling Google Tracking.");
1019 desktop.addDialogThread(prompter);
1023 * Locate the given string as a file and pass it to the groovy interpreter.
1025 * @param groovyscript
1026 * the script to execute
1027 * @param jalviewContext
1028 * the Jalview Desktop object passed in to the groovy binding as the
1031 private void executeGroovyScript(String groovyscript, AlignFrame af)
1034 * for scripts contained in files
1041 if (groovyscript.trim().equals("STDIN"))
1043 // read from stdin into a tempfile and execute it
1046 tfile = File.createTempFile("jalview", "groovy");
1047 PrintWriter outfile = new PrintWriter(
1048 new OutputStreamWriter(new FileOutputStream(tfile)));
1049 BufferedReader br = new BufferedReader(
1050 new InputStreamReader(System.in));
1052 while ((line = br.readLine()) != null)
1054 outfile.write(line + "\n");
1060 } catch (Exception ex)
1062 System.err.println("Failed to read from STDIN into tempfile "
1063 + ((tfile == null) ? "(tempfile wasn't created)"
1064 : tfile.toString()));
1065 ex.printStackTrace();
1070 sfile = tfile.toURI().toURL();
1071 } catch (Exception x)
1074 "Unexpected Malformed URL Exception for temporary file created from STDIN: "
1076 x.printStackTrace();
1084 sfile = new URI(groovyscript).toURL();
1085 } catch (Exception x)
1087 tfile = new File(groovyscript);
1088 if (!tfile.exists())
1090 System.err.println("File '" + groovyscript + "' does not exist.");
1093 if (!tfile.canRead())
1095 System.err.println("File '" + groovyscript + "' cannot be read.");
1098 if (tfile.length() < 1)
1100 System.err.println("File '" + groovyscript + "' is empty.");
1105 sfile = tfile.getAbsoluteFile().toURI().toURL();
1106 } catch (Exception ex)
1108 System.err.println("Failed to create a file URL for "
1109 + tfile.getAbsoluteFile());
1116 Map<String, java.lang.Object> vbinding = new HashMap<>();
1117 vbinding.put("Jalview", this);
1120 vbinding.put("currentAlFrame", af);
1122 Binding gbinding = new Binding(vbinding);
1123 GroovyScriptEngine gse = new GroovyScriptEngine(new URL[] { sfile });
1124 gse.run(sfile.toString(), gbinding);
1125 if ("STDIN".equals(groovyscript))
1127 // delete temp file that we made -
1128 // only if it was successfully executed
1131 } catch (Exception e)
1133 System.err.println("Exception Whilst trying to execute file " + sfile
1134 + " as a groovy script.");
1135 e.printStackTrace(System.err);
1140 public static boolean isHeadlessMode()
1142 String isheadless = System.getProperty("java.awt.headless");
1143 if (isheadless != null && isheadless.equalsIgnoreCase("true"))
1150 public AlignFrame[] getAlignFrames()
1152 return desktop == null ? new AlignFrame[] { getCurrentAlignFrame() }
1153 : Desktop.getAlignFrames();
1158 * Quit method delegates to Desktop.quit - unless running in headless mode
1159 * when it just ends the JVM
1163 if (desktop != null)
1173 public static AlignFrame getCurrentAlignFrame()
1175 return Jalview.currentAlignFrame;
1178 public static void setCurrentAlignFrame(AlignFrame currentAlignFrame)
1180 Jalview.currentAlignFrame = currentAlignFrame;