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.AlignCalcWorkerI;
24 import jalview.api.AlignFrameI;
25 import jalview.api.AlignViewportI;
26 import jalview.api.JalviewApp;
27 import jalview.api.StructureSelectionManagerProvider;
28 import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
29 import jalview.datamodel.ColumnSelection;
30 import jalview.datamodel.HiddenColumns;
31 import jalview.datamodel.PDBEntry;
32 import jalview.datamodel.SequenceGroup;
33 import jalview.datamodel.SequenceI;
34 import jalview.ext.so.SequenceOntology;
35 import jalview.gui.AlignFrame;
36 import jalview.gui.AlignViewport;
37 import jalview.gui.AlignmentPanel;
38 import jalview.gui.CalculationChooser;
39 import jalview.gui.Desktop;
40 import jalview.gui.Preferences;
41 import jalview.gui.PromptUserConfig;
42 import jalview.gui.StructureViewer;
43 import jalview.io.AppletFormatAdapter;
44 import jalview.io.BioJsHTMLOutput;
45 import jalview.io.DataSourceType;
46 import jalview.io.FileFormat;
47 import jalview.io.FileFormatException;
48 import jalview.io.FileFormatI;
49 import jalview.io.FileFormats;
50 import jalview.io.FileLoader;
51 import jalview.io.HtmlSvgOutput;
52 import jalview.io.IdentifyFile;
53 import jalview.io.NewickFile;
54 import jalview.io.gff.SequenceOntologyFactory;
55 import jalview.javascript.JSFunctionExec;
56 import jalview.javascript.MouseOverStructureListener;
57 import jalview.renderer.seqfeatures.FeatureRenderer;
58 import jalview.schemes.ColourSchemeI;
59 import jalview.schemes.ColourSchemeProperty;
60 import jalview.structure.SelectionSource;
61 import jalview.structure.VamsasSource;
62 import jalview.util.MessageManager;
63 import jalview.util.Platform;
64 import jalview.ws.jws2.Jws2Discoverer;
66 import java.applet.AppletContext;
67 import java.io.BufferedReader;
69 import java.io.FileOutputStream;
70 import java.io.IOException;
71 import java.io.InputStreamReader;
72 import java.io.OutputStreamWriter;
73 import java.io.PrintWriter;
74 import java.net.MalformedURLException;
76 import java.net.URISyntaxException;
78 import java.security.AllPermission;
79 import java.security.CodeSource;
80 import java.security.PermissionCollection;
81 import java.security.Permissions;
82 import java.security.Policy;
83 import java.util.HashMap;
84 import java.util.Hashtable;
86 import java.util.Vector;
88 import javax.swing.LookAndFeel;
89 import javax.swing.UIManager;
91 import groovy.lang.Binding;
92 import groovy.util.GroovyScriptEngine;
93 import netscape.javascript.JSObject;
96 * Main class for Jalview Application <br>
98 * start with: java -classpath "$PATH_TO_LIB$/*:$PATH_TO_CLASSES$" \
101 * or on Windows: java -classpath "$PATH_TO_LIB$/*;$PATH_TO_CLASSES$" \
102 * jalview.bin.Jalview jalview.bin.Jalview
104 * (ensure -classpath arg is quoted to avoid shell expansion of '*' and do not
105 * embellish '*' to e.g. '*.jar')
108 * @version $Revision$
110 public class Jalview implements ApplicationSingletonI, JalviewJSApi
113 public static Jalview getInstance()
115 return (Jalview) ApplicationSingletonProvider
116 .getInstance(Jalview.class);
125 Platform.getURLCommandArguments();
128 private boolean headless;
130 public static boolean isHeadlessMode()
132 return getInstance().headless;
135 private Desktop desktop;
137 private AlignFrame currentAlignFrame;
139 public boolean isJavaAppletTag;
141 public String appletResourcePath;
143 JalviewAppLoader appLoader;
145 protected JSFunctionExec jsFunctionExec;
147 private boolean noCalculation, noMenuBar, noStatus;
149 private boolean noAnnotation;
151 public boolean getStartCalculations()
153 return !noCalculation;
156 public boolean getAllowMenuBar()
161 public boolean getShowStatus()
166 public boolean getShowAnnotation()
168 return !noAnnotation;
171 public static AlignFrame getCurrentAlignFrame()
173 return getInstance().currentAlignFrame;
176 public static void setCurrentAlignFrame(AlignFrame currentAlignFrame)
178 getInstance().currentAlignFrame = currentAlignFrame;
183 if (!Platform.isJS())
190 // grab all the rights we can for the JVM
191 Policy.setPolicy(new Policy()
194 public PermissionCollection getPermissions(CodeSource codesource)
196 Permissions perms = new Permissions();
197 perms.add(new AllPermission());
202 public void refresh()
210 * keep track of feature fetching tasks.
218 * TODO: generalise to track all jalview events to orchestrate batch
222 private int queued = 0;
224 private int running = 0;
226 public FeatureFetcher()
231 public void addFetcher(final AlignFrame af,
232 final Vector<String> dasSources)
234 final long id = System.currentTimeMillis();
236 final FeatureFetcher us = this;
237 new Thread(new Runnable()
249 af.setProgressBar(MessageManager
250 .getString("status.das_features_being_retrived"), id);
251 af.featureSettings_actionPerformed(null);
252 af.setProgressBar(null, id);
261 public synchronized boolean allFinished()
263 return queued == 0 && running == 0;
269 * main class for Jalview application
272 * open <em>filename</em>
274 public static void main(String[] args)
276 // Platform.startJavaLogging();
277 getInstance().doMain(args);
281 @SuppressWarnings("unused")
285 void doMain(String[] args)
288 boolean isJS = Platform.isJS();
291 Platform.setAppClass(this);
295 // BH 2019.08.26 cannot pass null
296 System.setSecurityManager(null);
300 .println("Java version: " + System.getProperty("java.version"));
301 System.out.println(System.getProperty("os.arch") + " "
302 + System.getProperty("os.name") + " "
303 + System.getProperty("os.version"));
305 ArgsParser aparser = new ArgsParser(args);
307 String usrPropsFile = aparser.getValue(ArgsParser.PROPS);
308 Cache.loadProperties(usrPropsFile);
311 isJavaAppletTag = aparser.isApplet();
314 Preferences.setAppletDefaults();
315 Cache.loadProperties(usrPropsFile); // again, because we
316 // might be changing defaults here?
319 "<Applet> found: " + aparser.getValue("Info.j2sAppletID"));
320 appletResourcePath = aparser.getValue("Info.resourcePath");
329 if (usrPropsFile != null)
332 "CMD [-props " + usrPropsFile + "] executed successfully!");
335 if (aparser.contains("help") || aparser.contains("h"))
340 if (aparser.contains(ArgsParser.NODISPLAY)
341 || aparser.contains(ArgsParser.NOGUI)
342 || aparser.contains(ArgsParser.HEADLESS)
343 || "true".equals(System.getProperty("java.awt.headless")))
347 System.out.println("Headless operation detected.");
353 final String jabawsUrl = aparser.getValue(ArgsParser.JABAWS);
354 if (jabawsUrl != null)
358 Jws2Discoverer.getInstance().setPreferredUrl(jabawsUrl);
360 "CMD [-jabaws " + jabawsUrl + "] executed successfully!");
361 } catch (MalformedURLException e)
364 "Invalid jabaws parameter: " + jabawsUrl + " ignored");
369 // check for property setting
370 String defs = aparser.getValue(ArgsParser.SETPROP);
373 int p = defs.indexOf('=');
376 System.err.println("Ignoring invalid setprop argument : " + defs);
380 System.out.println("Executing setprop argument: " + defs);
383 Cache.setProperty(defs.substring(0, p), defs.substring(p + 1));
386 defs = aparser.getValue(ArgsParser.SETPROP);
388 System.setProperty("http.agent",
389 "Jalview Desktop/" + Cache.getDefault("VERSION", "Unknown"));
393 } catch (NoClassDefFoundError error)
395 error.printStackTrace();
396 System.out.println("\nEssential logging libraries not found."
397 + "\nUse: java -classpath \"$PATH_TO_LIB$/*:$PATH_TO_CLASSES$\" jalview.bin.Jalview");
405 UIManager.setLookAndFeel(
406 headless ? "javax.swing.plaf.metal.MetalLookAndFeel"
407 : UIManager.getSystemLookAndFeelClassName());
408 } catch (Exception ex)
410 System.err.println("Unexpected Look and Feel Exception");
411 ex.printStackTrace();
413 if (Platform.isAMacAndNotJS())
416 LookAndFeel lookAndFeel = ch.randelshofer.quaqua.QuaquaManager
418 System.setProperty("com.apple.mrj.application.apple.menu.about.name",
420 System.setProperty("apple.laf.useScreenMenuBar", "true");
421 if (lookAndFeel != null)
425 UIManager.setLookAndFeel(lookAndFeel);
426 } catch (Throwable e)
429 "Failed to set QuaQua look and feel: " + e.toString());
432 if (lookAndFeel == null
433 || !(lookAndFeel.getClass().isAssignableFrom(
434 UIManager.getLookAndFeel().getClass()))
435 || !UIManager.getLookAndFeel().getClass().toString()
436 .toLowerCase().contains("quaqua"))
441 "Quaqua LaF not available on this plaform. Using VAqua(4).\nSee https://issues.jalview.org/browse/JAL-2976");
442 UIManager.setLookAndFeel("org.violetlib.aqua.AquaLookAndFeel");
443 } catch (Throwable e)
446 "Failed to reset look and feel: " + e.toString());
452 * configure 'full' SO model if preferences say to,
453 * else use the default (SO Lite)
455 if (Cache.getDefault(Preferences.USE_FULL_SO, false))
457 SequenceOntologyFactory.setSequenceOntology(new SequenceOntology());
462 desktop = Desktop.getInstance();
463 desktop.setInBatchMode(true); // indicate we are starting up
464 desktop.setVisible(true);
473 desktop.startServiceDiscovery();
474 if (!aparser.contains(ArgsParser.NOUSAGESTATS))
476 startUsageStats(desktop);
480 System.err.println("CMD [-nousagestats] executed successfully!");
483 if (!aparser.contains(ArgsParser.NOQUESTIONNAIRE))
485 String url = aparser.getValue(ArgsParser.QUESTIONNAIRE);
488 // Start the desktop questionnaire prompter with the specified
490 Cache.log.debug("Starting questionnaire url at " + url);
491 desktop.checkForQuestionnaire(url);
492 System.out.println("CMD questionnaire[-" + url
493 + "] executed successfully!");
497 if (Cache.getProperty(Preferences.NOQUESTIONNAIRES) == null)
499 // Start the desktop questionnaire prompter with the specified
502 // "http://anaplog.compbio.dundee.ac.uk/cgi-bin/questionnaire.pl";
504 String defurl = "http://www.jalview.org/cgi-bin/questionnaire.pl";
506 "Starting questionnaire with default url: " + defurl);
507 desktop.checkForQuestionnaire(defurl);
514 .println("CMD [-noquestionnaire] executed successfully!");
517 if (!aparser.contains(ArgsParser.NONEWS))
519 desktop.checkForNews();
522 BioJsHTMLOutput.updateBioJS();
526 parseArguments(aparser, true);
530 * Allow an outside entity to initiate the second half of argument parsing
534 * @return null is good
537 public Object parseArguments(String[] args)
542 ArgsParser aparser = new ArgsParser(args);
543 return parseArguments(aparser, false);
544 } catch (Throwable t)
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)
572 FileFormatI format = null;
573 DataSourceType protocol = null;
575 if (file == null && desktop == null)
577 System.out.println("No files to open!");
580 boolean haveImport = checkStartVamas(aparser);
581 // Finally, deal with the remaining input data.
583 if (file == null && isJavaAppletTag)
585 // Maybe the sequences are added as parameters
586 StringBuffer data = new StringBuffer("PASTE");
588 while ((file = aparser.getAppletValue("sequence" + i, null)) != null)
590 data.append(file.toString() + "\n");
593 if (data.length() > 5)
595 file = data.toString();
606 desktop.setProgressBar(
608 .getString("status.processing_commandline_args"),
609 progress = System.currentTimeMillis());
614 * ignore in JavaScript -- can't just check file existence - could load
620 if (!file.startsWith("http://") && !file.startsWith("https://"))
621 // BH 2019 added https check for Java
623 if (!(new File(file)).exists())
626 "Can't find " + new File(file).getAbsolutePath());
635 protocol = AppletFormatAdapter.checkProtocol(file);
639 format = (isJavaAppletTag && fileFormat != null
640 ? FileFormats.getInstance().forName(fileFormat)
644 format = new IdentifyFile().identify(file, protocol);
646 } catch (FileFormatException e1)
651 if (aparser.contains(ArgsParser.NOMENUBAR))
654 System.out.println("CMD [nomenu] executed successfully!");
657 if (aparser.contains(ArgsParser.NOSTATUS))
660 System.out.println("CMD [nostatus] executed successfully!");
663 if (aparser.contains(ArgsParser.NOANNOTATION)
664 || aparser.contains(ArgsParser.NOANNOTATION2))
667 System.out.println("CMD no-annotation executed successfully!");
669 if (aparser.contains(ArgsParser.NOCALCULATION))
671 noCalculation = true;
672 System.out.println("CMD [nocalculation] executed successfully!");
675 AlignFrame af = new FileLoader(!headless).loadFileWaitTillLoaded(file,
679 System.out.println("error");
684 .println("CMD [-open " + file + "] executed successfully!");
687 protocol = AppletFormatAdapter.checkProtocol(file2);
690 format = new IdentifyFile().identify(file2, protocol);
691 } catch (FileFormatException e1)
695 AlignFrame af2 = new FileLoader(!headless)
696 .loadFileWaitTillLoaded(file2, protocol, format);
699 System.out.println("error");
703 AlignViewport.openLinkedAlignmentAs(af,
704 af.getViewport().getAlignment(),
705 af2.getViewport().getAlignment(), "",
706 AlignViewport.SPLIT_FRAME);
708 "CMD [-open2 " + file2 + "] executed successfully!");
712 setCurrentAlignFrame(af);
714 // TODO: file2 How to implement file2 for the applet spit screen?
716 data = aparser.getValue(ArgsParser.COLOUR, true);
719 data.replaceAll("%20", " ");
721 ColourSchemeI cs = ColourSchemeProperty.getColourScheme(
722 af.getViewport(), af.getViewport().getAlignment(), data);
727 "CMD [-color " + data + "] executed successfully!");
732 // Must maintain ability to use the groups flag
733 data = aparser.getValue(ArgsParser.GROUPS, true);
736 af.parseFeaturesFile(data,
737 AppletFormatAdapter.checkProtocol(data));
738 // System.out.println("Added " + data);
740 "CMD groups[-" + data + "] executed successfully!");
742 data = aparser.getValue(ArgsParser.FEATURES, true);
745 af.parseFeaturesFile(data,
746 AppletFormatAdapter.checkProtocol(data));
747 // System.out.println("Added " + data);
749 "CMD [-features " + data + "] executed successfully!");
752 data = aparser.getValue(ArgsParser.ANNOTATIONS, true);
755 af.loadJalviewDataFile(data, null, null, null);
756 // System.out.println("Added " + data);
758 "CMD [-annotations " + data + "] executed successfully!");
761 if (aparser.contains(ArgsParser.SHOWOVERVIEW))
765 af.overviewMenuItem_actionPerformed(null);
767 System.out.println("CMD [showoverview] executed successfully!");
770 // set or clear the sortbytree flag.
771 if (aparser.contains(ArgsParser.SORTBYTREE))
773 af.getViewport().setSortByTree(true);
774 if (af.getViewport().getSortByTree())
776 System.out.println("CMD [-sortbytree] executed successfully!");
780 boolean doUpdateAnnotation = false;
783 * we do this earlier in JalviewJS because of a complication with
786 * For now, just fixing this in JalviewJS.
793 if (aparser.contains(ArgsParser.NOANNOTATION)
794 || aparser.contains(ArgsParser.NOANNOTATION2))
796 af.getViewport().setShowAnnotation(false);
797 if (!af.getViewport().isShowAnnotation())
799 doUpdateAnnotation = true;
801 .println("CMD no-annotation executed successfully!");
805 if (aparser.contains(ArgsParser.NOSORTBYTREE))
807 af.getViewport().setSortByTree(false);
808 if (!af.getViewport().getSortByTree())
810 doUpdateAnnotation = true;
812 .println("CMD [-nosortbytree] executed successfully!");
815 if (doUpdateAnnotation)
817 af.setMenusForViewport();
818 af.alignPanel.updateLayout();
820 data = aparser.getValue(ArgsParser.TREE, true);
826 "CMD [-tree " + data + "] executed successfully!");
827 NewickFile nf = new NewickFile(data,
828 AppletFormatAdapter.checkProtocol(data));
830 .setCurrentTree(af.showNewickTree(nf, data).getTree());
831 } catch (IOException ex)
833 System.err.println("Couldn't add tree " + data);
834 ex.printStackTrace(System.err);
837 // TODO - load PDB structure(s) to alignment JAL-629
838 // (associate with identical sequence in alignment, or a specified
842 loadAppletParams(aparser, af);
851 if (groovyscript != null)
853 // Execute the groovy script after we've done all the rendering
855 // and before any images or figures are generated.
856 System.out.println("Executing script " + groovyscript);
857 executeGroovyScript(groovyscript, af);
858 System.out.println("CMD groovy[" + groovyscript
859 + "] executed successfully!");
862 checkOutputFile(aparser, af, format);
863 while (aparser.getSize() > 0)
865 System.out.println("Unknown arg: " + aparser.nextValue());
870 AlignFrame startUpAlframe = null;
871 // We'll only open the default file if the desktop is visible.
873 // ////////////////////
875 if (!isJS && !headless && file == null && !haveImport
876 && jalview.bin.Cache.getDefault("SHOW_STARTUP_FILE", true))
883 file = jalview.bin.Cache.getDefault("STARTUP_FILE",
884 jalview.bin.Cache.getDefault("www.jalview.org",
885 "http://www.jalview.org")
886 + "/examples/exampleFile_2_7.jar");
888 "http://www.jalview.org/examples/exampleFile_2_3.jar"))
890 // hardwire upgrade of the startup file
891 file.replace("_2_3.jar", "_2_7.jar");
892 // and remove the stale setting
893 jalview.bin.Cache.removeProperty("STARTUP_FILE");
896 protocol = DataSourceType.FILE;
898 if (file.indexOf("http:") > -1)
900 protocol = DataSourceType.URL;
903 if (file.endsWith(".jar"))
905 format = FileFormat.Jalview;
911 format = new IdentifyFile().identify(file, protocol);
912 } catch (FileFormatException e)
918 startUpAlframe = new FileLoader(!headless)
919 .loadFileWaitTillLoaded(file, protocol, format);
920 // extract groovy arguments before anything else.
923 // Once all other stuff is done, execute any groovy scripts (in order)
924 if (groovyscript != null)
926 if (Cache.groovyJarsPresent())
928 System.out.println("Executing script " + groovyscript);
929 executeGroovyScript(groovyscript, startUpAlframe);
934 "Sorry. Groovy Support is not available, so ignoring the provided groovy script "
938 // and finally, turn off batch mode indicator - if the desktop still exists
943 desktop.setProgressBar(null, progress);
945 desktop.setInBatchMode(false);
951 private boolean checkStartVamas(ArgsParser aparser)
953 String vamsasImport = aparser.getValue(ArgsParser.VDOC);
954 String vamsasSession = aparser.getValue(ArgsParser.VSESS);
955 if (vamsasImport == null && vamsasSession == null)
959 if (desktop == null || headless)
962 "Headless vamsas sessions not yet supported. Sorry.");
965 boolean haveImport = (vamsasImport != null);
968 // if we have a file, start a new session and import it.
969 boolean inSession = false;
972 DataSourceType viprotocol = AppletFormatAdapter
973 .checkProtocol(vamsasImport);
974 if (viprotocol == DataSourceType.FILE)
976 inSession = desktop.vamsasImport(new File(vamsasImport));
978 else if (viprotocol == DataSourceType.URL)
980 inSession = desktop.vamsasImport(new URL(vamsasImport));
983 } catch (Exception e)
985 System.err.println("Exeption when importing " + vamsasImport
986 + " as a vamsas document.");
991 System.err.println("Failed to import " + vamsasImport
992 + " as a vamsas document.");
996 System.out.println("Imported Successfully into new session "
997 + desktop.getVamsasApplication().getCurrentSession());
1000 if (vamsasSession != null)
1002 if (vamsasImport != null)
1004 // close the newly imported session and import the Jalview specific
1005 // remnants into the new session later on.
1006 desktop.vamsasStop_actionPerformed(null);
1008 // now join the new session
1011 if (desktop.joinVamsasSession(vamsasSession))
1014 "Successfully joined vamsas session " + vamsasSession);
1018 System.err.println("WARNING: Failed to join vamsas session "
1021 } catch (Exception e)
1024 "ERROR: Failed to join vamsas session " + vamsasSession);
1025 e.printStackTrace();
1027 if (vamsasImport != null)
1029 // the Jalview specific remnants can now be imported into the new
1030 // session at the user's leisure.
1032 "Skipping Push for import of data into existing vamsas session.");
1038 // desktop.getVamsasApplication().push_update();
1044 private void checkOutputFile(ArgsParser aparser, AlignFrame af,
1047 String imageName = "unnamed.png";
1048 while (aparser.getSize() > 1)
1053 // biojsmsa filename
1054 String outputFormat = aparser.nextValue();
1055 String file = aparser.nextValue();
1056 if (outputFormat.equalsIgnoreCase("png"))
1058 af.createPNG(new File(file));
1059 imageName = (new File(file)).getName();
1060 System.out.println("Creating PNG image: " + file);
1063 else if (outputFormat.equalsIgnoreCase("svg"))
1065 File imageFile = new File(file);
1066 imageName = imageFile.getName();
1067 af.createSVG(imageFile);
1068 System.out.println("Creating SVG image: " + file);
1071 else if (outputFormat.equalsIgnoreCase("html"))
1073 File imageFile = new File(file);
1074 imageName = imageFile.getName();
1075 HtmlSvgOutput htmlSVG = new HtmlSvgOutput(af.alignPanel);
1076 htmlSVG.exportHTML(file);
1078 System.out.println("Creating HTML image: " + file);
1081 else if (outputFormat.equalsIgnoreCase("biojsmsa"))
1085 System.err.println("The output html file must not be null");
1090 BioJsHTMLOutput.refreshVersionInfo(
1091 BioJsHTMLOutput.BJS_TEMPLATES_LOCAL_DIRECTORY);
1092 } catch (URISyntaxException e)
1094 e.printStackTrace();
1096 BioJsHTMLOutput bjs = new BioJsHTMLOutput(af.alignPanel);
1097 bjs.exportHTML(file);
1098 System.out.println("Creating BioJS MSA Viwer HTML file: " + file);
1101 else if (outputFormat.equalsIgnoreCase("imgMap"))
1103 af.createImageMap(new File(file), imageName);
1104 System.out.println("Creating image map: " + file);
1107 else if (outputFormat.equalsIgnoreCase("eps"))
1109 File outputFile = new File(file);
1111 "Creating EPS file: " + outputFile.getAbsolutePath());
1112 af.createEPS(outputFile);
1116 af.saveAlignment(file, format);
1117 if (af.isSaveAlignmentSuccessful())
1120 "Written alignment in " + format + " format to " + file);
1124 System.out.println("Error writing file " + file + " in " + format
1131 private static void showUsage()
1134 "Usage: jalview -open [FILE] [OUTPUT_FORMAT] [OUTPUT_FILE]\n\n"
1135 + "-nodisplay\tRun Jalview without User Interface.\n"
1136 + "-props FILE\tUse the given Jalview properties file instead of users default.\n"
1137 + "-colour COLOURSCHEME\tThe colourscheme to be applied to the alignment\n"
1138 + "-annotations FILE\tAdd precalculated annotations to the alignment.\n"
1139 + "-tree FILE\tLoad the given newick format tree file onto the alignment\n"
1140 + "-features FILE\tUse the given file to mark features on the alignment.\n"
1141 + "-fasta FILE\tCreate alignment file FILE in Fasta format.\n"
1142 + "-clustal FILE\tCreate alignment file FILE in Clustal format.\n"
1143 + "-pfam FILE\tCreate alignment file FILE in PFAM format.\n"
1144 + "-msf FILE\tCreate alignment file FILE in MSF format.\n"
1145 + "-pileup FILE\tCreate alignment file FILE in Pileup format\n"
1146 + "-pir FILE\tCreate alignment file FILE in PIR format.\n"
1147 + "-blc FILE\tCreate alignment file FILE in BLC format.\n"
1148 + "-json FILE\tCreate alignment file FILE in JSON format.\n"
1149 + "-jalview FILE\tCreate alignment file FILE in Jalview format.\n"
1150 + "-png FILE\tCreate PNG image FILE from alignment.\n"
1151 + "-svg FILE\tCreate SVG image FILE from alignment.\n"
1152 + "-html FILE\tCreate HTML file from alignment.\n"
1153 + "-biojsMSA FILE\tCreate BioJS MSA Viewer HTML file from alignment.\n"
1154 + "-imgMap FILE\tCreate HTML file FILE with image map of PNG image.\n"
1155 + "-eps FILE\tCreate EPS file FILE from alignment.\n"
1156 + "-questionnaire URL\tQueries the given URL for information about any Jalview user questionnaires.\n"
1157 + "-noquestionnaire\tTurn off questionnaire check.\n"
1158 + "-nonews\tTurn off check for Jalview news.\n"
1159 + "-nousagestats\tTurn off google analytics tracking for this session.\n"
1160 + "-sortbytree OR -nosortbytree\tEnable or disable sorting of the given alignment by the given tree\n"
1162 // "-setprop PROPERTY=VALUE\tSet the given Jalview property,
1163 // after all other properties files have been read\n\t
1164 // (quote the 'PROPERTY=VALUE' pair to ensure spaces are
1165 // passed in correctly)"
1166 + "-jabaws URL\tSpecify URL for Jabaws services (e.g. for a local installation).\n"
1167 + "-fetchfrom nickname\tQuery nickname for features for the alignments and display them.\n"
1169 // "-vdoc vamsas-document\tImport vamsas document into new
1170 // session or join existing session with same URN\n"
1171 // + "-vses vamsas-session\tJoin session with given URN\n"
1172 + "-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"
1173 + "\n~Read documentation in Application or visit http://www.jalview.org for description of Features and Annotations file~\n\n");
1176 private static void startUsageStats(final Desktop desktop)
1179 * start a User Config prompt asking if we can log usage statistics.
1181 PromptUserConfig prompter = new PromptUserConfig(
1182 Desktop.getDesktopPane(), "USAGESTATS",
1183 "Jalview Usage Statistics",
1184 "Do you want to help make Jalview better by enabling "
1185 + "the collection of usage statistics with Google Analytics ?"
1186 + "\n\n(you can enable or disable usage tracking in the preferences)",
1193 "Initialising googletracker for usage stats.");
1194 Cache.initGoogleTracker();
1195 Cache.log.debug("Tracking enabled.");
1202 Cache.log.debug("Not enabling Google Tracking.");
1205 desktop.addDialogThread(prompter);
1209 * Locate the given string as a file and pass it to the groovy interpreter.
1211 * @param groovyscript
1212 * the script to execute
1213 * @param jalviewContext
1214 * the Jalview Desktop object passed in to the groovy binding as the
1217 private void executeGroovyScript(String groovyscript, AlignFrame af)
1220 * for scripts contained in files
1227 if (groovyscript.trim().equals("STDIN"))
1229 // read from stdin into a tempfile and execute it
1232 tfile = File.createTempFile("jalview", "groovy");
1233 PrintWriter outfile = new PrintWriter(
1234 new OutputStreamWriter(new FileOutputStream(tfile)));
1235 BufferedReader br = new BufferedReader(
1236 new InputStreamReader(System.in));
1238 while ((line = br.readLine()) != null)
1240 outfile.write(line + "\n");
1246 } catch (Exception ex)
1248 System.err.println("Failed to read from STDIN into tempfile "
1249 + ((tfile == null) ? "(tempfile wasn't created)"
1250 : tfile.toString()));
1251 ex.printStackTrace();
1256 sfile = tfile.toURI().toURL();
1257 } catch (Exception x)
1260 "Unexpected Malformed URL Exception for temporary file created from STDIN: "
1262 x.printStackTrace();
1270 sfile = new URI(groovyscript).toURL();
1271 } catch (Exception x)
1273 tfile = new File(groovyscript);
1274 if (!tfile.exists())
1276 System.err.println("File '" + groovyscript + "' does not exist.");
1279 if (!tfile.canRead())
1281 System.err.println("File '" + groovyscript + "' cannot be read.");
1284 if (tfile.length() < 1)
1286 System.err.println("File '" + groovyscript + "' is empty.");
1291 sfile = tfile.getAbsoluteFile().toURI().toURL();
1292 } catch (Exception ex)
1294 System.err.println("Failed to create a file URL for "
1295 + tfile.getAbsoluteFile());
1302 Map<String, Object> vbinding = new HashMap<>();
1303 vbinding.put("Jalview", this);
1306 vbinding.put("currentAlFrame", af);
1308 Binding gbinding = new Binding(vbinding);
1309 GroovyScriptEngine gse = new GroovyScriptEngine(new URL[] { sfile });
1310 gse.run(sfile.toString(), gbinding);
1311 if ("STDIN".equals(groovyscript))
1313 // delete temp file that we made -
1314 // only if it was successfully executed
1317 } catch (Exception e)
1319 System.err.println("Exception Whilst trying to execute file " + sfile
1320 + " as a groovy script.");
1321 e.printStackTrace(System.err);
1326 public AlignFrame[] getAlignFrames()
1328 return desktop == null ? new AlignFrame[] { getCurrentAlignFrame() }
1329 : Desktop.getAlignFrames();
1334 * Quit method delegates to Desktop.quit - unless running in headless mode
1335 * when it just ends the JVM
1339 if (jsFunctionExec != null)
1341 jsFunctionExec.tidyUp();
1342 jsFunctionExec = null;
1345 if (desktop != null)
1356 * Get the SwingJS applet ID and combine that with the frameType
1359 * "alignment", "desktop", etc., or null
1362 public static String getAppID(String frameType)
1364 String id = Cache.getProperty("Info.j2sAppletID");
1369 return id + (frameType == null ? "" : "-" + frameType);
1373 * Handle all JalviewLite applet parameters
1378 private void loadAppletParams(ArgsParser aparser, AlignFrame af)
1380 JalviewApp app = new JalviewApp()
1385 // These are methods that are in JalviewLite that various classes call
1386 // but are not in JalviewLiteJsApi. Or, even if they are, other classes
1388 // them to JalviewLite directly. Some may not be necessary, but they have
1390 // be at least mentioned here, or the classes calling them should
1392 // JalviewLite itself.
1394 private boolean alignPDBStructures; // From JalviewLite; not implemented
1396 private Hashtable<String, Hashtable<String, String[]>> jsmessages;
1398 private Hashtable<String, int[]> jshashes;
1401 public String getParameter(String name)
1403 return aparser.getAppletValue(name, null);
1407 public boolean getDefaultParameter(String name, boolean def)
1410 return ((stn = getParameter(name)) == null ? def
1411 : "true".equalsIgnoreCase(stn));
1415 * Get the applet-like document base even though this is an application.
1418 public URL getDocumentBase()
1420 return Platform.getDocumentBase();
1424 * Get the applet-like code base even though this is an application.
1427 public URL getCodeBase()
1429 return Platform.getCodeBase();
1433 public AlignViewportI getViewport()
1435 return af.getViewport();
1443 public boolean parseFeaturesFile(String filename,
1444 DataSourceType protocol)
1446 return af.parseFeaturesFile(filename, protocol);
1454 public boolean loadScoreFile(String sScoreFile) throws IOException
1456 af.loadJalviewDataFile(sScoreFile, null, null, null);
1461 * annotations, jpredfile, jnetfile
1465 public void updateForAnnotations()
1467 af.updateForAnnotations();
1471 public void loadTree(NewickFile fin, String treeFile)
1474 // n/a -- already done by standard Jalview command line processing
1478 public void setAlignPdbStructures(boolean defaultParameter)
1480 alignPDBStructures = true;
1484 public void newStructureView(PDBEntry pdb, SequenceI[] seqs,
1485 String[] chains, DataSourceType protocol)
1487 StructureViewer.launchStructureViewer(af.alignPanel, pdb, seqs);
1491 public void setFeatureGroupState(String[] groups, boolean state)
1493 af.setFeatureGroupState(groups, state);
1497 public void alignedStructureView(PDBEntry[] pdb, SequenceI[][] seqs,
1498 String[][] chains, String[] protocols)
1501 "Jalview applet interface alignedStructureView not implemented");
1505 public void newFeatureSettings()
1508 "Jalview applet interface newFeatureSettings not implemented");
1511 private Vector<Runnable> jsExecQueue;
1514 public Vector<Runnable> getJsExecQueue(JSFunctionExec exec)
1516 jsFunctionExec = exec;
1517 return (jsExecQueue == null ? (jsExecQueue = new Vector<>())
1522 public AppletContext getAppletContext()
1524 // TODO Auto-generated method stub
1529 public boolean isJsfallbackEnabled()
1531 // TODO Auto-generated method stub
1536 public JSObject getJSObject()
1538 // TODO Auto-generated method stub
1543 public StructureSelectionManagerProvider getStructureSelectionManagerProvider()
1545 // TODO Q: what exactly is this? BH
1550 public void updateColoursFromMouseOver(Object source,
1551 MouseOverStructureListener mouseOverStructureListener)
1553 // TODO Auto-generated method stub
1558 public Object[] getSelectionForListener(SequenceGroup seqsel,
1559 ColumnSelection colsel, HiddenColumns hidden,
1560 SelectionSource source, Object alignFrame)
1562 return appLoader.getSelectionForListener(getCurrentAlignFrame(),
1563 seqsel, colsel, hidden, source, alignFrame);
1567 public String arrayToSeparatorList(String[] array)
1569 return appLoader.arrayToSeparatorList(array);
1573 public Hashtable<String, int[]> getJSHashes()
1575 return (jshashes == null ? (jshashes = new Hashtable<>())
1580 public Hashtable<String, Hashtable<String, String[]>> getJSMessages()
1582 return (jsmessages == null ? (jsmessages = new Hashtable<>())
1587 public Object getFrameForSource(VamsasSource source)
1592 if (source instanceof jalview.gui.AlignViewport
1593 && source == (af = getCurrentAlignFrame()).getViewport())
1595 // should be valid if it just generated an event!
1598 // TODO: ensure that if '_af' is specified along with a handler
1599 // function, then only events from that alignFrame are sent to that
1606 public FeatureRenderer getNewFeatureRenderer(AlignViewportI vp)
1608 return new jalview.gui.FeatureRenderer((AlignmentPanel) vp);
1613 appLoader = new JalviewAppLoader(true);
1614 appLoader.load(app);
1619 * @see jalview.bin.JalviewLiteJsApi#getSelectedSequences()
1622 public String getSelectedSequences()
1624 return getSelectedSequencesFrom(getCurrentAlignFrame());
1629 * @see jalview.bin.JalviewLiteJsApi#getSelectedSequences(java.lang.String)
1632 public String getSelectedSequences(String sep)
1634 return getSelectedSequencesFrom(getCurrentAlignFrame(), sep);
1639 * @see jalview.bin.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
1643 public String getSelectedSequencesFrom(AlignFrameI alf)
1645 return getSelectedSequencesFrom(alf, null);
1650 * @see jalview.bin.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
1651 * .AlignFrame, java.lang.String)
1654 public String getSelectedSequencesFrom(AlignFrameI alf, String sep)
1656 return appLoader.getSelectedSequencesFrom(alf, sep);
1661 * @see jalview.bin.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
1662 * .AlignFrame, java.lang.String)
1665 public void highlight(String sequenceId, String position,
1666 String alignedPosition)
1668 highlightIn(getCurrentAlignFrame(), sequenceId, position,
1673 public void highlightIn(AlignFrameI alf, String sequenceId,
1674 String position, String alignedPosition)
1676 appLoader.highlightIn(alf, sequenceId, position, alignedPosition);
1680 public void select(String sequenceIds, String columns)
1682 selectIn(getCurrentAlignFrame(), sequenceIds, columns, null);
1686 public void select(String sequenceIds, String columns, String sep)
1688 selectIn(getCurrentAlignFrame(), sequenceIds, columns, sep);
1692 public void selectIn(AlignFrameI alf, String sequenceIds, String columns)
1694 selectIn(alf, sequenceIds, columns, null);
1698 public void selectIn(AlignFrameI alf, String sequenceIds, String columns,
1701 appLoader.selectIn(alf, sequenceIds, columns, sep);
1705 public String getSelectedSequencesAsAlignment(String format,
1708 return getSelectedSequencesAsAlignmentFrom(getCurrentAlignFrame(),
1713 public String getSelectedSequencesAsAlignmentFrom(AlignFrameI alf,
1714 String format, String sep)
1716 return appLoader.getSelectedSequencesAsAlignmentFrom(alf, format, sep);
1720 public String getAlignmentOrder()
1722 return getAlignmentFrom(getCurrentAlignFrame(), null);
1726 public String getAlignmentOrderFrom(AlignFrameI alf)
1728 return getAlignmentFrom(alf, null);
1732 public String getAlignmentOrderFrom(AlignFrameI alf, String sep)
1734 return appLoader.getAlignmentOrderFrom(alf, sep);
1738 public String orderBy(String order, String undoName)
1740 return orderBy(order, undoName, null);
1744 public String orderBy(String order, String undoName, String sep)
1746 return orderAlignmentBy(getCurrentAlignFrame(), order, undoName, sep);
1750 public String orderAlignmentBy(AlignFrameI alf, String order,
1751 String undoName, String sep)
1753 return appLoader.orderAlignmentBy(alf, order, undoName, sep);
1757 public String getAlignment(String format)
1759 return getAlignmentFrom(null, format, null);
1763 public String getAlignmentFrom(AlignFrameI alf, String format)
1765 return getAlignmentFrom(alf, format, null);
1769 public String getAlignment(String format, String suffix)
1771 return getAlignmentFrom(getCurrentAlignFrame(), format, suffix);
1775 public String getAlignmentFrom(AlignFrameI alf, String format,
1778 return appLoader.getAlignmentFrom(alf, format, suffix);
1782 public void loadAnnotation(String annotation)
1784 loadAnnotationFrom(getCurrentAlignFrame(), annotation);
1788 public void loadAnnotationFrom(AlignFrameI alf, String annotation)
1790 appLoader.loadAnnotationFrom(alf, annotation);
1794 public void loadFeatures(String features, boolean autoenabledisplay)
1796 loadFeaturesFrom(currentAlignFrame, features, autoenabledisplay);
1800 public boolean loadFeaturesFrom(AlignFrameI alf, String features,
1801 boolean autoenabledisplay)
1803 return appLoader.loadFeaturesFrom(alf, features, autoenabledisplay);
1807 public String getFeatures(String format)
1809 return getFeaturesFrom(getCurrentAlignFrame(), format);
1813 public String getFeaturesFrom(AlignFrameI alf, String format)
1815 return appLoader.getFeaturesFrom(alf, format);
1819 public String getAnnotation()
1821 return getAnnotationFrom(getCurrentAlignFrame());
1825 public String getAnnotationFrom(AlignFrameI alf)
1827 return appLoader.getAnnotationFrom(alf);
1831 public AlignFrameI newView()
1833 return newViewFrom(getCurrentAlignFrame(), null);
1837 public AlignFrameI newView(String name)
1839 return newViewFrom(getCurrentAlignFrame(), name);
1843 public AlignFrameI newViewFrom(AlignFrameI alf)
1845 return newViewFrom(alf, null);
1849 public AlignFrameI newViewFrom(AlignFrameI alf, String name)
1851 return appLoader.newViewFrom(alf, name);
1855 public AlignFrameI loadAlignment(String text, String title)
1857 return appLoader.loadAlignment(text, AlignFrame.DEFAULT_WIDTH,
1858 AlignFrame.DEFAULT_HEIGHT, title);
1862 public boolean addPdbFile(AlignFrameI alFrame, String sequenceId,
1863 String pdbEntryString, String pdbFile)
1865 return appLoader.addPdbFile(alFrame, sequenceId, pdbEntryString,
1870 public void scrollViewToIn(AlignFrameI alf, String topRow,
1871 String leftHandColumn)
1873 appLoader.scrollViewToIn(alf, topRow, leftHandColumn);
1877 public void scrollViewToRowIn(AlignFrameI alf, String topRow)
1879 appLoader.scrollViewToRowIn(alf, topRow);
1883 public void scrollViewToColumnIn(AlignFrameI alf, String leftHandColumn)
1885 appLoader.scrollViewToColumnIn(alf, leftHandColumn);
1889 public String getFeatureGroups()
1891 return getFeatureGroupsOn(getCurrentAlignFrame());
1895 public String getFeatureGroupsOn(AlignFrameI alf)
1897 return appLoader.getFeatureGroupsOn(alf);
1901 public String getFeatureGroupsOfState(boolean visible)
1903 return getFeatureGroupsOfStateOn(getCurrentAlignFrame(), visible);
1907 public String getFeatureGroupsOfStateOn(AlignFrameI alf, boolean visible)
1909 return appLoader.getFeatureGroupsOfStateOn(alf, visible);
1913 public void setFeatureGroupStateOn(AlignFrameI alf, String groups,
1916 setFeatureGroupStateOn(alf, groups, state);
1920 public void setFeatureGroupState(String groups, boolean state)
1922 appLoader.setFeatureGroupStateOn(getCurrentAlignFrame(), groups, state);
1926 public String getSeparator()
1928 return appLoader.getSeparator();
1932 public void setSeparator(String separator)
1934 appLoader.setSeparator(separator);
1938 public String getJsMessage(String messageclass, String viewId)
1940 // see http://www.jalview.org/examples/jalviewLiteJs.html
1945 * Open a new Tree panel on the desktop statically. Params are standard (not
1946 * set by Groovy). No dialog is opened.
1951 * @return null, or the string "label.you_need_at_least_n_sequences" if number
1952 * of sequences selected is inappropriate
1955 public Object openTreePanel(AlignFrame af, String treeType,
1958 return CalculationChooser.openTreePanel(af, treeType, modelName, null);
1962 * public static method for JalviewJS API to open a PCAPanel without
1963 * necessarily using a dialog.
1967 * @return the PCAPanel, or the string "label.you_need_at_least_n_sequences"
1968 * if number of sequences selected is inappropriate
1971 public Object openPcaPanel(AlignFrame af, String modelName)
1973 return CalculationChooser.openPcaPanel(af, modelName, null);
1977 public String getSelectedSequencesAsAlignment(String format,
1980 return getSelectedSequencesAsAlignmentFrom(getCurrentAlignFrame(),
1985 public String getSelectedSequencesAsAlignmentFrom(AlignFrameI alf,
1986 String format, boolean suffix)
1988 return appLoader.getSelectedSequencesAsAlignmentFrom(alf, format,
1993 public String arrayToSeparatorList(String[] array)
1995 return appLoader.arrayToSeparatorList(array);
1999 public String[] separatorListToArray(String list)
2001 return appLoader.separatorListToArray(list);
2004 //// probably not needed in JalviewJS -- From when Jmol and Jalview did not
2005 //// have a direct connection?
2008 public void setMouseoverListener(String listener)
2010 // TODO Auto-generated method stub
2015 public void setMouseoverListener(AlignFrameI af, String listener)
2017 // TODO Auto-generated method stub
2022 public void setSelectionListener(String listener)
2024 // TODO Auto-generated method stub
2029 public void setSelectionListener(AlignFrameI af, String listener)
2031 // TODO Auto-generated method stub
2036 public void setStructureListener(String listener, String modelSet)
2038 // TODO Auto-generated method stub
2043 public void removeJavascriptListener(AlignFrameI af, String listener)
2045 // TODO Auto-generated method stub
2050 public void mouseOverStructure(String pdbResNum, String chain,
2053 // TODO Auto-generated method stub
2058 public void showOverview()
2060 currentAlignFrame.overviewMenuItem_actionPerformed(null);
2063 public void notifyWorker(AlignCalcWorkerI worker, String status)
2065 // System.out.println("Jalview worker " + worker.getClass().getSimpleName()