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 jalview.api.AlignFrameI;
24 import jalview.api.AlignViewportI;
25 import jalview.api.JalviewApp;
26 import jalview.api.StructureSelectionManagerProvider;
27 import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
28 import jalview.datamodel.ColumnSelection;
29 import jalview.datamodel.HiddenColumns;
30 import jalview.datamodel.PDBEntry;
31 import jalview.datamodel.SequenceGroup;
32 import jalview.datamodel.SequenceI;
33 import jalview.ext.so.SequenceOntology;
34 import jalview.gui.AlignFrame;
35 import jalview.gui.AlignViewport;
36 import jalview.gui.AlignmentPanel;
37 import jalview.gui.CalculationChooser;
38 import jalview.gui.Desktop;
39 import jalview.gui.Preferences;
40 import jalview.gui.PromptUserConfig;
41 import jalview.gui.StructureViewer;
42 import jalview.io.AppletFormatAdapter;
43 import jalview.io.BioJsHTMLOutput;
44 import jalview.io.DataSourceType;
45 import jalview.io.FileFormat;
46 import jalview.io.FileFormatException;
47 import jalview.io.FileFormatI;
48 import jalview.io.FileFormats;
49 import jalview.io.FileLoader;
50 import jalview.io.HtmlSvgOutput;
51 import jalview.io.IdentifyFile;
52 import jalview.io.NewickFile;
53 import jalview.io.gff.SequenceOntologyFactory;
54 import jalview.javascript.JSFunctionExec;
55 import jalview.javascript.MouseOverStructureListener;
56 import jalview.renderer.seqfeatures.FeatureRenderer;
57 import jalview.schemes.ColourSchemeI;
58 import jalview.schemes.ColourSchemeProperty;
59 import jalview.structure.SelectionSource;
60 import jalview.structure.VamsasSource;
61 import jalview.util.MessageManager;
62 import jalview.util.Platform;
63 import jalview.ws.jws2.Jws2Discoverer;
65 import java.applet.AppletContext;
66 import java.io.BufferedReader;
68 import java.io.FileOutputStream;
69 import java.io.IOException;
70 import java.io.InputStreamReader;
71 import java.io.OutputStreamWriter;
72 import java.io.PrintWriter;
73 import java.net.MalformedURLException;
75 import java.net.URISyntaxException;
77 import java.security.AllPermission;
78 import java.security.CodeSource;
79 import java.security.PermissionCollection;
80 import java.security.Permissions;
81 import java.security.Policy;
82 import java.util.HashMap;
83 import java.util.Hashtable;
85 import java.util.Vector;
86 import java.util.logging.ConsoleHandler;
87 import java.util.logging.Level;
88 import java.util.logging.Logger;
90 import javax.swing.LookAndFeel;
91 import javax.swing.UIManager;
93 import groovy.lang.Binding;
94 import groovy.util.GroovyScriptEngine;
95 import netscape.javascript.JSObject;
98 * Main class for Jalview Application <br>
100 * start with: java -classpath "$PATH_TO_LIB$/*:$PATH_TO_CLASSES$" \
101 * jalview.bin.Jalview
103 * or on Windows: java -classpath "$PATH_TO_LIB$/*;$PATH_TO_CLASSES$" \
104 * jalview.bin.Jalview jalview.bin.Jalview
106 * (ensure -classpath arg is quoted to avoid shell expansion of '*' and do not
107 * embellish '*' to e.g. '*.jar')
110 * @version $Revision$
112 public class Jalview implements ApplicationSingletonI, JalviewJSApi
115 public static Jalview getInstance()
117 return (Jalview) ApplicationSingletonProvider
118 .getInstance(Jalview.class);
127 Platform.getURLCommandArguments();
130 private boolean headless;
132 public static boolean isHeadlessMode()
134 return getInstance().headless;
137 private Desktop desktop;
139 private AlignFrame currentAlignFrame;
141 public boolean isJavaAppletTag;
143 public String appletResourcePath;
145 JalviewAppLoader appLoader;
147 protected JSFunctionExec jsFunctionExec;
149 public static AlignFrame getCurrentAlignFrame()
151 return getInstance().currentAlignFrame;
154 public static void setCurrentAlignFrame(AlignFrame currentAlignFrame)
156 getInstance().currentAlignFrame = currentAlignFrame;
161 if (!Platform.isJS())
168 // grab all the rights we can for the JVM
169 Policy.setPolicy(new Policy()
172 public PermissionCollection getPermissions(CodeSource codesource)
174 Permissions perms = new Permissions();
175 perms.add(new AllPermission());
180 public void refresh()
188 * keep track of feature fetching tasks.
196 * TODO: generalise to track all jalview events to orchestrate batch
200 private int queued = 0;
202 private int running = 0;
204 public FeatureFetcher()
209 public void addFetcher(final AlignFrame af,
210 final Vector<String> dasSources)
212 final long id = System.currentTimeMillis();
214 final FeatureFetcher us = this;
215 new Thread(new Runnable()
227 af.setProgressBar(MessageManager
228 .getString("status.das_features_being_retrived"), id);
229 af.featureSettings_actionPerformed(null);
230 af.setProgressBar(null, id);
239 public synchronized boolean allFinished()
241 return queued == 0 && running == 0;
247 * main class for Jalview application
250 * open <em>filename</em>
252 public static void main(String[] args)
254 // setLogging(); // BH - for event debugging in JavaScript
255 getInstance().doMain(args);
259 * Allow an outside entity to initiate the second half of argument parsing
263 * @return null is good
266 public Object parseArguments(String[] args)
271 ArgsParser aparser = new ArgsParser(args);
272 return parseArguments(aparser, false);
273 } catch (Throwable t)
279 private static void logClass(String name)
281 // BH - for event debugging in JavaScript
282 ConsoleHandler consoleHandler = new ConsoleHandler();
283 consoleHandler.setLevel(Level.ALL);
284 Logger logger = Logger.getLogger(name);
285 logger.setLevel(Level.ALL);
286 logger.addHandler(consoleHandler);
289 @SuppressWarnings("unused")
290 private static void setLogging()
298 System.out.println("not in js");
301 // BH - for event debugging in JavaScript (Java mode only)
302 if (!Platform.isJS())
309 Logger.getLogger("").setLevel(Level.ALL);
310 logClass("java.awt.EventDispatchThread");
311 logClass("java.awt.EventQueue");
312 logClass("java.awt.Component");
313 logClass("java.awt.focus.Component");
314 logClass("java.awt.focus.DefaultKeyboardFocusManager");
322 void doMain(String[] args)
325 boolean isJS = Platform.isJS();
328 System.setSecurityManager(null);
332 .println("Java version: " + System.getProperty("java.version"));
333 System.out.println(System.getProperty("os.arch") + " "
334 + System.getProperty("os.name") + " "
335 + System.getProperty("os.version"));
337 ArgsParser aparser = new ArgsParser(args);
339 String usrPropsFile = aparser.getValue(ArgsParser.PROPS);
340 Cache.loadProperties(usrPropsFile);
343 isJavaAppletTag = aparser.isApplet();
346 Preferences.setAppletDefaults();
347 Cache.loadProperties(usrPropsFile); // again, because we
348 // might be changing defaults here?
351 "<Applet> found: " + aparser.getValue("Info.j2sAppletID"));
352 appletResourcePath = aparser.getValue("Info.resourcePath");
361 if (usrPropsFile != null)
364 "CMD [-props " + usrPropsFile + "] executed successfully!");
367 if (aparser.contains("help") || aparser.contains("h"))
372 if (aparser.contains(ArgsParser.NODISPLAY)
373 || aparser.contains(ArgsParser.NOGUI)
374 || aparser.contains(ArgsParser.HEADLESS)
375 || "true".equals(System.getProperty("java.awt.headless")))
382 final String jabawsUrl = aparser.getValue(ArgsParser.JABAWS);
383 if (jabawsUrl != null)
387 Jws2Discoverer.getInstance().setPreferredUrl(jabawsUrl);
389 "CMD [-jabaws " + jabawsUrl + "] executed successfully!");
390 } catch (MalformedURLException e)
393 "Invalid jabaws parameter: " + jabawsUrl + " ignored");
398 // check for property setting
399 String defs = aparser.getValue(ArgsParser.SETPROP);
402 int p = defs.indexOf('=');
405 System.err.println("Ignoring invalid setprop argument : " + defs);
409 System.out.println("Executing setprop argument: " + defs);
412 Cache.setProperty(defs.substring(0, p), defs.substring(p + 1));
415 defs = aparser.getValue(ArgsParser.SETPROP);
417 System.setProperty("http.agent",
418 "Jalview Desktop/" + Cache.getDefault("VERSION", "Unknown"));
422 } catch (NoClassDefFoundError error)
424 error.printStackTrace();
425 System.out.println("\nEssential logging libraries not found."
426 + "\nUse: java -classpath \"$PATH_TO_LIB$/*:$PATH_TO_CLASSES$\" jalview.bin.Jalview");
434 UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
435 } catch (Exception ex)
437 System.err.println("Unexpected Look and Feel Exception");
438 ex.printStackTrace();
440 if (Platform.isAMacAndNotJS())
443 LookAndFeel lookAndFeel = ch.randelshofer.quaqua.QuaquaManager
445 System.setProperty("com.apple.mrj.application.apple.menu.about.name",
447 System.setProperty("apple.laf.useScreenMenuBar", "true");
448 if (lookAndFeel != null)
452 UIManager.setLookAndFeel(lookAndFeel);
453 } catch (Throwable e)
456 "Failed to set QuaQua look and feel: " + e.toString());
459 if (lookAndFeel == null
460 || !(lookAndFeel.getClass().isAssignableFrom(
461 UIManager.getLookAndFeel().getClass()))
462 || !UIManager.getLookAndFeel().getClass().toString()
463 .toLowerCase().contains("quaqua"))
468 "Quaqua LaF not available on this plaform. Using VAqua(4).\nSee https://issues.jalview.org/browse/JAL-2976");
469 UIManager.setLookAndFeel("org.violetlib.aqua.AquaLookAndFeel");
470 } catch (Throwable e)
473 "Failed to reset look and feel: " + e.toString());
479 * configure 'full' SO model if preferences say to,
480 * else use the default (SO Lite)
482 if (Cache.getDefault(Preferences.USE_FULL_SO, false))
484 SequenceOntologyFactory.setSequenceOntology(new SequenceOntology());
489 desktop = Desktop.getInstance();
490 desktop.setInBatchMode(true); // indicate we are starting up
491 desktop.setVisible(true);
500 desktop.startServiceDiscovery();
501 if (!aparser.contains(ArgsParser.NOUSAGESTATS))
503 startUsageStats(desktop);
507 System.err.println("CMD [-nousagestats] executed successfully!");
510 if (!aparser.contains(ArgsParser.NOQUESTIONNAIRE))
512 String url = aparser.getValue(ArgsParser.QUESTIONNAIRE);
515 // Start the desktop questionnaire prompter with the specified
517 Cache.log.debug("Starting questionnaire url at " + url);
518 desktop.checkForQuestionnaire(url);
519 System.out.println("CMD questionnaire[-" + url
520 + "] executed successfully!");
524 if (Cache.getProperty(Preferences.NOQUESTIONNAIRES) == null)
526 // Start the desktop questionnaire prompter with the specified
529 // "http://anaplog.compbio.dundee.ac.uk/cgi-bin/questionnaire.pl";
531 String defurl = "http://www.jalview.org/cgi-bin/questionnaire.pl";
533 "Starting questionnaire with default url: " + defurl);
534 desktop.checkForQuestionnaire(defurl);
541 .println("CMD [-noquestionnaire] executed successfully!");
544 if (!aparser.contains(ArgsParser.NONEWS))
546 desktop.checkForNews();
549 BioJsHTMLOutput.updateBioJS();
553 parseArguments(aparser, true);
556 private Object parseArguments(ArgsParser aparser, boolean isStartup)
558 boolean isJS = Platform.isJS();
560 Desktop desktop = (headless ? null : Desktop.getInstance());
561 // script to execute after all loading is
562 // completed one way or another
563 // extract groovy argument and execute if necessary
564 String groovyscript = (isJS ? null
565 : aparser.getValue(ArgsParser.GROOVY, true));
566 String file = aparser.getValue(ArgsParser.OPEN, true);
567 // BH this here to allow split frame; not working as of 5/17/2019
568 String file2 = aparser.getValue(ArgsParser.OPEN2, true);
569 String fileFormat = (isJavaAppletTag
570 ? aparser.getAppletValue("format", null)
573 FileFormatI format = null;
574 DataSourceType protocol = null;
576 if (file == null && desktop == null)
578 System.out.println("No files to open!");
581 boolean haveImport = checkStartVamas(aparser);
582 // Finally, deal with the remaining input data.
584 if (file == null && isJavaAppletTag)
586 // Maybe the sequences are added as parameters
587 StringBuffer data = new StringBuffer("PASTE");
589 while ((file = aparser.getAppletValue("sequence" + i, null)) != null)
591 data.append(file.toString() + "\n");
594 if (data.length() > 5)
596 file = data.toString();
604 desktop.setProgressBar(
606 .getString("status.processing_commandline_args"),
607 progress = System.currentTimeMillis());
612 * ignore in JavaScript -- can't just check file existence - could load
618 if (!file.startsWith("http://") && !file.startsWith("https://"))
619 // BH 2019 added https check for Java
621 if (!(new File(file)).exists())
623 System.out.println("Can't find " + file);
632 protocol = AppletFormatAdapter.checkProtocol(file);
636 format = (isJavaAppletTag && fileFormat != null
637 ? FileFormats.getInstance().forName(fileFormat)
641 format = new IdentifyFile().identify(file, protocol);
643 } catch (FileFormatException e1)
648 AlignFrame af = new FileLoader(!headless).loadFileWaitTillLoaded(file,
652 System.out.println("error");
657 .println("CMD [-open " + file + "] executed successfully!");
660 protocol = AppletFormatAdapter.checkProtocol(file2);
663 format = new IdentifyFile().identify(file2, protocol);
664 } catch (FileFormatException e1)
668 AlignFrame af2 = new FileLoader(!headless)
669 .loadFileWaitTillLoaded(file2, protocol, format);
672 System.out.println("error");
676 AlignViewport.openLinkedAlignmentAs(af,
677 af.getViewport().getAlignment(),
678 af2.getViewport().getAlignment(), "",
679 AlignViewport.SPLIT_FRAME);
681 "CMD [-open2 " + file2 + "] executed successfully!");
685 setCurrentAlignFrame(af);
687 // TODO: file2 How to implement file2 for the applet spit screen?
689 String data = aparser.getValue(ArgsParser.COLOUR, true);
692 data.replaceAll("%20", " ");
694 ColourSchemeI cs = ColourSchemeProperty.getColourScheme(
695 af.getViewport(), af.getViewport().getAlignment(), data);
700 "CMD [-color " + data + "] executed successfully!");
705 // Must maintain ability to use the groups flag
706 data = aparser.getValue(ArgsParser.GROUPS, true);
709 af.parseFeaturesFile(data,
710 AppletFormatAdapter.checkProtocol(data));
711 // System.out.println("Added " + data);
713 "CMD groups[-" + data + "] executed successfully!");
715 data = aparser.getValue(ArgsParser.FEATURES, true);
718 af.parseFeaturesFile(data,
719 AppletFormatAdapter.checkProtocol(data));
720 // System.out.println("Added " + data);
722 "CMD [-features " + data + "] executed successfully!");
725 data = aparser.getValue(ArgsParser.ANNOTATIONS, true);
728 af.loadJalviewDataFile(data, null, null, null);
729 // System.out.println("Added " + data);
731 "CMD [-annotations " + data + "] executed successfully!");
733 // set or clear the sortbytree flag.
734 if (aparser.contains(ArgsParser.SORTBYTREE))
736 af.getViewport().setSortByTree(true);
737 if (af.getViewport().getSortByTree())
739 System.out.println("CMD [-sortbytree] executed successfully!");
743 boolean doUpdateAnnotation = false;
746 if (aparser.contains(ArgsParser.NOANNOTATION)
747 || aparser.contains(ArgsParser.NOANNOTATION2))
749 af.getViewport().setShowAnnotation(false);
750 if (!af.getViewport().isShowAnnotation())
752 doUpdateAnnotation = true;
753 System.out.println("CMD no-annotation executed successfully!");
756 if (aparser.contains(ArgsParser.NOSORTBYTREE))
758 af.getViewport().setSortByTree(false);
759 if (!af.getViewport().getSortByTree())
761 doUpdateAnnotation = true;
763 .println("CMD [-nosortbytree] executed successfully!");
766 if (doUpdateAnnotation)
768 af.setMenusForViewport();
769 af.alignPanel.updateLayout();
771 data = aparser.getValue(ArgsParser.TREE, true);
777 "CMD [-tree " + data + "] executed successfully!");
778 NewickFile nf = new NewickFile(data,
779 AppletFormatAdapter.checkProtocol(data));
781 .setCurrentTree(af.showNewickTree(nf, data).getTree());
782 } catch (IOException ex)
784 System.err.println("Couldn't add tree " + data);
785 ex.printStackTrace(System.err);
788 // TODO - load PDB structure(s) to alignment JAL-629
789 // (associate with identical sequence in alignment, or a specified
793 loadAppletParams(aparser, af);
802 if (groovyscript != null)
804 // Execute the groovy script after we've done all the rendering
806 // and before any images or figures are generated.
807 System.out.println("Executing script " + groovyscript);
808 executeGroovyScript(groovyscript, af);
809 System.out.println("CMD groovy[" + groovyscript
810 + "] executed successfully!");
813 checkOutputFile(aparser, af, format);
814 while (aparser.getSize() > 0)
816 System.out.println("Unknown arg: " + aparser.nextValue());
821 AlignFrame startUpAlframe = null;
822 // We'll only open the default file if the desktop is visible.
824 // ////////////////////
826 if (!isJS && !headless && file == null && !haveImport
827 && jalview.bin.Cache.getDefault("SHOW_STARTUP_FILE", true))
834 file = jalview.bin.Cache.getDefault("STARTUP_FILE",
835 jalview.bin.Cache.getDefault("www.jalview.org",
836 "http://www.jalview.org")
837 + "/examples/exampleFile_2_7.jar");
839 "http://www.jalview.org/examples/exampleFile_2_3.jar"))
841 // hardwire upgrade of the startup file
842 file.replace("_2_3.jar", "_2_7.jar");
843 // and remove the stale setting
844 jalview.bin.Cache.removeProperty("STARTUP_FILE");
847 protocol = DataSourceType.FILE;
849 if (file.indexOf("http:") > -1)
851 protocol = DataSourceType.URL;
854 if (file.endsWith(".jar"))
856 format = FileFormat.Jalview;
862 format = new IdentifyFile().identify(file, protocol);
863 } catch (FileFormatException e)
869 startUpAlframe = new FileLoader(!headless)
870 .loadFileWaitTillLoaded(file, protocol, format);
871 // extract groovy arguments before anything else.
874 // Once all other stuff is done, execute any groovy scripts (in order)
875 if (groovyscript != null)
877 if (Cache.groovyJarsPresent())
879 System.out.println("Executing script " + groovyscript);
880 executeGroovyScript(groovyscript, startUpAlframe);
885 "Sorry. Groovy Support is not available, so ignoring the provided groovy script "
889 // and finally, turn off batch mode indicator - if the desktop still exists
894 desktop.setProgressBar(null, progress);
896 desktop.setInBatchMode(false);
902 private boolean checkStartVamas(ArgsParser aparser)
904 String vamsasImport = aparser.getValue(ArgsParser.VDOC);
905 String vamsasSession = aparser.getValue(ArgsParser.VSESS);
906 if (vamsasImport == null && vamsasSession == null)
910 if (desktop == null || headless)
913 "Headless vamsas sessions not yet supported. Sorry.");
916 boolean haveImport = (vamsasImport != null);
919 // if we have a file, start a new session and import it.
920 boolean inSession = false;
923 DataSourceType viprotocol = AppletFormatAdapter
924 .checkProtocol(vamsasImport);
925 if (viprotocol == DataSourceType.FILE)
927 inSession = desktop.vamsasImport(new File(vamsasImport));
929 else if (viprotocol == DataSourceType.URL)
931 inSession = desktop.vamsasImport(new URL(vamsasImport));
934 } catch (Exception e)
936 System.err.println("Exeption when importing " + vamsasImport
937 + " as a vamsas document.");
942 System.err.println("Failed to import " + vamsasImport
943 + " as a vamsas document.");
947 System.out.println("Imported Successfully into new session "
948 + desktop.getVamsasApplication().getCurrentSession());
951 if (vamsasSession != null)
953 if (vamsasImport != null)
955 // close the newly imported session and import the Jalview specific
956 // remnants into the new session later on.
957 desktop.vamsasStop_actionPerformed(null);
959 // now join the new session
962 if (desktop.joinVamsasSession(vamsasSession))
965 "Successfully joined vamsas session " + vamsasSession);
969 System.err.println("WARNING: Failed to join vamsas session "
972 } catch (Exception e)
975 "ERROR: Failed to join vamsas session " + vamsasSession);
978 if (vamsasImport != null)
980 // the Jalview specific remnants can now be imported into the new
981 // session at the user's leisure.
983 "Skipping Push for import of data into existing vamsas session.");
989 // desktop.getVamsasApplication().push_update();
995 private void checkOutputFile(ArgsParser aparser, AlignFrame af,
998 String imageName = "unnamed.png";
999 while (aparser.getSize() > 1)
1004 // biojsmsa filename
1005 String outputFormat = aparser.nextValue();
1006 String file = aparser.nextValue();
1007 if (outputFormat.equalsIgnoreCase("png"))
1009 af.createPNG(new File(file));
1010 imageName = (new File(file)).getName();
1011 System.out.println("Creating PNG image: " + file);
1014 else if (outputFormat.equalsIgnoreCase("svg"))
1016 File imageFile = new File(file);
1017 imageName = imageFile.getName();
1018 af.createSVG(imageFile);
1019 System.out.println("Creating SVG image: " + file);
1022 else if (outputFormat.equalsIgnoreCase("html"))
1024 File imageFile = new File(file);
1025 imageName = imageFile.getName();
1026 HtmlSvgOutput htmlSVG = new HtmlSvgOutput(af.alignPanel);
1027 htmlSVG.exportHTML(file);
1029 System.out.println("Creating HTML image: " + file);
1032 else if (outputFormat.equalsIgnoreCase("biojsmsa"))
1036 System.err.println("The output html file must not be null");
1041 BioJsHTMLOutput.refreshVersionInfo(
1042 BioJsHTMLOutput.BJS_TEMPLATES_LOCAL_DIRECTORY);
1043 } catch (URISyntaxException e)
1045 e.printStackTrace();
1047 BioJsHTMLOutput bjs = new BioJsHTMLOutput(af.alignPanel);
1048 bjs.exportHTML(file);
1049 System.out.println("Creating BioJS MSA Viwer HTML file: " + file);
1052 else if (outputFormat.equalsIgnoreCase("imgMap"))
1054 af.createImageMap(new File(file), imageName);
1055 System.out.println("Creating image map: " + file);
1058 else if (outputFormat.equalsIgnoreCase("eps"))
1060 File outputFile = new File(file);
1062 "Creating EPS file: " + outputFile.getAbsolutePath());
1063 af.createEPS(outputFile);
1067 af.saveAlignment(file, format);
1068 if (af.isSaveAlignmentSuccessful())
1071 "Written alignment in " + format + " format to " + file);
1075 System.out.println("Error writing file " + file + " in " + format
1082 private static void showUsage()
1085 "Usage: jalview -open [FILE] [OUTPUT_FORMAT] [OUTPUT_FILE]\n\n"
1086 + "-nodisplay\tRun Jalview without User Interface.\n"
1087 + "-props FILE\tUse the given Jalview properties file instead of users default.\n"
1088 + "-colour COLOURSCHEME\tThe colourscheme to be applied to the alignment\n"
1089 + "-annotations FILE\tAdd precalculated annotations to the alignment.\n"
1090 + "-tree FILE\tLoad the given newick format tree file onto the alignment\n"
1091 + "-features FILE\tUse the given file to mark features on the alignment.\n"
1092 + "-fasta FILE\tCreate alignment file FILE in Fasta format.\n"
1093 + "-clustal FILE\tCreate alignment file FILE in Clustal format.\n"
1094 + "-pfam FILE\tCreate alignment file FILE in PFAM format.\n"
1095 + "-msf FILE\tCreate alignment file FILE in MSF format.\n"
1096 + "-pileup FILE\tCreate alignment file FILE in Pileup format\n"
1097 + "-pir FILE\tCreate alignment file FILE in PIR format.\n"
1098 + "-blc FILE\tCreate alignment file FILE in BLC format.\n"
1099 + "-json FILE\tCreate alignment file FILE in JSON format.\n"
1100 + "-jalview FILE\tCreate alignment file FILE in Jalview format.\n"
1101 + "-png FILE\tCreate PNG image FILE from alignment.\n"
1102 + "-svg FILE\tCreate SVG image FILE from alignment.\n"
1103 + "-html FILE\tCreate HTML file from alignment.\n"
1104 + "-biojsMSA FILE\tCreate BioJS MSA Viewer HTML file from alignment.\n"
1105 + "-imgMap FILE\tCreate HTML file FILE with image map of PNG image.\n"
1106 + "-eps FILE\tCreate EPS file FILE from alignment.\n"
1107 + "-questionnaire URL\tQueries the given URL for information about any Jalview user questionnaires.\n"
1108 + "-noquestionnaire\tTurn off questionnaire check.\n"
1109 + "-nonews\tTurn off check for Jalview news.\n"
1110 + "-nousagestats\tTurn off google analytics tracking for this session.\n"
1111 + "-sortbytree OR -nosortbytree\tEnable or disable sorting of the given alignment by the given tree\n"
1113 // "-setprop PROPERTY=VALUE\tSet the given Jalview property,
1114 // after all other properties files have been read\n\t
1115 // (quote the 'PROPERTY=VALUE' pair to ensure spaces are
1116 // passed in correctly)"
1117 + "-jabaws URL\tSpecify URL for Jabaws services (e.g. for a local installation).\n"
1118 + "-fetchfrom nickname\tQuery nickname for features for the alignments and display them.\n"
1120 // "-vdoc vamsas-document\tImport vamsas document into new
1121 // session or join existing session with same URN\n"
1122 // + "-vses vamsas-session\tJoin session with given URN\n"
1123 + "-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"
1124 + "\n~Read documentation in Application or visit http://www.jalview.org for description of Features and Annotations file~\n\n");
1127 private static void startUsageStats(final Desktop desktop)
1130 * start a User Config prompt asking if we can log usage statistics.
1132 PromptUserConfig prompter = new PromptUserConfig(
1133 Desktop.getDesktopPane(), "USAGESTATS",
1134 "Jalview Usage Statistics",
1135 "Do you want to help make Jalview better by enabling "
1136 + "the collection of usage statistics with Google Analytics ?"
1137 + "\n\n(you can enable or disable usage tracking in the preferences)",
1144 "Initialising googletracker for usage stats.");
1145 Cache.initGoogleTracker();
1146 Cache.log.debug("Tracking enabled.");
1153 Cache.log.debug("Not enabling Google Tracking.");
1156 desktop.addDialogThread(prompter);
1160 * Locate the given string as a file and pass it to the groovy interpreter.
1162 * @param groovyscript
1163 * the script to execute
1164 * @param jalviewContext
1165 * the Jalview Desktop object passed in to the groovy binding as the
1168 private void executeGroovyScript(String groovyscript, AlignFrame af)
1171 * for scripts contained in files
1178 if (groovyscript.trim().equals("STDIN"))
1180 // read from stdin into a tempfile and execute it
1183 tfile = File.createTempFile("jalview", "groovy");
1184 PrintWriter outfile = new PrintWriter(
1185 new OutputStreamWriter(new FileOutputStream(tfile)));
1186 BufferedReader br = new BufferedReader(
1187 new InputStreamReader(System.in));
1189 while ((line = br.readLine()) != null)
1191 outfile.write(line + "\n");
1197 } catch (Exception ex)
1199 System.err.println("Failed to read from STDIN into tempfile "
1200 + ((tfile == null) ? "(tempfile wasn't created)"
1201 : tfile.toString()));
1202 ex.printStackTrace();
1207 sfile = tfile.toURI().toURL();
1208 } catch (Exception x)
1211 "Unexpected Malformed URL Exception for temporary file created from STDIN: "
1213 x.printStackTrace();
1221 sfile = new URI(groovyscript).toURL();
1222 } catch (Exception x)
1224 tfile = new File(groovyscript);
1225 if (!tfile.exists())
1227 System.err.println("File '" + groovyscript + "' does not exist.");
1230 if (!tfile.canRead())
1232 System.err.println("File '" + groovyscript + "' cannot be read.");
1235 if (tfile.length() < 1)
1237 System.err.println("File '" + groovyscript + "' is empty.");
1242 sfile = tfile.getAbsoluteFile().toURI().toURL();
1243 } catch (Exception ex)
1245 System.err.println("Failed to create a file URL for "
1246 + tfile.getAbsoluteFile());
1253 Map<String, Object> vbinding = new HashMap<>();
1254 vbinding.put("Jalview", this);
1257 vbinding.put("currentAlFrame", af);
1259 Binding gbinding = new Binding(vbinding);
1260 GroovyScriptEngine gse = new GroovyScriptEngine(new URL[] { sfile });
1261 gse.run(sfile.toString(), gbinding);
1262 if ("STDIN".equals(groovyscript))
1264 // delete temp file that we made -
1265 // only if it was successfully executed
1268 } catch (Exception e)
1270 System.err.println("Exception Whilst trying to execute file " + sfile
1271 + " as a groovy script.");
1272 e.printStackTrace(System.err);
1277 public AlignFrame[] getAlignFrames()
1279 return desktop == null ? new AlignFrame[] { getCurrentAlignFrame() }
1280 : Desktop.getAlignFrames();
1285 * Quit method delegates to Desktop.quit - unless running in headless mode
1286 * when it just ends the JVM
1290 if (jsFunctionExec != null)
1292 jsFunctionExec.tidyUp();
1293 jsFunctionExec = null;
1296 if (desktop != null)
1307 * Get the SwingJS applet ID and combine that with the frameType
1310 * "alignment", "desktop", etc., or null
1313 public static String getAppID(String frameType)
1315 String id = Cache.getProperty("Info.j2sAppletID");
1320 return id + (frameType == null ? "" : "-" + frameType);
1324 * Handle all JalviewLite applet parameters
1329 private void loadAppletParams(ArgsParser aparser, AlignFrame af)
1331 JalviewApp app = new JalviewApp()
1336 // These are methods that are in JalviewLite that various classes call
1337 // but are not in JalviewLiteJsApi. Or, even if they are, other classes
1339 // them to JalviewLite directly. Some may not be necessary, but they have
1341 // be at least mentioned here, or the classes calling them should
1343 // JalviewLite itself.
1345 private boolean alignPDBStructures; // From JalviewLite; not implemented
1347 private Hashtable<String, Hashtable<String, String[]>> jsmessages;
1349 private Hashtable<String, int[]> jshashes;
1352 public String getParameter(String name)
1354 return aparser.getAppletValue(name, null);
1358 public boolean getDefaultParameter(String name, boolean def)
1361 return ((stn = getParameter(name)) == null ? def
1362 : "true".equalsIgnoreCase(stn));
1366 * Get the applet-like document base even though this is an application.
1369 public URL getDocumentBase()
1371 return Platform.getDocumentBase();
1375 * Get the applet-like code base even though this is an application.
1378 public URL getCodeBase()
1380 return Platform.getCodeBase();
1384 public AlignViewportI getViewport()
1386 return af.getViewport();
1394 public boolean parseFeaturesFile(String filename,
1395 DataSourceType protocol)
1397 return af.parseFeaturesFile(filename, protocol);
1405 public boolean loadScoreFile(String sScoreFile) throws IOException
1407 af.loadJalviewDataFile(sScoreFile, null, null, null);
1412 * annotations, jpredfile, jnetfile
1416 public void updateForAnnotations()
1418 af.updateForAnnotations();
1422 public void loadTree(NewickFile fin, String treeFile)
1425 // n/a -- already done by standard Jalview command line processing
1429 public void setAlignPdbStructures(boolean defaultParameter)
1431 alignPDBStructures = true;
1435 public void newStructureView(PDBEntry pdb, SequenceI[] seqs,
1436 String[] chains, DataSourceType protocol)
1438 StructureViewer.launchStructureViewer(af.alignPanel, pdb, seqs);
1442 public void setFeatureGroupState(String[] groups, boolean state)
1444 af.setFeatureGroupState(groups, state);
1448 public void alignedStructureView(PDBEntry[] pdb, SequenceI[][] seqs,
1449 String[][] chains, String[] protocols)
1452 "Jalview applet interface alignedStructureView not implemented");
1456 public void newFeatureSettings()
1459 "Jalview applet interface newFeatureSettings not implemented");
1462 private Vector<Runnable> jsExecQueue;
1465 public Vector<Runnable> getJsExecQueue(JSFunctionExec exec)
1467 jsFunctionExec = exec;
1468 return (jsExecQueue == null ? (jsExecQueue = new Vector<>())
1473 public AppletContext getAppletContext()
1475 // TODO Auto-generated method stub
1480 public boolean isJsfallbackEnabled()
1482 // TODO Auto-generated method stub
1487 public JSObject getJSObject()
1489 // TODO Auto-generated method stub
1494 public StructureSelectionManagerProvider getStructureSelectionManagerProvider()
1496 // TODO Q: what exactly is this? BH
1501 public void updateColoursFromMouseOver(Object source,
1502 MouseOverStructureListener mouseOverStructureListener)
1504 // TODO Auto-generated method stub
1509 public Object[] getSelectionForListener(SequenceGroup seqsel,
1510 ColumnSelection colsel, HiddenColumns hidden,
1511 SelectionSource source, Object alignFrame)
1513 return appLoader.getSelectionForListener(getCurrentAlignFrame(),
1514 seqsel, colsel, hidden, source, alignFrame);
1518 public String arrayToSeparatorList(String[] array)
1520 return appLoader.arrayToSeparatorList(array);
1524 public Hashtable<String, int[]> getJSHashes()
1526 return (jshashes == null ? (jshashes = new Hashtable<>())
1531 public Hashtable<String, Hashtable<String, String[]>> getJSMessages()
1533 return (jsmessages == null ? (jsmessages = new Hashtable<>())
1538 public Object getFrameForSource(VamsasSource source)
1543 if (source instanceof jalview.gui.AlignViewport
1544 && source == (af = getCurrentAlignFrame()).getViewport())
1546 // should be valid if it just generated an event!
1549 // TODO: ensure that if '_af' is specified along with a handler
1550 // function, then only events from that alignFrame are sent to that
1557 public FeatureRenderer getNewFeatureRenderer(AlignViewportI vp)
1559 return new jalview.gui.FeatureRenderer((AlignmentPanel) vp);
1564 appLoader = new JalviewAppLoader(true);
1565 appLoader.load(app);
1570 * @see jalview.bin.JalviewLiteJsApi#getSelectedSequences()
1573 public String getSelectedSequences()
1575 return getSelectedSequencesFrom(getCurrentAlignFrame());
1580 * @see jalview.bin.JalviewLiteJsApi#getSelectedSequences(java.lang.String)
1583 public String getSelectedSequences(String sep)
1585 return getSelectedSequencesFrom(getCurrentAlignFrame(), sep);
1590 * @see jalview.bin.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
1594 public String getSelectedSequencesFrom(AlignFrameI alf)
1596 return getSelectedSequencesFrom(alf, null);
1601 * @see jalview.bin.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
1602 * .AlignFrame, java.lang.String)
1605 public String getSelectedSequencesFrom(AlignFrameI alf, String sep)
1607 return appLoader.getSelectedSequencesFrom(alf, sep);
1612 * @see jalview.bin.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
1613 * .AlignFrame, java.lang.String)
1616 public void highlight(String sequenceId, String position,
1617 String alignedPosition)
1619 highlightIn(getCurrentAlignFrame(), sequenceId, position,
1624 public void highlightIn(AlignFrameI alf, String sequenceId,
1625 String position, String alignedPosition)
1627 appLoader.highlightIn(alf, sequenceId, position, alignedPosition);
1631 public void select(String sequenceIds, String columns)
1633 selectIn(getCurrentAlignFrame(), sequenceIds, columns, null);
1637 public void select(String sequenceIds, String columns, String sep)
1639 selectIn(getCurrentAlignFrame(), sequenceIds, columns, sep);
1643 public void selectIn(AlignFrameI alf, String sequenceIds, String columns)
1645 selectIn(alf, sequenceIds, columns, null);
1649 public void selectIn(AlignFrameI alf, String sequenceIds, String columns,
1652 appLoader.selectIn(alf, sequenceIds, columns, sep);
1656 public String getSelectedSequencesAsAlignment(String format,
1659 return getSelectedSequencesAsAlignmentFrom(getCurrentAlignFrame(),
1664 public String getSelectedSequencesAsAlignmentFrom(AlignFrameI alf,
1665 String format, String sep)
1667 return appLoader.getSelectedSequencesAsAlignmentFrom(alf, format, sep);
1671 public String getAlignmentOrder()
1673 return getAlignmentFrom(getCurrentAlignFrame(), null);
1677 public String getAlignmentOrderFrom(AlignFrameI alf)
1679 return getAlignmentFrom(alf, null);
1683 public String getAlignmentOrderFrom(AlignFrameI alf, String sep)
1685 return appLoader.getAlignmentOrderFrom(alf, sep);
1689 public String orderBy(String order, String undoName)
1691 return orderBy(order, undoName, null);
1695 public String orderBy(String order, String undoName, String sep)
1697 return orderAlignmentBy(getCurrentAlignFrame(), order, undoName, sep);
1701 public String orderAlignmentBy(AlignFrameI alf, String order,
1702 String undoName, String sep)
1704 return appLoader.orderAlignmentBy(alf, order, undoName, sep);
1708 public String getAlignment(String format)
1710 return getAlignmentFrom(null, format, null);
1714 public String getAlignmentFrom(AlignFrameI alf, String format)
1716 return getAlignmentFrom(alf, format, null);
1720 public String getAlignment(String format, String suffix)
1722 return getAlignmentFrom(getCurrentAlignFrame(), format, suffix);
1726 public String getAlignmentFrom(AlignFrameI alf, String format,
1729 return appLoader.getAlignmentFrom(alf, format, suffix);
1733 public void loadAnnotation(String annotation)
1735 loadAnnotationFrom(getCurrentAlignFrame(), annotation);
1739 public void loadAnnotationFrom(AlignFrameI alf, String annotation)
1741 appLoader.loadAnnotationFrom(alf, annotation);
1745 public void loadFeatures(String features, boolean autoenabledisplay)
1747 loadFeaturesFrom(currentAlignFrame, features, autoenabledisplay);
1751 public boolean loadFeaturesFrom(AlignFrameI alf, String features,
1752 boolean autoenabledisplay)
1754 return appLoader.loadFeaturesFrom(alf, features, autoenabledisplay);
1758 public String getFeatures(String format)
1760 return getFeaturesFrom(getCurrentAlignFrame(), format);
1764 public String getFeaturesFrom(AlignFrameI alf, String format)
1766 return appLoader.getFeaturesFrom(alf, format);
1770 public String getAnnotation()
1772 return getAnnotationFrom(getCurrentAlignFrame());
1776 public String getAnnotationFrom(AlignFrameI alf)
1778 return appLoader.getAnnotationFrom(alf);
1782 public AlignFrameI newView()
1784 return newViewFrom(getCurrentAlignFrame(), null);
1788 public AlignFrameI newView(String name)
1790 return newViewFrom(getCurrentAlignFrame(), name);
1794 public AlignFrameI newViewFrom(AlignFrameI alf)
1796 return newViewFrom(alf, null);
1800 public AlignFrameI newViewFrom(AlignFrameI alf, String name)
1802 return appLoader.newViewFrom(alf, name);
1806 public AlignFrameI loadAlignment(String text, String title)
1808 return appLoader.loadAlignment(text, AlignFrame.DEFAULT_WIDTH,
1809 AlignFrame.DEFAULT_HEIGHT, title);
1813 public boolean addPdbFile(AlignFrameI alFrame, String sequenceId,
1814 String pdbEntryString, String pdbFile)
1816 return appLoader.addPdbFile(alFrame, sequenceId, pdbEntryString,
1821 public void scrollViewToIn(AlignFrameI alf, String topRow,
1822 String leftHandColumn)
1824 appLoader.scrollViewToIn(alf, topRow, leftHandColumn);
1828 public void scrollViewToRowIn(AlignFrameI alf, String topRow)
1830 appLoader.scrollViewToRowIn(alf, topRow);
1834 public void scrollViewToColumnIn(AlignFrameI alf, String leftHandColumn)
1836 appLoader.scrollViewToColumnIn(alf, leftHandColumn);
1840 public String getFeatureGroups()
1842 return getFeatureGroupsOn(getCurrentAlignFrame());
1846 public String getFeatureGroupsOn(AlignFrameI alf)
1848 return appLoader.getFeatureGroupsOn(alf);
1852 public String getFeatureGroupsOfState(boolean visible)
1854 return getFeatureGroupsOfStateOn(getCurrentAlignFrame(), visible);
1858 public String getFeatureGroupsOfStateOn(AlignFrameI alf, boolean visible)
1860 return appLoader.getFeatureGroupsOfStateOn(alf, visible);
1864 public void setFeatureGroupStateOn(AlignFrameI alf, String groups,
1867 setFeatureGroupStateOn(alf, groups, state);
1871 public void setFeatureGroupState(String groups, boolean state)
1873 appLoader.setFeatureGroupStateOn(getCurrentAlignFrame(), groups, state);
1877 public String getSeparator()
1879 return appLoader.getSeparator();
1883 public void setSeparator(String separator)
1885 appLoader.setSeparator(separator);
1889 public String getJsMessage(String messageclass, String viewId)
1891 // see http://www.jalview.org/examples/jalviewLiteJs.html
1896 * Open a new Tree panel on the desktop statically. Params are standard (not
1897 * set by Groovy). No dialog is opened.
1902 * @return null, or the string "label.you_need_at_least_n_sequences" if number
1903 * of sequences selected is inappropriate
1906 public Object openTreePanel(AlignFrame af, String treeType,
1909 return CalculationChooser.openTreePanel(af, treeType, modelName, null);
1913 * public static method for JalviewJS API to open a PCAPanel without
1914 * necessarily using a dialog.
1918 * @return the PCAPanel, or the string "label.you_need_at_least_n_sequences"
1919 * if number of sequences selected is inappropriate
1922 public Object openPcaPanel(AlignFrame af, String modelName)
1924 return CalculationChooser.openPcaPanel(af, modelName, null);
1928 public String getSelectedSequencesAsAlignment(String format,
1931 return getSelectedSequencesAsAlignmentFrom(getCurrentAlignFrame(),
1936 public String getSelectedSequencesAsAlignmentFrom(AlignFrameI alf,
1937 String format, boolean suffix)
1939 return appLoader.getSelectedSequencesAsAlignmentFrom(alf, format,
1944 public String arrayToSeparatorList(String[] array)
1946 return appLoader.arrayToSeparatorList(array);
1950 public String[] separatorListToArray(String list)
1952 return appLoader.separatorListToArray(list);
1955 //// probably not needed in JalviewJS -- From when Jmol and Jalview did not
1956 //// have a direct connection?
1959 public void setMouseoverListener(String listener)
1961 // TODO Auto-generated method stub
1966 public void setMouseoverListener(AlignFrameI af, String listener)
1968 // TODO Auto-generated method stub
1973 public void setSelectionListener(String listener)
1975 // TODO Auto-generated method stub
1980 public void setSelectionListener(AlignFrameI af, String listener)
1982 // TODO Auto-generated method stub
1987 public void setStructureListener(String listener, String modelSet)
1989 // TODO Auto-generated method stub
1994 public void removeJavascriptListener(AlignFrameI af, String listener)
1996 // TODO Auto-generated method stub
2001 public void mouseOverStructure(String pdbResNum, String chain,
2004 // TODO Auto-generated method stub