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")
379 || Cache.getProperty("NONEWS") == null)
381 desktop.checkForNews();
384 BioJsHTMLOutput.updateBioJS();
387 // Move any new getdown-launcher-new.jar into place over old
388 // getdown-launcher.jar
389 String appdirString = System.getProperty("getdownappdir");
390 if (appdirString != null && appdirString.length() > 0)
392 final File appdir = new File(appdirString);
398 LaunchUtil.upgradeGetdown(
399 new File(appdir, "getdown-launcher-old.jar"),
400 new File(appdir, "getdown-launcher.jar"),
401 new File(appdir, "getdown-launcher-new.jar"));
406 String file = null, data = null;
407 FileFormatI format = null;
408 DataSourceType protocol = null;
409 FileLoader fileLoader = new FileLoader(!headless);
411 String groovyscript = null; // script to execute after all loading is
412 // completed one way or another
413 // extract groovy argument and execute if necessary
414 groovyscript = aparser.getValue("groovy", true);
415 file = aparser.getValue("open", true);
417 if (file == null && desktop == null)
419 System.out.println("No files to open!");
423 // Finally, deal with the remaining input data.
428 desktop.setProgressBar(
430 .getString("status.processing_commandline_args"),
431 progress = System.currentTimeMillis());
433 System.out.println("CMD [-open " + file + "] executed successfully!");
435 protocol = AppletFormatAdapter.checkProtocol(file);
437 if (protocol == DataSourceType.FILE)
439 if (!(new File(file)).exists())
441 System.out.println("Can't find " + file);
451 format = new IdentifyFile().identify(file, protocol);
452 } catch (FileFormatException e1)
457 AlignFrame af = fileLoader.LoadFileWaitTillLoaded(file, protocol,
461 System.out.println("error");
465 setCurrentAlignFrame(af);
466 data = aparser.getValue("colour", true);
469 data.replaceAll("%20", " ");
471 ColourSchemeI cs = ColourSchemeProperty.getColourScheme(
472 af.getViewport(), af.getViewport().getAlignment(), data);
477 "CMD [-color " + data + "] executed successfully!");
482 // Must maintain ability to use the groups flag
483 data = aparser.getValue("groups", true);
486 af.parseFeaturesFile(data,
487 AppletFormatAdapter.checkProtocol(data));
488 // System.out.println("Added " + data);
490 "CMD groups[-" + data + "] executed successfully!");
492 data = aparser.getValue("features", true);
495 af.parseFeaturesFile(data,
496 AppletFormatAdapter.checkProtocol(data));
497 // System.out.println("Added " + data);
499 "CMD [-features " + data + "] executed successfully!");
502 data = aparser.getValue("annotations", true);
505 af.loadJalviewDataFile(data, null, null, null);
506 // System.out.println("Added " + data);
508 "CMD [-annotations " + data + "] executed successfully!");
510 // set or clear the sortbytree flag.
511 if (aparser.contains("sortbytree"))
513 af.getViewport().setSortByTree(true);
514 if (af.getViewport().getSortByTree())
516 System.out.println("CMD [-sortbytree] executed successfully!");
519 if (aparser.contains("no-annotation"))
521 af.getViewport().setShowAnnotation(false);
522 if (!af.getViewport().isShowAnnotation())
524 System.out.println("CMD no-annotation executed successfully!");
527 if (aparser.contains("nosortbytree"))
529 af.getViewport().setSortByTree(false);
530 if (!af.getViewport().getSortByTree())
533 .println("CMD [-nosortbytree] executed successfully!");
536 data = aparser.getValue("tree", true);
542 "CMD [-tree " + data + "] executed successfully!");
543 NewickFile nf = new NewickFile(data,
544 AppletFormatAdapter.checkProtocol(data));
546 .setCurrentTree(af.showNewickTree(nf, data).getTree());
547 } catch (IOException ex)
549 System.err.println("Couldn't add tree " + data);
550 ex.printStackTrace(System.err);
553 // TODO - load PDB structure(s) to alignment JAL-629
554 // (associate with identical sequence in alignment, or a specified
556 if (groovyscript != null)
558 // Execute the groovy script after we've done all the rendering stuff
559 // and before any images or figures are generated.
560 System.out.println("Executing script " + groovyscript);
561 executeGroovyScript(groovyscript, af);
562 System.out.println("CMD groovy[" + groovyscript
563 + "] executed successfully!");
566 String imageName = "unnamed.png";
567 while (aparser.getSize() > 1)
569 String outputFormat = aparser.nextValue();
570 file = aparser.nextValue();
572 if (outputFormat.equalsIgnoreCase("png"))
574 af.createPNG(new File(file));
575 imageName = (new File(file)).getName();
576 System.out.println("Creating PNG image: " + file);
579 else if (outputFormat.equalsIgnoreCase("svg"))
581 File imageFile = new File(file);
582 imageName = imageFile.getName();
583 af.createSVG(imageFile);
584 System.out.println("Creating SVG image: " + file);
587 else if (outputFormat.equalsIgnoreCase("html"))
589 File imageFile = new File(file);
590 imageName = imageFile.getName();
591 HtmlSvgOutput htmlSVG = new HtmlSvgOutput(af.alignPanel);
592 htmlSVG.exportHTML(file);
594 System.out.println("Creating HTML image: " + file);
597 else if (outputFormat.equalsIgnoreCase("biojsmsa"))
601 System.err.println("The output html file must not be null");
606 BioJsHTMLOutput.refreshVersionInfo(
607 BioJsHTMLOutput.BJS_TEMPLATES_LOCAL_DIRECTORY);
608 } catch (URISyntaxException e)
612 BioJsHTMLOutput bjs = new BioJsHTMLOutput(af.alignPanel);
613 bjs.exportHTML(file);
615 .println("Creating BioJS MSA Viwer HTML file: " + file);
618 else if (outputFormat.equalsIgnoreCase("imgMap"))
620 af.createImageMap(new File(file), imageName);
621 System.out.println("Creating image map: " + file);
624 else if (outputFormat.equalsIgnoreCase("eps"))
626 File outputFile = new File(file);
628 "Creating EPS file: " + outputFile.getAbsolutePath());
629 af.createEPS(outputFile);
632 FileFormatI outFormat = null;
635 outFormat = FileFormats.getInstance().forName(outputFormat);
636 } catch (Exception formatP)
638 System.out.println("Couldn't parse " + outFormat
639 + " as a valid Jalview format string.");
641 if (outFormat != null)
643 if (!outFormat.isWritable())
646 "This version of Jalview does not support alignment export as "
651 if (af.saveAlignment(file, outFormat))
653 System.out.println("Written alignment in " + format
654 + " format to " + file);
658 System.out.println("Error writing file " + file + " in "
659 + format + " format!!");
665 while (aparser.getSize() > 0)
667 System.out.println("Unknown arg: " + aparser.nextValue());
671 AlignFrame startUpAlframe = null;
672 // We'll only open the default file if the desktop is visible.
674 // ////////////////////
676 if (!headless && file == null
677 && jalview.bin.Cache.getDefault("SHOW_STARTUP_FILE", true))
679 file = jalview.bin.Cache.getDefault("STARTUP_FILE",
680 jalview.bin.Cache.getDefault("www.jalview.org",
681 "https://www.jalview.org")
682 + "/examples/exampleFile_2_7.jvp");
683 if (file.equals("http://www.jalview.org/examples/exampleFile_2_3.jar")
685 "http://www.jalview.org/examples/exampleFile_2_7.jar"))
687 file.replace("http:", "https:");
688 // hardwire upgrade of the startup file
689 file.replace("_2_3", "_2_7");
690 file.replace("2_7.jar", "2_7.jvp");
691 // and remove the stale setting
692 jalview.bin.Cache.removeProperty("STARTUP_FILE");
695 protocol = AppletFormatAdapter.checkProtocol(file);
697 if (file.endsWith(".jar"))
699 format = FileFormat.Jalview;
705 format = new IdentifyFile().identify(file, protocol);
706 } catch (FileFormatException e)
712 startUpAlframe = fileLoader.LoadFileWaitTillLoaded(file, protocol,
714 // extract groovy arguments before anything else.
717 // Once all other stuff is done, execute any groovy scripts (in order)
718 if (groovyscript != null)
720 if (Cache.groovyJarsPresent())
722 System.out.println("Executing script " + groovyscript);
723 executeGroovyScript(groovyscript, startUpAlframe);
728 "Sorry. Groovy Support is not available, so ignoring the provided groovy script "
732 // and finally, turn off batch mode indicator - if the desktop still exists
737 desktop.setProgressBar(null, progress);
739 desktop.setInBatchMode(false);
743 private static void setLookAndFeel()
745 // property laf = "crossplatform", "system", "gtk", "metal", "nimbus" or
747 // If not set (or chosen laf fails), use the normal SystemLaF and if on Mac,
749 String lafProp = System.getProperty("laf");
750 String lafSetting = Cache.getDefault("PREFERRED_LAF", null);
756 else if (lafSetting != null)
760 boolean lafSet = false;
763 case "crossplatform":
764 lafSet = setCrossPlatformLookAndFeel();
767 Cache.log.error("Could not set requested laf=" + laf);
771 lafSet = setSystemLookAndFeel();
774 Cache.log.error("Could not set requested laf=" + laf);
778 lafSet = setGtkLookAndFeel();
781 Cache.log.error("Could not set requested laf=" + laf);
785 lafSet = setMetalLookAndFeel();
788 Cache.log.error("Could not set requested laf=" + laf);
792 lafSet = setNimbusLookAndFeel();
795 Cache.log.error("Could not set requested laf=" + laf);
799 lafSet = setQuaquaLookAndFeel();
802 Cache.log.error("Could not set requested laf=" + laf);
806 lafSet = setVaquaLookAndFeel();
809 Cache.log.error("Could not set requested laf=" + laf);
813 lafSet = setMacLookAndFeel();
816 Cache.log.error("Could not set requested laf=" + laf);
822 Cache.log.error("Requested laf=" + laf + " not implemented");
826 setSystemLookAndFeel();
827 if (Platform.isLinux())
829 setMetalLookAndFeel();
831 if (Platform.isAMac())
838 private static boolean setCrossPlatformLookAndFeel()
840 return setGenericLookAndFeel(false);
843 private static boolean setSystemLookAndFeel()
845 return setGenericLookAndFeel(true);
848 private static boolean setGenericLookAndFeel(boolean system)
853 UIManager.setLookAndFeel(
854 system ? UIManager.getSystemLookAndFeelClassName()
855 : UIManager.getCrossPlatformLookAndFeelClassName());
857 } catch (Exception ex)
859 Cache.log.error("Unexpected Look and Feel Exception");
860 Cache.log.error(ex.getMessage());
861 Cache.log.debug(Cache.getStackTraceString(ex));
866 private static boolean setSpecificLookAndFeel(String name,
867 String className, boolean nameStartsWith)
872 for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels())
874 if (info.getName() != null && nameStartsWith
875 ? info.getName().toLowerCase()
876 .startsWith(name.toLowerCase())
877 : info.getName().toLowerCase().equals(name.toLowerCase()))
879 className = info.getClassName();
883 UIManager.setLookAndFeel(className);
885 } catch (Exception ex)
887 Cache.log.error("Unexpected Look and Feel Exception");
888 Cache.log.error(ex.getMessage());
889 Cache.log.debug(Cache.getStackTraceString(ex));
894 private static boolean setGtkLookAndFeel()
896 return setSpecificLookAndFeel("gtk",
897 "com.sun.java.swing.plaf.gtk.GTKLookAndFeel", true);
900 private static boolean setMetalLookAndFeel()
902 return setSpecificLookAndFeel("metal",
903 "javax.swing.plaf.metal.MetalLookAndFeel", false);
906 private static boolean setNimbusLookAndFeel()
908 return setSpecificLookAndFeel("nimbus",
909 "javax.swing.plaf.nimbus.NimbusLookAndFeel", false);
912 private static boolean setQuaquaLookAndFeel()
914 return setSpecificLookAndFeel("quaqua",
915 ch.randelshofer.quaqua.QuaquaManager.getLookAndFeel().getClass()
920 private static boolean setVaquaLookAndFeel()
922 return setSpecificLookAndFeel("vaqua",
923 "org.violetlib.aqua.AquaLookAndFeel", false);
926 private static boolean setMacLookAndFeel()
929 System.setProperty("com.apple.mrj.application.apple.menu.about.name",
931 System.setProperty("apple.laf.useScreenMenuBar", "true");
932 set = setQuaquaLookAndFeel();
933 if ((!set) || !UIManager.getLookAndFeel().getClass().toString()
934 .toLowerCase().contains("quaqua"))
936 set = setVaquaLookAndFeel();
941 private static void showUsage()
944 "Usage: jalview -open [FILE] [OUTPUT_FORMAT] [OUTPUT_FILE]\n\n"
945 + "-nodisplay\tRun Jalview without User Interface.\n"
946 + "-props FILE\tUse the given Jalview properties file instead of users default.\n"
947 + "-colour COLOURSCHEME\tThe colourscheme to be applied to the alignment\n"
948 + "-annotations FILE\tAdd precalculated annotations to the alignment.\n"
949 + "-tree FILE\tLoad the given newick format tree file onto the alignment\n"
950 + "-features FILE\tUse the given file to mark features on the alignment.\n"
951 + "-fasta FILE\tCreate alignment file FILE in Fasta format.\n"
952 + "-clustal FILE\tCreate alignment file FILE in Clustal format.\n"
953 + "-pfam FILE\tCreate alignment file FILE in PFAM format.\n"
954 + "-msf FILE\tCreate alignment file FILE in MSF format.\n"
955 + "-pileup FILE\tCreate alignment file FILE in Pileup format\n"
956 + "-pir FILE\tCreate alignment file FILE in PIR format.\n"
957 + "-blc FILE\tCreate alignment file FILE in BLC format.\n"
958 + "-json FILE\tCreate alignment file FILE in JSON format.\n"
959 + "-jalview FILE\tCreate alignment file FILE in Jalview format.\n"
960 + "-png FILE\tCreate PNG image FILE from alignment.\n"
961 + "-svg FILE\tCreate SVG image FILE from alignment.\n"
962 + "-html FILE\tCreate HTML file from alignment.\n"
963 + "-biojsMSA FILE\tCreate BioJS MSA Viewer HTML file from alignment.\n"
964 + "-imgMap FILE\tCreate HTML file FILE with image map of PNG image.\n"
965 + "-eps FILE\tCreate EPS file FILE from alignment.\n"
966 + "-questionnaire URL\tQueries the given URL for information about any Jalview user questionnaires.\n"
967 + "-noquestionnaire\tTurn off questionnaire check.\n"
968 + "-nonews\tTurn off check for Jalview news.\n"
969 + "-nousagestats\tTurn off google analytics tracking for this session.\n"
970 + "-sortbytree OR -nosortbytree\tEnable or disable sorting of the given alignment by the given tree\n"
972 // "-setprop PROPERTY=VALUE\tSet the given Jalview property,
973 // after all other properties files have been read\n\t
974 // (quote the 'PROPERTY=VALUE' pair to ensure spaces are
975 // passed in correctly)"
976 + "-jabaws URL\tSpecify URL for Jabaws services (e.g. for a local installation).\n"
977 + "-fetchfrom nickname\tQuery nickname for features for the alignments and display them.\n"
978 + "-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"
979 + "-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"
980 + "-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"
981 + "\n~Read documentation in Application or visit https://www.jalview.org for description of Features and Annotations file~\n\n");
984 private static void startUsageStats(final Desktop desktop)
987 * start a User Config prompt asking if we can log usage statistics.
989 PromptUserConfig prompter = new PromptUserConfig(Desktop.desktop,
990 "USAGESTATS", "Jalview Usage Statistics",
991 "Do you want to help make Jalview better by enabling "
992 + "the collection of usage statistics with Google Analytics ?"
993 + "\n\n(you can enable or disable usage tracking in the preferences)",
1000 "Initialising googletracker for usage stats.");
1001 Cache.initGoogleTracker();
1002 Cache.log.debug("Tracking enabled.");
1009 Cache.log.debug("Not enabling Google Tracking.");
1012 desktop.addDialogThread(prompter);
1016 * Locate the given string as a file and pass it to the groovy interpreter.
1018 * @param groovyscript
1019 * the script to execute
1020 * @param jalviewContext
1021 * the Jalview Desktop object passed in to the groovy binding as the
1024 private void executeGroovyScript(String groovyscript, AlignFrame af)
1027 * for scripts contained in files
1034 if (groovyscript.trim().equals("STDIN"))
1036 // read from stdin into a tempfile and execute it
1039 tfile = File.createTempFile("jalview", "groovy");
1040 PrintWriter outfile = new PrintWriter(
1041 new OutputStreamWriter(new FileOutputStream(tfile)));
1042 BufferedReader br = new BufferedReader(
1043 new InputStreamReader(System.in));
1045 while ((line = br.readLine()) != null)
1047 outfile.write(line + "\n");
1053 } catch (Exception ex)
1055 System.err.println("Failed to read from STDIN into tempfile "
1056 + ((tfile == null) ? "(tempfile wasn't created)"
1057 : tfile.toString()));
1058 ex.printStackTrace();
1063 sfile = tfile.toURI().toURL();
1064 } catch (Exception x)
1067 "Unexpected Malformed URL Exception for temporary file created from STDIN: "
1069 x.printStackTrace();
1077 sfile = new URI(groovyscript).toURL();
1078 } catch (Exception x)
1080 tfile = new File(groovyscript);
1081 if (!tfile.exists())
1083 System.err.println("File '" + groovyscript + "' does not exist.");
1086 if (!tfile.canRead())
1088 System.err.println("File '" + groovyscript + "' cannot be read.");
1091 if (tfile.length() < 1)
1093 System.err.println("File '" + groovyscript + "' is empty.");
1098 sfile = tfile.getAbsoluteFile().toURI().toURL();
1099 } catch (Exception ex)
1101 System.err.println("Failed to create a file URL for "
1102 + tfile.getAbsoluteFile());
1109 Map<String, java.lang.Object> vbinding = new HashMap<>();
1110 vbinding.put("Jalview", this);
1113 vbinding.put("currentAlFrame", af);
1115 Binding gbinding = new Binding(vbinding);
1116 GroovyScriptEngine gse = new GroovyScriptEngine(new URL[] { sfile });
1117 gse.run(sfile.toString(), gbinding);
1118 if ("STDIN".equals(groovyscript))
1120 // delete temp file that we made -
1121 // only if it was successfully executed
1124 } catch (Exception e)
1126 System.err.println("Exception Whilst trying to execute file " + sfile
1127 + " as a groovy script.");
1128 e.printStackTrace(System.err);
1133 public static boolean isHeadlessMode()
1135 String isheadless = System.getProperty("java.awt.headless");
1136 if (isheadless != null && isheadless.equalsIgnoreCase("true"))
1143 public AlignFrame[] getAlignFrames()
1145 return desktop == null ? new AlignFrame[] { getCurrentAlignFrame() }
1146 : Desktop.getAlignFrames();
1151 * Quit method delegates to Desktop.quit - unless running in headless mode
1152 * when it just ends the JVM
1156 if (desktop != null)
1166 public static AlignFrame getCurrentAlignFrame()
1168 return Jalview.currentAlignFrame;
1171 public static void setCurrentAlignFrame(AlignFrame currentAlignFrame)
1173 Jalview.currentAlignFrame = currentAlignFrame;