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 final String jabawsUrl = aparser.getValue("jabaws");
251 if (jabawsUrl != null)
255 Jws2Discoverer.getDiscoverer().setPreferredUrl(jabawsUrl);
257 "CMD [-jabaws " + jabawsUrl + "] executed successfully!");
258 } catch (MalformedURLException e)
261 "Invalid jabaws parameter: " + jabawsUrl + " ignored");
265 String defs = aparser.getValue("setprop");
268 int p = defs.indexOf('=');
271 System.err.println("Ignoring invalid setprop argument : " + defs);
275 System.out.println("Executing setprop argument: " + defs);
276 // DISABLED FOR SECURITY REASONS
277 // TODO: add a property to allow properties to be overriden by cli args
278 // Cache.setProperty(defs.substring(0,p), defs.substring(p+1));
280 defs = aparser.getValue("setprop");
282 if (System.getProperty("java.awt.headless") != null
283 && System.getProperty("java.awt.headless").equals("true"))
287 System.setProperty("http.agent",
288 "Jalview Desktop/" + Cache.getDefault("VERSION", "Unknown"));
292 } catch (NoClassDefFoundError error)
294 error.printStackTrace();
295 System.out.println("\nEssential logging libraries not found."
296 + "\nUse: java -classpath \"$PATH_TO_LIB$/*:$PATH_TO_CLASSES$\" jalview.bin.Jalview");
305 * configure 'full' SO model if preferences say to, else use the default (SO
308 if (Cache.getDefault("USE_FULL_SO", true))
310 SequenceOntologyFactory.setInstance(new SequenceOntology());
316 desktop = new Desktop();
317 desktop.setInBatchMode(true); // indicate we are starting up
321 JalviewTaskbar.setTaskbar(this);
322 } catch (Exception e)
324 Cache.log.info("Cannot set Taskbar");
325 Cache.log.error(e.getMessage());
326 // e.printStackTrace();
327 } catch (Throwable t)
329 Cache.log.info("Cannot set Taskbar");
330 Cache.log.error(t.getMessage());
331 // t.printStackTrace();
334 desktop.setVisible(true);
335 desktop.startServiceDiscovery();
336 if (!aparser.contains("nousagestats"))
338 startUsageStats(desktop);
342 System.err.println("CMD [-nousagestats] executed successfully!");
345 if (!aparser.contains("noquestionnaire"))
347 String url = aparser.getValue("questionnaire");
350 // Start the desktop questionnaire prompter with the specified
352 Cache.log.debug("Starting questionnaire url at " + url);
353 desktop.checkForQuestionnaire(url);
355 "CMD questionnaire[-" + url + "] executed successfully!");
359 if (Cache.getProperty("NOQUESTIONNAIRES") == null)
361 // Start the desktop questionnaire prompter with the specified
364 // "http://anaplog.compbio.dundee.ac.uk/cgi-bin/questionnaire.pl";
366 String defurl = "https://www.jalview.org/cgi-bin/questionnaire.pl";
368 "Starting questionnaire with default url: " + defurl);
369 desktop.checkForQuestionnaire(defurl);
375 System.err.println("CMD [-noquestionnaire] executed successfully!");
378 if (!aparser.contains("nonews"))
380 desktop.checkForNews();
383 BioJsHTMLOutput.updateBioJS();
386 // Move any new getdown-launcher-new.jar into place over old
387 // getdown-launcher.jar
388 String appdirString = System.getProperty("getdownappdir");
389 if (appdirString != null && appdirString.length() > 0)
391 final File appdir = new File(appdirString);
397 LaunchUtil.upgradeGetdown(
398 new File(appdir, "getdown-launcher-old.jar"),
399 new File(appdir, "getdown-launcher.jar"),
400 new File(appdir, "getdown-launcher-new.jar"));
405 String file = null, data = null;
406 FileFormatI format = null;
407 DataSourceType protocol = null;
408 FileLoader fileLoader = new FileLoader(!headless);
410 String groovyscript = null; // script to execute after all loading is
411 // completed one way or another
412 // extract groovy argument and execute if necessary
413 groovyscript = aparser.getValue("groovy", true);
414 file = aparser.getValue("open", true);
416 if (file == null && desktop == null)
418 System.out.println("No files to open!");
422 // Finally, deal with the remaining input data.
427 desktop.setProgressBar(
429 .getString("status.processing_commandline_args"),
430 progress = System.currentTimeMillis());
432 System.out.println("CMD [-open " + file + "] executed successfully!");
434 protocol = AppletFormatAdapter.checkProtocol(file);
436 if (protocol == DataSourceType.FILE)
438 if (!(new File(file)).exists())
440 System.out.println("Can't find " + file);
450 format = new IdentifyFile().identify(file, protocol);
451 } catch (FileFormatException e1)
456 AlignFrame af = fileLoader.LoadFileWaitTillLoaded(file, protocol,
460 System.out.println("error");
464 setCurrentAlignFrame(af);
465 data = aparser.getValue("colour", true);
468 data.replaceAll("%20", " ");
470 ColourSchemeI cs = ColourSchemeProperty.getColourScheme(
471 af.getViewport(), af.getViewport().getAlignment(), data);
476 "CMD [-color " + data + "] executed successfully!");
481 // Must maintain ability to use the groups flag
482 data = aparser.getValue("groups", true);
485 af.parseFeaturesFile(data,
486 AppletFormatAdapter.checkProtocol(data));
487 // System.out.println("Added " + data);
489 "CMD groups[-" + data + "] executed successfully!");
491 data = aparser.getValue("features", true);
494 af.parseFeaturesFile(data,
495 AppletFormatAdapter.checkProtocol(data));
496 // System.out.println("Added " + data);
498 "CMD [-features " + data + "] executed successfully!");
501 data = aparser.getValue("annotations", true);
504 af.loadJalviewDataFile(data, null, null, null);
505 // System.out.println("Added " + data);
507 "CMD [-annotations " + data + "] executed successfully!");
509 // set or clear the sortbytree flag.
510 if (aparser.contains("sortbytree"))
512 af.getViewport().setSortByTree(true);
513 if (af.getViewport().getSortByTree())
515 System.out.println("CMD [-sortbytree] executed successfully!");
518 if (aparser.contains("no-annotation"))
520 af.getViewport().setShowAnnotation(false);
521 if (!af.getViewport().isShowAnnotation())
523 System.out.println("CMD no-annotation executed successfully!");
526 if (aparser.contains("nosortbytree"))
528 af.getViewport().setSortByTree(false);
529 if (!af.getViewport().getSortByTree())
532 .println("CMD [-nosortbytree] executed successfully!");
535 data = aparser.getValue("tree", true);
541 "CMD [-tree " + data + "] executed successfully!");
542 NewickFile nf = new NewickFile(data,
543 AppletFormatAdapter.checkProtocol(data));
545 .setCurrentTree(af.showNewickTree(nf, data).getTree());
546 } catch (IOException ex)
548 System.err.println("Couldn't add tree " + data);
549 ex.printStackTrace(System.err);
552 // TODO - load PDB structure(s) to alignment JAL-629
553 // (associate with identical sequence in alignment, or a specified
555 if (groovyscript != null)
557 // Execute the groovy script after we've done all the rendering stuff
558 // and before any images or figures are generated.
559 System.out.println("Executing script " + groovyscript);
560 executeGroovyScript(groovyscript, af);
561 System.out.println("CMD groovy[" + groovyscript
562 + "] executed successfully!");
565 String imageName = "unnamed.png";
566 while (aparser.getSize() > 1)
568 String outputFormat = aparser.nextValue();
569 file = aparser.nextValue();
571 if (outputFormat.equalsIgnoreCase("png"))
573 af.createPNG(new File(file));
574 imageName = (new File(file)).getName();
575 System.out.println("Creating PNG image: " + file);
578 else if (outputFormat.equalsIgnoreCase("svg"))
580 File imageFile = new File(file);
581 imageName = imageFile.getName();
582 af.createSVG(imageFile);
583 System.out.println("Creating SVG image: " + file);
586 else if (outputFormat.equalsIgnoreCase("html"))
588 File imageFile = new File(file);
589 imageName = imageFile.getName();
590 HtmlSvgOutput htmlSVG = new HtmlSvgOutput(af.alignPanel);
591 htmlSVG.exportHTML(file);
593 System.out.println("Creating HTML image: " + file);
596 else if (outputFormat.equalsIgnoreCase("biojsmsa"))
600 System.err.println("The output html file must not be null");
605 BioJsHTMLOutput.refreshVersionInfo(
606 BioJsHTMLOutput.BJS_TEMPLATES_LOCAL_DIRECTORY);
607 } catch (URISyntaxException e)
611 BioJsHTMLOutput bjs = new BioJsHTMLOutput(af.alignPanel);
612 bjs.exportHTML(file);
614 .println("Creating BioJS MSA Viwer HTML file: " + file);
617 else if (outputFormat.equalsIgnoreCase("imgMap"))
619 af.createImageMap(new File(file), imageName);
620 System.out.println("Creating image map: " + file);
623 else if (outputFormat.equalsIgnoreCase("eps"))
625 File outputFile = new File(file);
627 "Creating EPS file: " + outputFile.getAbsolutePath());
628 af.createEPS(outputFile);
631 FileFormatI outFormat = null;
634 outFormat = FileFormats.getInstance().forName(outputFormat);
635 } catch (Exception formatP)
637 System.out.println("Couldn't parse " + outFormat
638 + " as a valid Jalview format string.");
640 if (outFormat != null)
642 if (!outFormat.isWritable())
645 "This version of Jalview does not support alignment export as "
650 if (af.saveAlignment(file, outFormat))
652 System.out.println("Written alignment in " + format
653 + " format to " + file);
657 System.out.println("Error writing file " + file + " in "
658 + format + " format!!");
664 while (aparser.getSize() > 0)
666 System.out.println("Unknown arg: " + aparser.nextValue());
670 AlignFrame startUpAlframe = null;
671 // We'll only open the default file if the desktop is visible.
673 // ////////////////////
675 if (!headless && file == null
676 && jalview.bin.Cache.getDefault("SHOW_STARTUP_FILE", true))
678 file = jalview.bin.Cache.getDefault("STARTUP_FILE",
679 jalview.bin.Cache.getDefault("www.jalview.org",
680 "https://www.jalview.org")
681 + "/examples/exampleFile_2_7.jvp");
682 if (file.equals("http://www.jalview.org/examples/exampleFile_2_3.jar")
684 "http://www.jalview.org/examples/exampleFile_2_7.jar"))
686 file.replace("http:", "https:");
687 // hardwire upgrade of the startup file
688 file.replace("_2_3", "_2_7");
689 file.replace("2_7.jar", "2_7.jvp");
690 // and remove the stale setting
691 jalview.bin.Cache.removeProperty("STARTUP_FILE");
694 protocol = DataSourceType.FILE;
696 if (HttpUtils.startsWithHttpOrHttps(file))
698 protocol = DataSourceType.URL;
701 if (file.endsWith(".jar"))
703 format = FileFormat.Jalview;
709 format = new IdentifyFile().identify(file, protocol);
710 } catch (FileFormatException e)
716 startUpAlframe = fileLoader.LoadFileWaitTillLoaded(file, protocol,
718 // extract groovy arguments before anything else.
721 // Once all other stuff is done, execute any groovy scripts (in order)
722 if (groovyscript != null)
724 if (Cache.groovyJarsPresent())
726 System.out.println("Executing script " + groovyscript);
727 executeGroovyScript(groovyscript, startUpAlframe);
732 "Sorry. Groovy Support is not available, so ignoring the provided groovy script "
736 // and finally, turn off batch mode indicator - if the desktop still exists
741 desktop.setProgressBar(null, progress);
743 desktop.setInBatchMode(false);
747 private static void setLookAndFeel()
749 // property laf = "crossplatform", "system", "gtk", "metal", "nimbus" or
751 // If not set (or chosen laf fails), use the normal SystemLaF and if on Mac,
753 String lafProp = System.getProperty("laf");
754 String lafSetting = Cache.getDefault("PREFERRED_LAF", null);
760 else if (lafSetting != null)
764 boolean lafSet = false;
767 case "crossplatform":
768 lafSet = setCrossPlatformLookAndFeel();
771 Cache.log.error("Could not set requested laf=" + laf);
775 lafSet = setSystemLookAndFeel();
778 Cache.log.error("Could not set requested laf=" + laf);
782 lafSet = setGtkLookAndFeel();
785 Cache.log.error("Could not set requested laf=" + laf);
789 lafSet = setMetalLookAndFeel();
792 Cache.log.error("Could not set requested laf=" + laf);
796 lafSet = setNimbusLookAndFeel();
799 Cache.log.error("Could not set requested laf=" + laf);
803 lafSet = setQuaquaLookAndFeel();
806 Cache.log.error("Could not set requested laf=" + laf);
810 lafSet = setVaquaLookAndFeel();
813 Cache.log.error("Could not set requested laf=" + laf);
817 lafSet = setMacLookAndFeel();
820 Cache.log.error("Could not set requested laf=" + laf);
826 Cache.log.error("Requested laf=" + laf + " not implemented");
830 setSystemLookAndFeel();
831 if (Platform.isLinux())
833 setMetalLookAndFeel();
835 if (Platform.isAMac())
842 private static boolean setCrossPlatformLookAndFeel()
844 return setGenericLookAndFeel(false);
847 private static boolean setSystemLookAndFeel()
849 return setGenericLookAndFeel(true);
852 private static boolean setGenericLookAndFeel(boolean system)
857 UIManager.setLookAndFeel(
858 system ? UIManager.getSystemLookAndFeelClassName()
859 : UIManager.getCrossPlatformLookAndFeelClassName());
861 } catch (Exception ex)
863 Cache.log.error("Unexpected Look and Feel Exception");
864 Cache.log.error(ex.getMessage());
865 Cache.log.debug(Cache.getStackTraceString(ex));
870 private static boolean setSpecificLookAndFeel(String name,
871 String className, boolean nameStartsWith)
876 for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels())
878 if (info.getName() != null && nameStartsWith
879 ? info.getName().toLowerCase()
880 .startsWith(name.toLowerCase())
881 : info.getName().toLowerCase().equals(name.toLowerCase()))
883 className = info.getClassName();
887 UIManager.setLookAndFeel(className);
889 } catch (Exception ex)
891 Cache.log.error("Unexpected Look and Feel Exception");
892 Cache.log.error(ex.getMessage());
893 Cache.log.debug(Cache.getStackTraceString(ex));
898 private static boolean setGtkLookAndFeel()
900 return setSpecificLookAndFeel("gtk",
901 "com.sun.java.swing.plaf.gtk.GTKLookAndFeel", true);
904 private static boolean setMetalLookAndFeel()
906 return setSpecificLookAndFeel("metal",
907 "javax.swing.plaf.metal.MetalLookAndFeel", false);
910 private static boolean setNimbusLookAndFeel()
912 return setSpecificLookAndFeel("nimbus",
913 "javax.swing.plaf.nimbus.NimbusLookAndFeel", false);
916 private static boolean setQuaquaLookAndFeel()
918 return setSpecificLookAndFeel("quaqua",
919 ch.randelshofer.quaqua.QuaquaManager.getLookAndFeel().getClass()
924 private static boolean setVaquaLookAndFeel()
926 return setSpecificLookAndFeel("vaqua",
927 "org.violetlib.aqua.AquaLookAndFeel", false);
930 private static boolean setMacLookAndFeel()
933 System.setProperty("com.apple.mrj.application.apple.menu.about.name",
935 System.setProperty("apple.laf.useScreenMenuBar", "true");
936 set = setQuaquaLookAndFeel();
937 if ((!set) || !UIManager.getLookAndFeel().getClass().toString()
938 .toLowerCase().contains("quaqua"))
940 set = setVaquaLookAndFeel();
945 private static void showUsage()
948 "Usage: jalview -open [FILE] [OUTPUT_FORMAT] [OUTPUT_FILE]\n\n"
949 + "-nodisplay\tRun Jalview without User Interface.\n"
950 + "-props FILE\tUse the given Jalview properties file instead of users default.\n"
951 + "-colour COLOURSCHEME\tThe colourscheme to be applied to the alignment\n"
952 + "-annotations FILE\tAdd precalculated annotations to the alignment.\n"
953 + "-tree FILE\tLoad the given newick format tree file onto the alignment\n"
954 + "-features FILE\tUse the given file to mark features on the alignment.\n"
955 + "-fasta FILE\tCreate alignment file FILE in Fasta format.\n"
956 + "-clustal FILE\tCreate alignment file FILE in Clustal format.\n"
957 + "-pfam FILE\tCreate alignment file FILE in PFAM format.\n"
958 + "-msf FILE\tCreate alignment file FILE in MSF format.\n"
959 + "-pileup FILE\tCreate alignment file FILE in Pileup format\n"
960 + "-pir FILE\tCreate alignment file FILE in PIR format.\n"
961 + "-blc FILE\tCreate alignment file FILE in BLC format.\n"
962 + "-json FILE\tCreate alignment file FILE in JSON format.\n"
963 + "-jalview FILE\tCreate alignment file FILE in Jalview format.\n"
964 + "-png FILE\tCreate PNG image FILE from alignment.\n"
965 + "-svg FILE\tCreate SVG image FILE from alignment.\n"
966 + "-html FILE\tCreate HTML file from alignment.\n"
967 + "-biojsMSA FILE\tCreate BioJS MSA Viewer HTML file from alignment.\n"
968 + "-imgMap FILE\tCreate HTML file FILE with image map of PNG image.\n"
969 + "-eps FILE\tCreate EPS file FILE from alignment.\n"
970 + "-questionnaire URL\tQueries the given URL for information about any Jalview user questionnaires.\n"
971 + "-noquestionnaire\tTurn off questionnaire check.\n"
972 + "-nonews\tTurn off check for Jalview news.\n"
973 + "-nousagestats\tTurn off google analytics tracking for this session.\n"
974 + "-sortbytree OR -nosortbytree\tEnable or disable sorting of the given alignment by the given tree\n"
976 // "-setprop PROPERTY=VALUE\tSet the given Jalview property,
977 // after all other properties files have been read\n\t
978 // (quote the 'PROPERTY=VALUE' pair to ensure spaces are
979 // passed in correctly)"
980 + "-jabaws URL\tSpecify URL for Jabaws services (e.g. for a local installation).\n"
981 + "-fetchfrom nickname\tQuery nickname for features for the alignments and display them.\n"
982 + "-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"
983 + "-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"
984 + "-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"
985 + "\n~Read documentation in Application or visit https://www.jalview.org for description of Features and Annotations file~\n\n");
988 private static void startUsageStats(final Desktop desktop)
991 * start a User Config prompt asking if we can log usage statistics.
993 PromptUserConfig prompter = new PromptUserConfig(Desktop.desktop,
994 "USAGESTATS", "Jalview Usage Statistics",
995 "Do you want to help make Jalview better by enabling "
996 + "the collection of usage statistics with Google Analytics ?"
997 + "\n\n(you can enable or disable usage tracking in the preferences)",
1004 "Initialising googletracker for usage stats.");
1005 Cache.initGoogleTracker();
1006 Cache.log.debug("Tracking enabled.");
1013 Cache.log.debug("Not enabling Google Tracking.");
1016 desktop.addDialogThread(prompter);
1020 * Locate the given string as a file and pass it to the groovy interpreter.
1022 * @param groovyscript
1023 * the script to execute
1024 * @param jalviewContext
1025 * the Jalview Desktop object passed in to the groovy binding as the
1028 private void executeGroovyScript(String groovyscript, AlignFrame af)
1031 * for scripts contained in files
1038 if (groovyscript.trim().equals("STDIN"))
1040 // read from stdin into a tempfile and execute it
1043 tfile = File.createTempFile("jalview", "groovy");
1044 PrintWriter outfile = new PrintWriter(
1045 new OutputStreamWriter(new FileOutputStream(tfile)));
1046 BufferedReader br = new BufferedReader(
1047 new InputStreamReader(System.in));
1049 while ((line = br.readLine()) != null)
1051 outfile.write(line + "\n");
1057 } catch (Exception ex)
1059 System.err.println("Failed to read from STDIN into tempfile "
1060 + ((tfile == null) ? "(tempfile wasn't created)"
1061 : tfile.toString()));
1062 ex.printStackTrace();
1067 sfile = tfile.toURI().toURL();
1068 } catch (Exception x)
1071 "Unexpected Malformed URL Exception for temporary file created from STDIN: "
1073 x.printStackTrace();
1081 sfile = new URI(groovyscript).toURL();
1082 } catch (Exception x)
1084 tfile = new File(groovyscript);
1085 if (!tfile.exists())
1087 System.err.println("File '" + groovyscript + "' does not exist.");
1090 if (!tfile.canRead())
1092 System.err.println("File '" + groovyscript + "' cannot be read.");
1095 if (tfile.length() < 1)
1097 System.err.println("File '" + groovyscript + "' is empty.");
1102 sfile = tfile.getAbsoluteFile().toURI().toURL();
1103 } catch (Exception ex)
1105 System.err.println("Failed to create a file URL for "
1106 + tfile.getAbsoluteFile());
1113 Map<String, java.lang.Object> vbinding = new HashMap<>();
1114 vbinding.put("Jalview", this);
1117 vbinding.put("currentAlFrame", af);
1119 Binding gbinding = new Binding(vbinding);
1120 GroovyScriptEngine gse = new GroovyScriptEngine(new URL[] { sfile });
1121 gse.run(sfile.toString(), gbinding);
1122 if ("STDIN".equals(groovyscript))
1124 // delete temp file that we made -
1125 // only if it was successfully executed
1128 } catch (Exception e)
1130 System.err.println("Exception Whilst trying to execute file " + sfile
1131 + " as a groovy script.");
1132 e.printStackTrace(System.err);
1137 public static boolean isHeadlessMode()
1139 String isheadless = System.getProperty("java.awt.headless");
1140 if (isheadless != null && isheadless.equalsIgnoreCase("true"))
1147 public AlignFrame[] getAlignFrames()
1149 return desktop == null ? new AlignFrame[] { getCurrentAlignFrame() }
1150 : Desktop.getAlignFrames();
1155 * Quit method delegates to Desktop.quit - unless running in headless mode
1156 * when it just ends the JVM
1160 if (desktop != null)
1170 public static AlignFrame getCurrentAlignFrame()
1172 return Jalview.currentAlignFrame;
1175 public static void setCurrentAlignFrame(AlignFrame currentAlignFrame)
1177 Jalview.currentAlignFrame = currentAlignFrame;