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;
87 import javax.swing.LookAndFeel;
88 import javax.swing.UIManager;
90 import groovy.lang.Binding;
91 import groovy.util.GroovyScriptEngine;
92 import netscape.javascript.JSObject;
95 * Main class for Jalview Application <br>
97 * start with: java -classpath "$PATH_TO_LIB$/*:$PATH_TO_CLASSES$" \
100 * or on Windows: java -classpath "$PATH_TO_LIB$/*;$PATH_TO_CLASSES$" \
101 * jalview.bin.Jalview jalview.bin.Jalview
103 * (ensure -classpath arg is quoted to avoid shell expansion of '*' and do not
104 * embellish '*' to e.g. '*.jar')
107 * @version $Revision$
109 public class Jalview implements ApplicationSingletonI, JalviewJSApi
112 public static Jalview getInstance()
114 return (Jalview) ApplicationSingletonProvider
115 .getInstance(Jalview.class);
124 Platform.getURLCommandArguments();
127 private boolean headless;
129 public static boolean isHeadlessMode()
131 return getInstance().headless;
134 private Desktop desktop;
136 private AlignFrame currentAlignFrame;
138 public boolean isJavaAppletTag;
140 public String appletResourcePath;
142 JalviewAppLoader appLoader;
144 protected JSFunctionExec jsFunctionExec;
146 private boolean noCalculation, noMenuBar, noStatus;
148 public boolean getStartCalculations()
150 return !noCalculation;
153 public boolean getAllowMenuBar()
158 public boolean getShowStatus()
164 public static AlignFrame getCurrentAlignFrame()
166 return getInstance().currentAlignFrame;
169 public static void setCurrentAlignFrame(AlignFrame currentAlignFrame)
171 getInstance().currentAlignFrame = currentAlignFrame;
176 if (!Platform.isJS())
183 // grab all the rights we can for the JVM
184 Policy.setPolicy(new Policy()
187 public PermissionCollection getPermissions(CodeSource codesource)
189 Permissions perms = new Permissions();
190 perms.add(new AllPermission());
195 public void refresh()
203 * keep track of feature fetching tasks.
211 * TODO: generalise to track all jalview events to orchestrate batch
215 private int queued = 0;
217 private int running = 0;
219 public FeatureFetcher()
224 public void addFetcher(final AlignFrame af,
225 final Vector<String> dasSources)
227 final long id = System.currentTimeMillis();
229 final FeatureFetcher us = this;
230 new Thread(new Runnable()
242 af.setProgressBar(MessageManager
243 .getString("status.das_features_being_retrived"), id);
244 af.featureSettings_actionPerformed(null);
245 af.setProgressBar(null, id);
254 public synchronized boolean allFinished()
256 return queued == 0 && running == 0;
262 * main class for Jalview application
265 * open <em>filename</em>
267 public static void main(String[] args)
269 // Platform.startJavaLogging();
270 getInstance().doMain(args);
274 @SuppressWarnings("unused")
278 void doMain(String[] args)
281 boolean isJS = Platform.isJS();
284 Platform.setAppClass(this);
288 System.setSecurityManager(null);
292 .println("Java version: " + System.getProperty("java.version"));
293 System.out.println(System.getProperty("os.arch") + " "
294 + System.getProperty("os.name") + " "
295 + System.getProperty("os.version"));
297 ArgsParser aparser = new ArgsParser(args);
299 String usrPropsFile = aparser.getValue(ArgsParser.PROPS);
300 Cache.loadProperties(usrPropsFile);
303 isJavaAppletTag = aparser.isApplet();
306 Preferences.setAppletDefaults();
307 Cache.loadProperties(usrPropsFile); // again, because we
308 // might be changing defaults here?
311 "<Applet> found: " + aparser.getValue("Info.j2sAppletID"));
312 appletResourcePath = aparser.getValue("Info.resourcePath");
321 if (usrPropsFile != null)
324 "CMD [-props " + usrPropsFile + "] executed successfully!");
327 if (aparser.contains("help") || aparser.contains("h"))
332 if (aparser.contains(ArgsParser.NODISPLAY)
333 || aparser.contains(ArgsParser.NOGUI)
334 || aparser.contains(ArgsParser.HEADLESS)
335 || "true".equals(System.getProperty("java.awt.headless")))
342 final String jabawsUrl = aparser.getValue(ArgsParser.JABAWS);
343 if (jabawsUrl != null)
347 Jws2Discoverer.getInstance().setPreferredUrl(jabawsUrl);
349 "CMD [-jabaws " + jabawsUrl + "] executed successfully!");
350 } catch (MalformedURLException e)
353 "Invalid jabaws parameter: " + jabawsUrl + " ignored");
358 // check for property setting
359 String defs = aparser.getValue(ArgsParser.SETPROP);
362 int p = defs.indexOf('=');
365 System.err.println("Ignoring invalid setprop argument : " + defs);
369 System.out.println("Executing setprop argument: " + defs);
372 Cache.setProperty(defs.substring(0, p), defs.substring(p + 1));
375 defs = aparser.getValue(ArgsParser.SETPROP);
377 System.setProperty("http.agent",
378 "Jalview Desktop/" + Cache.getDefault("VERSION", "Unknown"));
382 } catch (NoClassDefFoundError error)
384 error.printStackTrace();
385 System.out.println("\nEssential logging libraries not found."
386 + "\nUse: java -classpath \"$PATH_TO_LIB$/*:$PATH_TO_CLASSES$\" jalview.bin.Jalview");
394 UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
395 } catch (Exception ex)
397 System.err.println("Unexpected Look and Feel Exception");
398 ex.printStackTrace();
400 if (Platform.isAMacAndNotJS())
403 LookAndFeel lookAndFeel = ch.randelshofer.quaqua.QuaquaManager
405 System.setProperty("com.apple.mrj.application.apple.menu.about.name",
407 System.setProperty("apple.laf.useScreenMenuBar", "true");
408 if (lookAndFeel != null)
412 UIManager.setLookAndFeel(lookAndFeel);
413 } catch (Throwable e)
416 "Failed to set QuaQua look and feel: " + e.toString());
419 if (lookAndFeel == null
420 || !(lookAndFeel.getClass().isAssignableFrom(
421 UIManager.getLookAndFeel().getClass()))
422 || !UIManager.getLookAndFeel().getClass().toString()
423 .toLowerCase().contains("quaqua"))
428 "Quaqua LaF not available on this plaform. Using VAqua(4).\nSee https://issues.jalview.org/browse/JAL-2976");
429 UIManager.setLookAndFeel("org.violetlib.aqua.AquaLookAndFeel");
430 } catch (Throwable e)
433 "Failed to reset look and feel: " + e.toString());
439 * configure 'full' SO model if preferences say to,
440 * else use the default (SO Lite)
442 if (Cache.getDefault(Preferences.USE_FULL_SO, false))
444 SequenceOntologyFactory.setSequenceOntology(new SequenceOntology());
449 desktop = Desktop.getInstance();
450 desktop.setInBatchMode(true); // indicate we are starting up
451 desktop.setVisible(true);
460 desktop.startServiceDiscovery();
461 if (!aparser.contains(ArgsParser.NOUSAGESTATS))
463 startUsageStats(desktop);
467 System.err.println("CMD [-nousagestats] executed successfully!");
470 if (!aparser.contains(ArgsParser.NOQUESTIONNAIRE))
472 String url = aparser.getValue(ArgsParser.QUESTIONNAIRE);
475 // Start the desktop questionnaire prompter with the specified
477 Cache.log.debug("Starting questionnaire url at " + url);
478 desktop.checkForQuestionnaire(url);
479 System.out.println("CMD questionnaire[-" + url
480 + "] executed successfully!");
484 if (Cache.getProperty(Preferences.NOQUESTIONNAIRES) == null)
486 // Start the desktop questionnaire prompter with the specified
489 // "http://anaplog.compbio.dundee.ac.uk/cgi-bin/questionnaire.pl";
491 String defurl = "http://www.jalview.org/cgi-bin/questionnaire.pl";
493 "Starting questionnaire with default url: " + defurl);
494 desktop.checkForQuestionnaire(defurl);
501 .println("CMD [-noquestionnaire] executed successfully!");
504 if (!aparser.contains(ArgsParser.NONEWS))
506 desktop.checkForNews();
509 BioJsHTMLOutput.updateBioJS();
513 parseArguments(aparser, true);
517 * Allow an outside entity to initiate the second half of argument parsing
521 * @return null is good
524 public Object parseArguments(String[] args)
529 ArgsParser aparser = new ArgsParser(args);
530 return parseArguments(aparser, false);
531 } catch (Throwable t)
543 private Object parseArguments(ArgsParser aparser, boolean isStartup)
545 boolean isJS = Platform.isJS();
547 Desktop desktop = (headless ? null : Desktop.getInstance());
548 // script to execute after all loading is
549 // completed one way or another
550 // extract groovy argument and execute if necessary
551 String groovyscript = (isJS ? null
552 : aparser.getValue(ArgsParser.GROOVY, true));
553 String file = aparser.getValue(ArgsParser.OPEN, true);
554 // BH this here to allow split frame; not working as of 5/17/2019
555 String file2 = aparser.getValue(ArgsParser.OPEN2, true);
556 String fileFormat = (isJavaAppletTag
557 ? aparser.getAppletValue("format", null)
559 FileFormatI format = null;
560 DataSourceType protocol = null;
562 if (file == null && desktop == null)
564 System.out.println("No files to open!");
567 boolean haveImport = checkStartVamas(aparser);
568 // Finally, deal with the remaining input data.
570 if (file == null && isJavaAppletTag)
572 // Maybe the sequences are added as parameters
573 StringBuffer data = new StringBuffer("PASTE");
575 while ((file = aparser.getAppletValue("sequence" + i, null)) != null)
577 data.append(file.toString() + "\n");
580 if (data.length() > 5)
582 file = data.toString();
593 desktop.setProgressBar(
595 .getString("status.processing_commandline_args"),
596 progress = System.currentTimeMillis());
601 * ignore in JavaScript -- can't just check file existence - could load
607 if (!file.startsWith("http://") && !file.startsWith("https://"))
608 // BH 2019 added https check for Java
610 if (!(new File(file)).exists())
612 System.out.println("Can't find " + file);
621 protocol = AppletFormatAdapter.checkProtocol(file);
625 format = (isJavaAppletTag && fileFormat != null
626 ? FileFormats.getInstance().forName(fileFormat)
630 format = new IdentifyFile().identify(file, protocol);
632 } catch (FileFormatException e1)
637 if (aparser.contains(ArgsParser.SHOWOVERVIEW))
639 jalview.bin.Cache.setPropertyNoSave(Preferences.SHOW_OVERVIEW,
642 System.out.println("CMD [showoverview] executed successfully!");
645 if (aparser.contains(ArgsParser.NOMENUBAR))
648 System.out.println("CMD [nomenu] executed successfully!");
651 if (aparser.contains(ArgsParser.NOSTATUS))
654 System.out.println("CMD [nostatus] executed successfully!");
657 if (aparser.contains(ArgsParser.NOCALCULATION))
659 noCalculation = true;
660 System.out.println("CMD [nocalculation] executed successfully!");
663 AlignFrame af = new FileLoader(!headless).loadFileWaitTillLoaded(file,
667 System.out.println("error");
672 .println("CMD [-open " + file + "] executed successfully!");
675 protocol = AppletFormatAdapter.checkProtocol(file2);
678 format = new IdentifyFile().identify(file2, protocol);
679 } catch (FileFormatException e1)
683 AlignFrame af2 = new FileLoader(!headless)
684 .loadFileWaitTillLoaded(file2, protocol, format);
687 System.out.println("error");
691 AlignViewport.openLinkedAlignmentAs(af,
692 af.getViewport().getAlignment(),
693 af2.getViewport().getAlignment(), "",
694 AlignViewport.SPLIT_FRAME);
696 "CMD [-open2 " + file2 + "] executed successfully!");
700 setCurrentAlignFrame(af);
702 // TODO: file2 How to implement file2 for the applet spit screen?
704 data = aparser.getValue(ArgsParser.COLOUR, true);
707 data.replaceAll("%20", " ");
709 ColourSchemeI cs = ColourSchemeProperty.getColourScheme(
710 af.getViewport(), af.getViewport().getAlignment(), data);
715 "CMD [-color " + data + "] executed successfully!");
720 // Must maintain ability to use the groups flag
721 data = aparser.getValue(ArgsParser.GROUPS, true);
724 af.parseFeaturesFile(data,
725 AppletFormatAdapter.checkProtocol(data));
726 // System.out.println("Added " + data);
728 "CMD groups[-" + data + "] executed successfully!");
730 data = aparser.getValue(ArgsParser.FEATURES, true);
733 af.parseFeaturesFile(data,
734 AppletFormatAdapter.checkProtocol(data));
735 // System.out.println("Added " + data);
737 "CMD [-features " + data + "] executed successfully!");
740 data = aparser.getValue(ArgsParser.ANNOTATIONS, true);
743 af.loadJalviewDataFile(data, null, null, null);
744 // System.out.println("Added " + data);
746 "CMD [-annotations " + data + "] executed successfully!");
748 // set or clear the sortbytree flag.
749 if (aparser.contains(ArgsParser.SORTBYTREE))
751 af.getViewport().setSortByTree(true);
752 if (af.getViewport().getSortByTree())
754 System.out.println("CMD [-sortbytree] executed successfully!");
758 boolean doUpdateAnnotation = false;
761 if (aparser.contains(ArgsParser.NOANNOTATION)
762 || aparser.contains(ArgsParser.NOANNOTATION2))
764 af.getViewport().setShowAnnotation(false);
765 if (!af.getViewport().isShowAnnotation())
767 doUpdateAnnotation = true;
768 System.out.println("CMD no-annotation executed successfully!");
771 if (aparser.contains(ArgsParser.NOSORTBYTREE))
773 af.getViewport().setSortByTree(false);
774 if (!af.getViewport().getSortByTree())
776 doUpdateAnnotation = true;
778 .println("CMD [-nosortbytree] executed successfully!");
781 if (doUpdateAnnotation)
783 af.setMenusForViewport();
784 af.alignPanel.updateLayout();
786 data = aparser.getValue(ArgsParser.TREE, true);
792 "CMD [-tree " + data + "] executed successfully!");
793 NewickFile nf = new NewickFile(data,
794 AppletFormatAdapter.checkProtocol(data));
796 .setCurrentTree(af.showNewickTree(nf, data).getTree());
797 } catch (IOException ex)
799 System.err.println("Couldn't add tree " + data);
800 ex.printStackTrace(System.err);
803 // TODO - load PDB structure(s) to alignment JAL-629
804 // (associate with identical sequence in alignment, or a specified
808 loadAppletParams(aparser, af);
817 if (groovyscript != null)
819 // Execute the groovy script after we've done all the rendering
821 // and before any images or figures are generated.
822 System.out.println("Executing script " + groovyscript);
823 executeGroovyScript(groovyscript, af);
824 System.out.println("CMD groovy[" + groovyscript
825 + "] executed successfully!");
828 checkOutputFile(aparser, af, format);
829 while (aparser.getSize() > 0)
831 System.out.println("Unknown arg: " + aparser.nextValue());
836 AlignFrame startUpAlframe = null;
837 // We'll only open the default file if the desktop is visible.
839 // ////////////////////
841 if (!isJS && !headless && file == null && !haveImport
842 && jalview.bin.Cache.getDefault("SHOW_STARTUP_FILE", true))
849 file = jalview.bin.Cache.getDefault("STARTUP_FILE",
850 jalview.bin.Cache.getDefault("www.jalview.org",
851 "http://www.jalview.org")
852 + "/examples/exampleFile_2_7.jar");
854 "http://www.jalview.org/examples/exampleFile_2_3.jar"))
856 // hardwire upgrade of the startup file
857 file.replace("_2_3.jar", "_2_7.jar");
858 // and remove the stale setting
859 jalview.bin.Cache.removeProperty("STARTUP_FILE");
862 protocol = DataSourceType.FILE;
864 if (file.indexOf("http:") > -1)
866 protocol = DataSourceType.URL;
869 if (file.endsWith(".jar"))
871 format = FileFormat.Jalview;
877 format = new IdentifyFile().identify(file, protocol);
878 } catch (FileFormatException e)
884 startUpAlframe = new FileLoader(!headless)
885 .loadFileWaitTillLoaded(file, protocol, format);
886 // extract groovy arguments before anything else.
889 // Once all other stuff is done, execute any groovy scripts (in order)
890 if (groovyscript != null)
892 if (Cache.groovyJarsPresent())
894 System.out.println("Executing script " + groovyscript);
895 executeGroovyScript(groovyscript, startUpAlframe);
900 "Sorry. Groovy Support is not available, so ignoring the provided groovy script "
904 // and finally, turn off batch mode indicator - if the desktop still exists
909 desktop.setProgressBar(null, progress);
911 desktop.setInBatchMode(false);
917 private boolean checkStartVamas(ArgsParser aparser)
919 String vamsasImport = aparser.getValue(ArgsParser.VDOC);
920 String vamsasSession = aparser.getValue(ArgsParser.VSESS);
921 if (vamsasImport == null && vamsasSession == null)
925 if (desktop == null || headless)
928 "Headless vamsas sessions not yet supported. Sorry.");
931 boolean haveImport = (vamsasImport != null);
934 // if we have a file, start a new session and import it.
935 boolean inSession = false;
938 DataSourceType viprotocol = AppletFormatAdapter
939 .checkProtocol(vamsasImport);
940 if (viprotocol == DataSourceType.FILE)
942 inSession = desktop.vamsasImport(new File(vamsasImport));
944 else if (viprotocol == DataSourceType.URL)
946 inSession = desktop.vamsasImport(new URL(vamsasImport));
949 } catch (Exception e)
951 System.err.println("Exeption when importing " + vamsasImport
952 + " as a vamsas document.");
957 System.err.println("Failed to import " + vamsasImport
958 + " as a vamsas document.");
962 System.out.println("Imported Successfully into new session "
963 + desktop.getVamsasApplication().getCurrentSession());
966 if (vamsasSession != null)
968 if (vamsasImport != null)
970 // close the newly imported session and import the Jalview specific
971 // remnants into the new session later on.
972 desktop.vamsasStop_actionPerformed(null);
974 // now join the new session
977 if (desktop.joinVamsasSession(vamsasSession))
980 "Successfully joined vamsas session " + vamsasSession);
984 System.err.println("WARNING: Failed to join vamsas session "
987 } catch (Exception e)
990 "ERROR: Failed to join vamsas session " + vamsasSession);
993 if (vamsasImport != null)
995 // the Jalview specific remnants can now be imported into the new
996 // session at the user's leisure.
998 "Skipping Push for import of data into existing vamsas session.");
1004 // desktop.getVamsasApplication().push_update();
1010 private void checkOutputFile(ArgsParser aparser, AlignFrame af,
1013 String imageName = "unnamed.png";
1014 while (aparser.getSize() > 1)
1019 // biojsmsa filename
1020 String outputFormat = aparser.nextValue();
1021 String file = aparser.nextValue();
1022 if (outputFormat.equalsIgnoreCase("png"))
1024 af.createPNG(new File(file));
1025 imageName = (new File(file)).getName();
1026 System.out.println("Creating PNG image: " + file);
1029 else if (outputFormat.equalsIgnoreCase("svg"))
1031 File imageFile = new File(file);
1032 imageName = imageFile.getName();
1033 af.createSVG(imageFile);
1034 System.out.println("Creating SVG image: " + file);
1037 else if (outputFormat.equalsIgnoreCase("html"))
1039 File imageFile = new File(file);
1040 imageName = imageFile.getName();
1041 HtmlSvgOutput htmlSVG = new HtmlSvgOutput(af.alignPanel);
1042 htmlSVG.exportHTML(file);
1044 System.out.println("Creating HTML image: " + file);
1047 else if (outputFormat.equalsIgnoreCase("biojsmsa"))
1051 System.err.println("The output html file must not be null");
1056 BioJsHTMLOutput.refreshVersionInfo(
1057 BioJsHTMLOutput.BJS_TEMPLATES_LOCAL_DIRECTORY);
1058 } catch (URISyntaxException e)
1060 e.printStackTrace();
1062 BioJsHTMLOutput bjs = new BioJsHTMLOutput(af.alignPanel);
1063 bjs.exportHTML(file);
1064 System.out.println("Creating BioJS MSA Viwer HTML file: " + file);
1067 else if (outputFormat.equalsIgnoreCase("imgMap"))
1069 af.createImageMap(new File(file), imageName);
1070 System.out.println("Creating image map: " + file);
1073 else if (outputFormat.equalsIgnoreCase("eps"))
1075 File outputFile = new File(file);
1077 "Creating EPS file: " + outputFile.getAbsolutePath());
1078 af.createEPS(outputFile);
1082 af.saveAlignment(file, format);
1083 if (af.isSaveAlignmentSuccessful())
1086 "Written alignment in " + format + " format to " + file);
1090 System.out.println("Error writing file " + file + " in " + format
1097 private static void showUsage()
1100 "Usage: jalview -open [FILE] [OUTPUT_FORMAT] [OUTPUT_FILE]\n\n"
1101 + "-nodisplay\tRun Jalview without User Interface.\n"
1102 + "-props FILE\tUse the given Jalview properties file instead of users default.\n"
1103 + "-colour COLOURSCHEME\tThe colourscheme to be applied to the alignment\n"
1104 + "-annotations FILE\tAdd precalculated annotations to the alignment.\n"
1105 + "-tree FILE\tLoad the given newick format tree file onto the alignment\n"
1106 + "-features FILE\tUse the given file to mark features on the alignment.\n"
1107 + "-fasta FILE\tCreate alignment file FILE in Fasta format.\n"
1108 + "-clustal FILE\tCreate alignment file FILE in Clustal format.\n"
1109 + "-pfam FILE\tCreate alignment file FILE in PFAM format.\n"
1110 + "-msf FILE\tCreate alignment file FILE in MSF format.\n"
1111 + "-pileup FILE\tCreate alignment file FILE in Pileup format\n"
1112 + "-pir FILE\tCreate alignment file FILE in PIR format.\n"
1113 + "-blc FILE\tCreate alignment file FILE in BLC format.\n"
1114 + "-json FILE\tCreate alignment file FILE in JSON format.\n"
1115 + "-jalview FILE\tCreate alignment file FILE in Jalview format.\n"
1116 + "-png FILE\tCreate PNG image FILE from alignment.\n"
1117 + "-svg FILE\tCreate SVG image FILE from alignment.\n"
1118 + "-html FILE\tCreate HTML file from alignment.\n"
1119 + "-biojsMSA FILE\tCreate BioJS MSA Viewer HTML file from alignment.\n"
1120 + "-imgMap FILE\tCreate HTML file FILE with image map of PNG image.\n"
1121 + "-eps FILE\tCreate EPS file FILE from alignment.\n"
1122 + "-questionnaire URL\tQueries the given URL for information about any Jalview user questionnaires.\n"
1123 + "-noquestionnaire\tTurn off questionnaire check.\n"
1124 + "-nonews\tTurn off check for Jalview news.\n"
1125 + "-nousagestats\tTurn off google analytics tracking for this session.\n"
1126 + "-sortbytree OR -nosortbytree\tEnable or disable sorting of the given alignment by the given tree\n"
1128 // "-setprop PROPERTY=VALUE\tSet the given Jalview property,
1129 // after all other properties files have been read\n\t
1130 // (quote the 'PROPERTY=VALUE' pair to ensure spaces are
1131 // passed in correctly)"
1132 + "-jabaws URL\tSpecify URL for Jabaws services (e.g. for a local installation).\n"
1133 + "-fetchfrom nickname\tQuery nickname for features for the alignments and display them.\n"
1135 // "-vdoc vamsas-document\tImport vamsas document into new
1136 // session or join existing session with same URN\n"
1137 // + "-vses vamsas-session\tJoin session with given URN\n"
1138 + "-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"
1139 + "\n~Read documentation in Application or visit http://www.jalview.org for description of Features and Annotations file~\n\n");
1142 private static void startUsageStats(final Desktop desktop)
1145 * start a User Config prompt asking if we can log usage statistics.
1147 PromptUserConfig prompter = new PromptUserConfig(
1148 Desktop.getDesktopPane(), "USAGESTATS",
1149 "Jalview Usage Statistics",
1150 "Do you want to help make Jalview better by enabling "
1151 + "the collection of usage statistics with Google Analytics ?"
1152 + "\n\n(you can enable or disable usage tracking in the preferences)",
1159 "Initialising googletracker for usage stats.");
1160 Cache.initGoogleTracker();
1161 Cache.log.debug("Tracking enabled.");
1168 Cache.log.debug("Not enabling Google Tracking.");
1171 desktop.addDialogThread(prompter);
1175 * Locate the given string as a file and pass it to the groovy interpreter.
1177 * @param groovyscript
1178 * the script to execute
1179 * @param jalviewContext
1180 * the Jalview Desktop object passed in to the groovy binding as the
1183 private void executeGroovyScript(String groovyscript, AlignFrame af)
1186 * for scripts contained in files
1193 if (groovyscript.trim().equals("STDIN"))
1195 // read from stdin into a tempfile and execute it
1198 tfile = File.createTempFile("jalview", "groovy");
1199 PrintWriter outfile = new PrintWriter(
1200 new OutputStreamWriter(new FileOutputStream(tfile)));
1201 BufferedReader br = new BufferedReader(
1202 new InputStreamReader(System.in));
1204 while ((line = br.readLine()) != null)
1206 outfile.write(line + "\n");
1212 } catch (Exception ex)
1214 System.err.println("Failed to read from STDIN into tempfile "
1215 + ((tfile == null) ? "(tempfile wasn't created)"
1216 : tfile.toString()));
1217 ex.printStackTrace();
1222 sfile = tfile.toURI().toURL();
1223 } catch (Exception x)
1226 "Unexpected Malformed URL Exception for temporary file created from STDIN: "
1228 x.printStackTrace();
1236 sfile = new URI(groovyscript).toURL();
1237 } catch (Exception x)
1239 tfile = new File(groovyscript);
1240 if (!tfile.exists())
1242 System.err.println("File '" + groovyscript + "' does not exist.");
1245 if (!tfile.canRead())
1247 System.err.println("File '" + groovyscript + "' cannot be read.");
1250 if (tfile.length() < 1)
1252 System.err.println("File '" + groovyscript + "' is empty.");
1257 sfile = tfile.getAbsoluteFile().toURI().toURL();
1258 } catch (Exception ex)
1260 System.err.println("Failed to create a file URL for "
1261 + tfile.getAbsoluteFile());
1268 Map<String, Object> vbinding = new HashMap<>();
1269 vbinding.put("Jalview", this);
1272 vbinding.put("currentAlFrame", af);
1274 Binding gbinding = new Binding(vbinding);
1275 GroovyScriptEngine gse = new GroovyScriptEngine(new URL[] { sfile });
1276 gse.run(sfile.toString(), gbinding);
1277 if ("STDIN".equals(groovyscript))
1279 // delete temp file that we made -
1280 // only if it was successfully executed
1283 } catch (Exception e)
1285 System.err.println("Exception Whilst trying to execute file " + sfile
1286 + " as a groovy script.");
1287 e.printStackTrace(System.err);
1292 public AlignFrame[] getAlignFrames()
1294 return desktop == null ? new AlignFrame[] { getCurrentAlignFrame() }
1295 : Desktop.getAlignFrames();
1300 * Quit method delegates to Desktop.quit - unless running in headless mode
1301 * when it just ends the JVM
1305 if (jsFunctionExec != null)
1307 jsFunctionExec.tidyUp();
1308 jsFunctionExec = null;
1311 if (desktop != null)
1322 * Get the SwingJS applet ID and combine that with the frameType
1325 * "alignment", "desktop", etc., or null
1328 public static String getAppID(String frameType)
1330 String id = Cache.getProperty("Info.j2sAppletID");
1335 return id + (frameType == null ? "" : "-" + frameType);
1339 * Handle all JalviewLite applet parameters
1344 private void loadAppletParams(ArgsParser aparser, AlignFrame af)
1346 JalviewApp app = new JalviewApp()
1351 // These are methods that are in JalviewLite that various classes call
1352 // but are not in JalviewLiteJsApi. Or, even if they are, other classes
1354 // them to JalviewLite directly. Some may not be necessary, but they have
1356 // be at least mentioned here, or the classes calling them should
1358 // JalviewLite itself.
1360 private boolean alignPDBStructures; // From JalviewLite; not implemented
1362 private Hashtable<String, Hashtable<String, String[]>> jsmessages;
1364 private Hashtable<String, int[]> jshashes;
1367 public String getParameter(String name)
1369 return aparser.getAppletValue(name, null);
1373 public boolean getDefaultParameter(String name, boolean def)
1376 return ((stn = getParameter(name)) == null ? def
1377 : "true".equalsIgnoreCase(stn));
1381 * Get the applet-like document base even though this is an application.
1384 public URL getDocumentBase()
1386 return Platform.getDocumentBase();
1390 * Get the applet-like code base even though this is an application.
1393 public URL getCodeBase()
1395 return Platform.getCodeBase();
1399 public AlignViewportI getViewport()
1401 return af.getViewport();
1409 public boolean parseFeaturesFile(String filename,
1410 DataSourceType protocol)
1412 return af.parseFeaturesFile(filename, protocol);
1420 public boolean loadScoreFile(String sScoreFile) throws IOException
1422 af.loadJalviewDataFile(sScoreFile, null, null, null);
1427 * annotations, jpredfile, jnetfile
1431 public void updateForAnnotations()
1433 af.updateForAnnotations();
1437 public void loadTree(NewickFile fin, String treeFile)
1440 // n/a -- already done by standard Jalview command line processing
1444 public void setAlignPdbStructures(boolean defaultParameter)
1446 alignPDBStructures = true;
1450 public void newStructureView(PDBEntry pdb, SequenceI[] seqs,
1451 String[] chains, DataSourceType protocol)
1453 StructureViewer.launchStructureViewer(af.alignPanel, pdb, seqs);
1457 public void setFeatureGroupState(String[] groups, boolean state)
1459 af.setFeatureGroupState(groups, state);
1463 public void alignedStructureView(PDBEntry[] pdb, SequenceI[][] seqs,
1464 String[][] chains, String[] protocols)
1467 "Jalview applet interface alignedStructureView not implemented");
1471 public void newFeatureSettings()
1474 "Jalview applet interface newFeatureSettings not implemented");
1477 private Vector<Runnable> jsExecQueue;
1480 public Vector<Runnable> getJsExecQueue(JSFunctionExec exec)
1482 jsFunctionExec = exec;
1483 return (jsExecQueue == null ? (jsExecQueue = new Vector<>())
1488 public AppletContext getAppletContext()
1490 // TODO Auto-generated method stub
1495 public boolean isJsfallbackEnabled()
1497 // TODO Auto-generated method stub
1502 public JSObject getJSObject()
1504 // TODO Auto-generated method stub
1509 public StructureSelectionManagerProvider getStructureSelectionManagerProvider()
1511 // TODO Q: what exactly is this? BH
1516 public void updateColoursFromMouseOver(Object source,
1517 MouseOverStructureListener mouseOverStructureListener)
1519 // TODO Auto-generated method stub
1524 public Object[] getSelectionForListener(SequenceGroup seqsel,
1525 ColumnSelection colsel, HiddenColumns hidden,
1526 SelectionSource source, Object alignFrame)
1528 return appLoader.getSelectionForListener(getCurrentAlignFrame(),
1529 seqsel, colsel, hidden, source, alignFrame);
1533 public String arrayToSeparatorList(String[] array)
1535 return appLoader.arrayToSeparatorList(array);
1539 public Hashtable<String, int[]> getJSHashes()
1541 return (jshashes == null ? (jshashes = new Hashtable<>())
1546 public Hashtable<String, Hashtable<String, String[]>> getJSMessages()
1548 return (jsmessages == null ? (jsmessages = new Hashtable<>())
1553 public Object getFrameForSource(VamsasSource source)
1558 if (source instanceof jalview.gui.AlignViewport
1559 && source == (af = getCurrentAlignFrame()).getViewport())
1561 // should be valid if it just generated an event!
1564 // TODO: ensure that if '_af' is specified along with a handler
1565 // function, then only events from that alignFrame are sent to that
1572 public FeatureRenderer getNewFeatureRenderer(AlignViewportI vp)
1574 return new jalview.gui.FeatureRenderer((AlignmentPanel) vp);
1579 appLoader = new JalviewAppLoader(true);
1580 appLoader.load(app);
1585 * @see jalview.bin.JalviewLiteJsApi#getSelectedSequences()
1588 public String getSelectedSequences()
1590 return getSelectedSequencesFrom(getCurrentAlignFrame());
1595 * @see jalview.bin.JalviewLiteJsApi#getSelectedSequences(java.lang.String)
1598 public String getSelectedSequences(String sep)
1600 return getSelectedSequencesFrom(getCurrentAlignFrame(), sep);
1605 * @see jalview.bin.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
1609 public String getSelectedSequencesFrom(AlignFrameI alf)
1611 return getSelectedSequencesFrom(alf, null);
1616 * @see jalview.bin.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
1617 * .AlignFrame, java.lang.String)
1620 public String getSelectedSequencesFrom(AlignFrameI alf, String sep)
1622 return appLoader.getSelectedSequencesFrom(alf, sep);
1627 * @see jalview.bin.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
1628 * .AlignFrame, java.lang.String)
1631 public void highlight(String sequenceId, String position,
1632 String alignedPosition)
1634 highlightIn(getCurrentAlignFrame(), sequenceId, position,
1639 public void highlightIn(AlignFrameI alf, String sequenceId,
1640 String position, String alignedPosition)
1642 appLoader.highlightIn(alf, sequenceId, position, alignedPosition);
1646 public void select(String sequenceIds, String columns)
1648 selectIn(getCurrentAlignFrame(), sequenceIds, columns, null);
1652 public void select(String sequenceIds, String columns, String sep)
1654 selectIn(getCurrentAlignFrame(), sequenceIds, columns, sep);
1658 public void selectIn(AlignFrameI alf, String sequenceIds, String columns)
1660 selectIn(alf, sequenceIds, columns, null);
1664 public void selectIn(AlignFrameI alf, String sequenceIds, String columns,
1667 appLoader.selectIn(alf, sequenceIds, columns, sep);
1671 public String getSelectedSequencesAsAlignment(String format,
1674 return getSelectedSequencesAsAlignmentFrom(getCurrentAlignFrame(),
1679 public String getSelectedSequencesAsAlignmentFrom(AlignFrameI alf,
1680 String format, String sep)
1682 return appLoader.getSelectedSequencesAsAlignmentFrom(alf, format, sep);
1686 public String getAlignmentOrder()
1688 return getAlignmentFrom(getCurrentAlignFrame(), null);
1692 public String getAlignmentOrderFrom(AlignFrameI alf)
1694 return getAlignmentFrom(alf, null);
1698 public String getAlignmentOrderFrom(AlignFrameI alf, String sep)
1700 return appLoader.getAlignmentOrderFrom(alf, sep);
1704 public String orderBy(String order, String undoName)
1706 return orderBy(order, undoName, null);
1710 public String orderBy(String order, String undoName, String sep)
1712 return orderAlignmentBy(getCurrentAlignFrame(), order, undoName, sep);
1716 public String orderAlignmentBy(AlignFrameI alf, String order,
1717 String undoName, String sep)
1719 return appLoader.orderAlignmentBy(alf, order, undoName, sep);
1723 public String getAlignment(String format)
1725 return getAlignmentFrom(null, format, null);
1729 public String getAlignmentFrom(AlignFrameI alf, String format)
1731 return getAlignmentFrom(alf, format, null);
1735 public String getAlignment(String format, String suffix)
1737 return getAlignmentFrom(getCurrentAlignFrame(), format, suffix);
1741 public String getAlignmentFrom(AlignFrameI alf, String format,
1744 return appLoader.getAlignmentFrom(alf, format, suffix);
1748 public void loadAnnotation(String annotation)
1750 loadAnnotationFrom(getCurrentAlignFrame(), annotation);
1754 public void loadAnnotationFrom(AlignFrameI alf, String annotation)
1756 appLoader.loadAnnotationFrom(alf, annotation);
1760 public void loadFeatures(String features, boolean autoenabledisplay)
1762 loadFeaturesFrom(currentAlignFrame, features, autoenabledisplay);
1766 public boolean loadFeaturesFrom(AlignFrameI alf, String features,
1767 boolean autoenabledisplay)
1769 return appLoader.loadFeaturesFrom(alf, features, autoenabledisplay);
1773 public String getFeatures(String format)
1775 return getFeaturesFrom(getCurrentAlignFrame(), format);
1779 public String getFeaturesFrom(AlignFrameI alf, String format)
1781 return appLoader.getFeaturesFrom(alf, format);
1785 public String getAnnotation()
1787 return getAnnotationFrom(getCurrentAlignFrame());
1791 public String getAnnotationFrom(AlignFrameI alf)
1793 return appLoader.getAnnotationFrom(alf);
1797 public AlignFrameI newView()
1799 return newViewFrom(getCurrentAlignFrame(), null);
1803 public AlignFrameI newView(String name)
1805 return newViewFrom(getCurrentAlignFrame(), name);
1809 public AlignFrameI newViewFrom(AlignFrameI alf)
1811 return newViewFrom(alf, null);
1815 public AlignFrameI newViewFrom(AlignFrameI alf, String name)
1817 return appLoader.newViewFrom(alf, name);
1821 public AlignFrameI loadAlignment(String text, String title)
1823 return appLoader.loadAlignment(text, AlignFrame.DEFAULT_WIDTH,
1824 AlignFrame.DEFAULT_HEIGHT, title);
1828 public boolean addPdbFile(AlignFrameI alFrame, String sequenceId,
1829 String pdbEntryString, String pdbFile)
1831 return appLoader.addPdbFile(alFrame, sequenceId, pdbEntryString,
1836 public void scrollViewToIn(AlignFrameI alf, String topRow,
1837 String leftHandColumn)
1839 appLoader.scrollViewToIn(alf, topRow, leftHandColumn);
1843 public void scrollViewToRowIn(AlignFrameI alf, String topRow)
1845 appLoader.scrollViewToRowIn(alf, topRow);
1849 public void scrollViewToColumnIn(AlignFrameI alf, String leftHandColumn)
1851 appLoader.scrollViewToColumnIn(alf, leftHandColumn);
1855 public String getFeatureGroups()
1857 return getFeatureGroupsOn(getCurrentAlignFrame());
1861 public String getFeatureGroupsOn(AlignFrameI alf)
1863 return appLoader.getFeatureGroupsOn(alf);
1867 public String getFeatureGroupsOfState(boolean visible)
1869 return getFeatureGroupsOfStateOn(getCurrentAlignFrame(), visible);
1873 public String getFeatureGroupsOfStateOn(AlignFrameI alf, boolean visible)
1875 return appLoader.getFeatureGroupsOfStateOn(alf, visible);
1879 public void setFeatureGroupStateOn(AlignFrameI alf, String groups,
1882 setFeatureGroupStateOn(alf, groups, state);
1886 public void setFeatureGroupState(String groups, boolean state)
1888 appLoader.setFeatureGroupStateOn(getCurrentAlignFrame(), groups, state);
1892 public String getSeparator()
1894 return appLoader.getSeparator();
1898 public void setSeparator(String separator)
1900 appLoader.setSeparator(separator);
1904 public String getJsMessage(String messageclass, String viewId)
1906 // see http://www.jalview.org/examples/jalviewLiteJs.html
1911 * Open a new Tree panel on the desktop statically. Params are standard (not
1912 * set by Groovy). No dialog is opened.
1917 * @return null, or the string "label.you_need_at_least_n_sequences" if number
1918 * of sequences selected is inappropriate
1921 public Object openTreePanel(AlignFrame af, String treeType,
1924 return CalculationChooser.openTreePanel(af, treeType, modelName, null);
1928 * public static method for JalviewJS API to open a PCAPanel without
1929 * necessarily using a dialog.
1933 * @return the PCAPanel, or the string "label.you_need_at_least_n_sequences"
1934 * if number of sequences selected is inappropriate
1937 public Object openPcaPanel(AlignFrame af, String modelName)
1939 return CalculationChooser.openPcaPanel(af, modelName, null);
1943 public String getSelectedSequencesAsAlignment(String format,
1946 return getSelectedSequencesAsAlignmentFrom(getCurrentAlignFrame(),
1951 public String getSelectedSequencesAsAlignmentFrom(AlignFrameI alf,
1952 String format, boolean suffix)
1954 return appLoader.getSelectedSequencesAsAlignmentFrom(alf, format,
1959 public String arrayToSeparatorList(String[] array)
1961 return appLoader.arrayToSeparatorList(array);
1965 public String[] separatorListToArray(String list)
1967 return appLoader.separatorListToArray(list);
1970 //// probably not needed in JalviewJS -- From when Jmol and Jalview did not
1971 //// have a direct connection?
1974 public void setMouseoverListener(String listener)
1976 // TODO Auto-generated method stub
1981 public void setMouseoverListener(AlignFrameI af, String listener)
1983 // TODO Auto-generated method stub
1988 public void setSelectionListener(String listener)
1990 // TODO Auto-generated method stub
1995 public void setSelectionListener(AlignFrameI af, String listener)
1997 // TODO Auto-generated method stub
2002 public void setStructureListener(String listener, String modelSet)
2004 // TODO Auto-generated method stub
2009 public void removeJavascriptListener(AlignFrameI af, String listener)
2011 // TODO Auto-generated method stub
2016 public void mouseOverStructure(String pdbResNum, String chain,
2019 // TODO Auto-generated method stub