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 System.setSecurityManager(null);
299 .println("Java version: " + System.getProperty("java.version"));
300 System.out.println(System.getProperty("os.arch") + " "
301 + System.getProperty("os.name") + " "
302 + System.getProperty("os.version"));
304 ArgsParser aparser = new ArgsParser(args);
306 String usrPropsFile = aparser.getValue(ArgsParser.PROPS);
307 Cache.loadProperties(usrPropsFile);
309 if (aparser.contains(ArgsParser.NODISPLAY)
310 || aparser.contains(ArgsParser.NOGUI)
311 || aparser.contains(ArgsParser.HEADLESS)
312 || "true".equals(System.getProperty("java.awt.headless")))
319 isJavaAppletTag = aparser.isApplet();
322 Preferences.setAppletDefaults();
323 Cache.loadProperties(usrPropsFile); // again, because we
324 // might be changing defaults here?
327 "<Applet> found: " + aparser.getValue("Info.j2sAppletID"));
328 appletResourcePath = aparser.getValue("Info.resourcePath");
337 if (usrPropsFile != null)
340 "CMD [-props " + usrPropsFile + "] executed successfully!");
343 if (aparser.contains("help") || aparser.contains("h"))
352 final String jabawsUrl = aparser.getValue(ArgsParser.JABAWS);
353 if (jabawsUrl != null)
357 Jws2Discoverer.getInstance().setPreferredUrl(jabawsUrl);
359 "CMD [-jabaws " + jabawsUrl + "] executed successfully!");
360 } catch (MalformedURLException e)
363 "Invalid jabaws parameter: " + jabawsUrl + " ignored");
368 // check for property setting
369 String defs = aparser.getValue(ArgsParser.SETPROP);
372 int p = defs.indexOf('=');
375 System.err.println("Ignoring invalid setprop argument : " + defs);
379 System.out.println("Executing setprop argument: " + defs);
382 Cache.setProperty(defs.substring(0, p), defs.substring(p + 1));
385 defs = aparser.getValue(ArgsParser.SETPROP);
387 System.setProperty("http.agent",
388 "Jalview Desktop/" + Cache.getDefault("VERSION", "Unknown"));
392 } catch (NoClassDefFoundError error)
394 error.printStackTrace();
395 System.out.println("\nEssential logging libraries not found."
396 + "\nUse: java -classpath \"$PATH_TO_LIB$/*:$PATH_TO_CLASSES$\" jalview.bin.Jalview");
404 if (!isJS && Platform.isWin())
406 UIManager.setLookAndFeel(
407 headless ? "javax.swing.plaf.metal.MetalLookAndFeel"
408 : UIManager.getSystemLookAndFeelClassName());
409 // UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
411 } catch (Exception ex)
413 System.err.println("Unexpected Look and Feel Exception");
414 ex.printStackTrace();
416 if (Platform.isAMacAndNotJS())
419 LookAndFeel lookAndFeel = ch.randelshofer.quaqua.QuaquaManager
421 System.setProperty("com.apple.mrj.application.apple.menu.about.name",
423 System.setProperty("apple.laf.useScreenMenuBar", "true");
424 if (lookAndFeel != null)
428 UIManager.setLookAndFeel(lookAndFeel);
429 } catch (Throwable e)
432 "Failed to set QuaQua look and feel: " + e.toString());
435 if (lookAndFeel == null
436 || !(lookAndFeel.getClass().isAssignableFrom(
437 UIManager.getLookAndFeel().getClass()))
438 || !UIManager.getLookAndFeel().getClass().toString()
439 .toLowerCase().contains("quaqua"))
444 "Quaqua LaF not available on this plaform. Using VAqua(4).\nSee https://issues.jalview.org/browse/JAL-2976");
445 UIManager.setLookAndFeel("org.violetlib.aqua.AquaLookAndFeel");
446 } catch (Throwable e)
449 "Failed to reset look and feel: " + e.toString());
455 * configure 'full' SO model if preferences say to,
456 * else use the default (SO Lite)
458 if (Cache.getDefault(Preferences.USE_FULL_SO, false))
460 SequenceOntologyFactory.setSequenceOntology(new SequenceOntology());
465 desktop = Desktop.getInstance();
466 desktop.setInBatchMode(true); // indicate we are starting up
467 desktop.setVisible(true);
476 desktop.startServiceDiscovery();
477 if (!aparser.contains(ArgsParser.NOUSAGESTATS))
479 startUsageStats(desktop);
483 System.err.println("CMD [-nousagestats] executed successfully!");
486 if (!aparser.contains(ArgsParser.NOQUESTIONNAIRE))
488 String url = aparser.getValue(ArgsParser.QUESTIONNAIRE);
491 // Start the desktop questionnaire prompter with the specified
493 Cache.log.debug("Starting questionnaire url at " + url);
494 desktop.checkForQuestionnaire(url);
495 System.out.println("CMD questionnaire[-" + url
496 + "] executed successfully!");
500 if (Cache.getProperty(Preferences.NOQUESTIONNAIRES) == null)
502 // Start the desktop questionnaire prompter with the specified
505 // "http://anaplog.compbio.dundee.ac.uk/cgi-bin/questionnaire.pl";
507 String defurl = "http://www.jalview.org/cgi-bin/questionnaire.pl";
509 "Starting questionnaire with default url: " + defurl);
510 desktop.checkForQuestionnaire(defurl);
517 .println("CMD [-noquestionnaire] executed successfully!");
520 if (!aparser.contains(ArgsParser.NONEWS))
522 desktop.checkForNews();
525 BioJsHTMLOutput.updateBioJS();
529 parseArguments(aparser, true);
533 * Allow an outside entity to initiate the second half of argument parsing
537 * @return null is good
540 public Object parseArguments(String[] args)
545 ArgsParser aparser = new ArgsParser(args);
546 return parseArguments(aparser, false);
547 } catch (Throwable t)
559 private Object parseArguments(ArgsParser aparser, boolean isStartup)
561 boolean isJS = Platform.isJS();
563 Desktop desktop = (headless ? null : Desktop.getInstance());
564 // script to execute after all loading is
565 // completed one way or another
566 // extract groovy argument and execute if necessary
567 String groovyscript = (isJS ? null
568 : aparser.getValue(ArgsParser.GROOVY, true));
569 String file = aparser.getValue(ArgsParser.OPEN, true);
570 // BH this here to allow split frame; not working as of 5/17/2019
571 String file2 = aparser.getValue(ArgsParser.OPEN2, true);
572 String fileFormat = (isJavaAppletTag
573 ? aparser.getAppletValue("format", null)
575 FileFormatI format = null;
576 DataSourceType protocol = null;
578 if (file == null && desktop == null)
580 System.out.println("No files to open!");
583 boolean haveImport = checkStartVamas(aparser);
584 // Finally, deal with the remaining input data.
586 if (file == null && isJavaAppletTag)
588 // Maybe the sequences are added as parameters
589 StringBuffer data = new StringBuffer("PASTE");
591 while ((file = aparser.getAppletValue("sequence" + i, null)) != null)
593 data.append(file.toString() + "\n");
596 if (data.length() > 5)
598 file = data.toString();
609 desktop.setProgressBar(
611 .getString("status.processing_commandline_args"),
612 progress = System.currentTimeMillis());
617 * ignore in JavaScript -- can't just check file existence - could load
623 if (!file.startsWith("http://") && !file.startsWith("https://"))
624 // BH 2019 added https check for Java
626 if (!(new File(file)).exists())
628 System.out.println("Can't find " + file);
637 protocol = AppletFormatAdapter.checkProtocol(file);
641 format = (isJavaAppletTag && fileFormat != null
642 ? FileFormats.getInstance().forName(fileFormat)
646 format = new IdentifyFile().identify(file, protocol);
648 } catch (FileFormatException e1)
653 if (aparser.contains(ArgsParser.NOMENUBAR))
656 System.out.println("CMD [nomenu] executed successfully!");
659 if (aparser.contains(ArgsParser.NOSTATUS))
662 System.out.println("CMD [nostatus] executed successfully!");
665 if (aparser.contains(ArgsParser.NOANNOTATION)
666 || aparser.contains(ArgsParser.NOANNOTATION2))
669 System.out.println("CMD no-annotation executed successfully!");
671 if (aparser.contains(ArgsParser.NOCALCULATION))
673 noCalculation = true;
674 System.out.println("CMD [nocalculation] executed successfully!");
677 AlignFrame af = new FileLoader(!headless).loadFileWaitTillLoaded(file,
681 System.out.println("error");
686 .println("CMD [-open " + file + "] executed successfully!");
689 protocol = AppletFormatAdapter.checkProtocol(file2);
692 format = new IdentifyFile().identify(file2, protocol);
693 } catch (FileFormatException e1)
697 AlignFrame af2 = new FileLoader(!headless)
698 .loadFileWaitTillLoaded(file2, protocol, format);
701 System.out.println("error");
705 AlignViewport.openLinkedAlignmentAs(af,
706 af.getViewport().getAlignment(),
707 af2.getViewport().getAlignment(), "",
708 AlignViewport.SPLIT_FRAME);
710 "CMD [-open2 " + file2 + "] executed successfully!");
714 setCurrentAlignFrame(af);
716 // TODO: file2 How to implement file2 for the applet spit screen?
718 data = aparser.getValue(ArgsParser.COLOUR, true);
721 data.replaceAll("%20", " ");
723 ColourSchemeI cs = ColourSchemeProperty.getColourScheme(
724 af.getViewport(), af.getViewport().getAlignment(), data);
729 "CMD [-color " + data + "] executed successfully!");
734 // Must maintain ability to use the groups flag
735 data = aparser.getValue(ArgsParser.GROUPS, true);
738 af.parseFeaturesFile(data,
739 AppletFormatAdapter.checkProtocol(data));
740 // System.out.println("Added " + data);
742 "CMD groups[-" + data + "] executed successfully!");
744 data = aparser.getValue(ArgsParser.FEATURES, true);
747 af.parseFeaturesFile(data,
748 AppletFormatAdapter.checkProtocol(data));
749 // System.out.println("Added " + data);
751 "CMD [-features " + data + "] executed successfully!");
754 data = aparser.getValue(ArgsParser.ANNOTATIONS, true);
757 af.loadJalviewDataFile(data, null, null, null);
758 // System.out.println("Added " + data);
760 "CMD [-annotations " + data + "] executed successfully!");
763 if (aparser.contains(ArgsParser.SHOWOVERVIEW))
765 af.overviewMenuItem_actionPerformed(null);
766 System.out.println("CMD [showoverview] executed successfully!");
769 // set or clear the sortbytree flag.
770 if (aparser.contains(ArgsParser.SORTBYTREE))
772 af.getViewport().setSortByTree(true);
773 if (af.getViewport().getSortByTree())
775 System.out.println("CMD [-sortbytree] executed successfully!");
779 boolean doUpdateAnnotation = false;
782 * we do this earlier in JalviewJS because of a complication with
785 * For now, just fixing this in JalviewJS.
792 if (aparser.contains(ArgsParser.NOANNOTATION)
793 || aparser.contains(ArgsParser.NOANNOTATION2))
795 af.getViewport().setShowAnnotation(false);
796 if (!af.getViewport().isShowAnnotation())
798 doUpdateAnnotation = true;
800 .println("CMD no-annotation executed successfully!");
804 if (aparser.contains(ArgsParser.NOSORTBYTREE))
806 af.getViewport().setSortByTree(false);
807 if (!af.getViewport().getSortByTree())
809 doUpdateAnnotation = true;
811 .println("CMD [-nosortbytree] executed successfully!");
814 if (doUpdateAnnotation)
816 af.setMenusForViewport();
817 af.alignPanel.updateLayout();
819 data = aparser.getValue(ArgsParser.TREE, true);
825 "CMD [-tree " + data + "] executed successfully!");
826 NewickFile nf = new NewickFile(data,
827 AppletFormatAdapter.checkProtocol(data));
829 .setCurrentTree(af.showNewickTree(nf, data).getTree());
830 } catch (IOException ex)
832 System.err.println("Couldn't add tree " + data);
833 ex.printStackTrace(System.err);
836 // TODO - load PDB structure(s) to alignment JAL-629
837 // (associate with identical sequence in alignment, or a specified
841 loadAppletParams(aparser, af);
850 if (groovyscript != null)
852 // Execute the groovy script after we've done all the rendering
854 // and before any images or figures are generated.
855 System.out.println("Executing script " + groovyscript);
856 executeGroovyScript(groovyscript, af);
857 System.out.println("CMD groovy[" + groovyscript
858 + "] executed successfully!");
862 checkOutputFile(aparser, af, format);
863 while (aparser.getSize() > 0)
865 System.out.println("Unknown arg: " + aparser.nextValue());
869 AlignFrame startUpAlframe = null;
870 // We'll only open the default file if the desktop is visible.
872 // ////////////////////
874 if (!isJS && !headless && file == null && !haveImport
875 && jalview.bin.Cache.getDefault("SHOW_STARTUP_FILE", true))
882 file = jalview.bin.Cache.getDefault("STARTUP_FILE",
883 jalview.bin.Cache.getDefault("www.jalview.org",
884 "http://www.jalview.org")
885 + "/examples/exampleFile_2_7.jar");
887 "http://www.jalview.org/examples/exampleFile_2_3.jar"))
889 // hardwire upgrade of the startup file
890 file.replace("_2_3.jar", "_2_7.jar");
891 // and remove the stale setting
892 jalview.bin.Cache.removeProperty("STARTUP_FILE");
895 protocol = DataSourceType.FILE;
897 if (file.indexOf("http:") > -1)
899 protocol = DataSourceType.URL;
902 if (file.endsWith(".jar"))
904 format = FileFormat.Jalview;
910 format = new IdentifyFile().identify(file, protocol);
911 } catch (FileFormatException e)
917 startUpAlframe = new FileLoader(!headless)
918 .loadFileWaitTillLoaded(file, protocol, format);
919 // extract groovy arguments before anything else.
922 // Once all other stuff is done, execute any groovy scripts (in order)
923 if (groovyscript != null)
925 if (Cache.groovyJarsPresent())
927 System.out.println("Executing script " + groovyscript);
928 executeGroovyScript(groovyscript, startUpAlframe);
933 "Sorry. Groovy Support is not available, so ignoring the provided groovy script "
937 // and finally, turn off batch mode indicator - if the desktop still exists
942 desktop.setProgressBar(null, progress);
944 desktop.setInBatchMode(false);
950 private boolean checkStartVamas(ArgsParser aparser)
952 String vamsasImport = aparser.getValue(ArgsParser.VDOC);
953 String vamsasSession = aparser.getValue(ArgsParser.VSESS);
954 if (vamsasImport == null && vamsasSession == null)
958 if (desktop == null || headless)
961 "Headless vamsas sessions not yet supported. Sorry.");
964 boolean haveImport = (vamsasImport != null);
967 // if we have a file, start a new session and import it.
968 boolean inSession = false;
971 DataSourceType viprotocol = AppletFormatAdapter
972 .checkProtocol(vamsasImport);
973 if (viprotocol == DataSourceType.FILE)
975 inSession = desktop.vamsasImport(new File(vamsasImport));
977 else if (viprotocol == DataSourceType.URL)
979 inSession = desktop.vamsasImport(new URL(vamsasImport));
982 } catch (Exception e)
984 System.err.println("Exeption when importing " + vamsasImport
985 + " as a vamsas document.");
990 System.err.println("Failed to import " + vamsasImport
991 + " as a vamsas document.");
995 System.out.println("Imported Successfully into new session "
996 + desktop.getVamsasApplication().getCurrentSession());
999 if (vamsasSession != null)
1001 if (vamsasImport != null)
1003 // close the newly imported session and import the Jalview specific
1004 // remnants into the new session later on.
1005 desktop.vamsasStop_actionPerformed(null);
1007 // now join the new session
1010 if (desktop.joinVamsasSession(vamsasSession))
1013 "Successfully joined vamsas session " + vamsasSession);
1017 System.err.println("WARNING: Failed to join vamsas session "
1020 } catch (Exception e)
1023 "ERROR: Failed to join vamsas session " + vamsasSession);
1024 e.printStackTrace();
1026 if (vamsasImport != null)
1028 // the Jalview specific remnants can now be imported into the new
1029 // session at the user's leisure.
1031 "Skipping Push for import of data into existing vamsas session.");
1037 // desktop.getVamsasApplication().push_update();
1043 private void checkOutputFile(ArgsParser aparser, AlignFrame af,
1046 String imageName = "unnamed.png";
1047 while (aparser.getSize() > 1)
1052 // biojsmsa filename
1053 String outputFormat = aparser.nextValue();
1054 String file = aparser.nextValue();
1055 System.out.println("format " + outputFormat);
1057 if (outputFormat.equalsIgnoreCase("png"))
1059 af.createPNG(new File(file));
1060 imageName = (new File(file)).getName();
1061 System.out.println("Creating PNG image: " + file);
1064 else if (outputFormat.equalsIgnoreCase("svg"))
1066 File imageFile = new File(file);
1067 imageName = imageFile.getName();
1068 af.createSVG(imageFile);
1069 System.out.println("Creating SVG image: " + file);
1072 else if (outputFormat.equalsIgnoreCase("html"))
1074 File imageFile = new File(file);
1075 imageName = imageFile.getName();
1076 HtmlSvgOutput htmlSVG = new HtmlSvgOutput(af.alignPanel);
1077 htmlSVG.exportHTML(file);
1079 System.out.println("Creating HTML image: " + file);
1082 else if (outputFormat.equalsIgnoreCase("biojsmsa"))
1086 System.err.println("The output html file must not be null");
1091 BioJsHTMLOutput.refreshVersionInfo(
1092 BioJsHTMLOutput.BJS_TEMPLATES_LOCAL_DIRECTORY);
1093 } catch (URISyntaxException e)
1095 e.printStackTrace();
1097 BioJsHTMLOutput bjs = new BioJsHTMLOutput(af.alignPanel);
1098 bjs.exportHTML(file);
1099 System.out.println("Creating BioJS MSA Viwer HTML file: " + file);
1102 else if (outputFormat.equalsIgnoreCase("imgMap"))
1104 af.createImageMap(new File(file), imageName);
1105 System.out.println("Creating image map: " + file);
1108 else if (outputFormat.equalsIgnoreCase("eps"))
1110 File outputFile = new File(file);
1112 "Creating EPS file: " + outputFile.getAbsolutePath());
1113 af.createEPS(outputFile);
1117 af.saveAlignment(file, format);
1118 if (af.isSaveAlignmentSuccessful())
1121 "Written alignment in " + format + " format to " + file);
1125 System.out.println("Error writing file " + file + " in " + format
1132 private static void showUsage()
1135 "Usage: jalview -open [FILE] [OUTPUT_FORMAT] [OUTPUT_FILE]\n\n"
1136 + "-nodisplay\tRun Jalview without User Interface.\n"
1137 + "-props FILE\tUse the given Jalview properties file instead of users default.\n"
1138 + "-colour COLOURSCHEME\tThe colourscheme to be applied to the alignment\n"
1139 + "-annotations FILE\tAdd precalculated annotations to the alignment.\n"
1140 + "-tree FILE\tLoad the given newick format tree file onto the alignment\n"
1141 + "-features FILE\tUse the given file to mark features on the alignment.\n"
1142 + "-fasta FILE\tCreate alignment file FILE in Fasta format.\n"
1143 + "-clustal FILE\tCreate alignment file FILE in Clustal format.\n"
1144 + "-pfam FILE\tCreate alignment file FILE in PFAM format.\n"
1145 + "-msf FILE\tCreate alignment file FILE in MSF format.\n"
1146 + "-pileup FILE\tCreate alignment file FILE in Pileup format\n"
1147 + "-pir FILE\tCreate alignment file FILE in PIR format.\n"
1148 + "-blc FILE\tCreate alignment file FILE in BLC format.\n"
1149 + "-json FILE\tCreate alignment file FILE in JSON format.\n"
1150 + "-jalview FILE\tCreate alignment file FILE in Jalview format.\n"
1151 + "-png FILE\tCreate PNG image FILE from alignment.\n"
1152 + "-svg FILE\tCreate SVG image FILE from alignment.\n"
1153 + "-html FILE\tCreate HTML file from alignment.\n"
1154 + "-biojsMSA FILE\tCreate BioJS MSA Viewer HTML file from alignment.\n"
1155 + "-imgMap FILE\tCreate HTML file FILE with image map of PNG image.\n"
1156 + "-eps FILE\tCreate EPS file FILE from alignment.\n"
1157 + "-questionnaire URL\tQueries the given URL for information about any Jalview user questionnaires.\n"
1158 + "-noquestionnaire\tTurn off questionnaire check.\n"
1159 + "-nonews\tTurn off check for Jalview news.\n"
1160 + "-nousagestats\tTurn off google analytics tracking for this session.\n"
1161 + "-sortbytree OR -nosortbytree\tEnable or disable sorting of the given alignment by the given tree\n"
1163 // "-setprop PROPERTY=VALUE\tSet the given Jalview property,
1164 // after all other properties files have been read\n\t
1165 // (quote the 'PROPERTY=VALUE' pair to ensure spaces are
1166 // passed in correctly)"
1167 + "-jabaws URL\tSpecify URL for Jabaws services (e.g. for a local installation).\n"
1168 + "-fetchfrom nickname\tQuery nickname for features for the alignments and display them.\n"
1170 // "-vdoc vamsas-document\tImport vamsas document into new
1171 // session or join existing session with same URN\n"
1172 // + "-vses vamsas-session\tJoin session with given URN\n"
1173 + "-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"
1174 + "\n~Read documentation in Application or visit http://www.jalview.org for description of Features and Annotations file~\n\n");
1177 private static void startUsageStats(final Desktop desktop)
1180 * start a User Config prompt asking if we can log usage statistics.
1182 PromptUserConfig prompter = new PromptUserConfig(
1183 Desktop.getDesktopPane(), "USAGESTATS",
1184 "Jalview Usage Statistics",
1185 "Do you want to help make Jalview better by enabling "
1186 + "the collection of usage statistics with Google Analytics ?"
1187 + "\n\n(you can enable or disable usage tracking in the preferences)",
1194 "Initialising googletracker for usage stats.");
1195 Cache.initGoogleTracker();
1196 Cache.log.debug("Tracking enabled.");
1203 Cache.log.debug("Not enabling Google Tracking.");
1206 desktop.addDialogThread(prompter);
1210 * Locate the given string as a file and pass it to the groovy interpreter.
1212 * @param groovyscript
1213 * the script to execute
1214 * @param jalviewContext
1215 * the Jalview Desktop object passed in to the groovy binding as the
1218 private void executeGroovyScript(String groovyscript, AlignFrame af)
1221 * for scripts contained in files
1228 if (groovyscript.trim().equals("STDIN"))
1230 // read from stdin into a tempfile and execute it
1233 tfile = File.createTempFile("jalview", "groovy");
1234 PrintWriter outfile = new PrintWriter(
1235 new OutputStreamWriter(new FileOutputStream(tfile)));
1236 BufferedReader br = new BufferedReader(
1237 new InputStreamReader(System.in));
1239 while ((line = br.readLine()) != null)
1241 outfile.write(line + "\n");
1247 } catch (Exception ex)
1249 System.err.println("Failed to read from STDIN into tempfile "
1250 + ((tfile == null) ? "(tempfile wasn't created)"
1251 : tfile.toString()));
1252 ex.printStackTrace();
1257 sfile = tfile.toURI().toURL();
1258 } catch (Exception x)
1261 "Unexpected Malformed URL Exception for temporary file created from STDIN: "
1263 x.printStackTrace();
1271 sfile = new URI(groovyscript).toURL();
1272 } catch (Exception x)
1274 tfile = new File(groovyscript);
1275 if (!tfile.exists())
1277 System.err.println("File '" + groovyscript + "' does not exist.");
1280 if (!tfile.canRead())
1282 System.err.println("File '" + groovyscript + "' cannot be read.");
1285 if (tfile.length() < 1)
1287 System.err.println("File '" + groovyscript + "' is empty.");
1292 sfile = tfile.getAbsoluteFile().toURI().toURL();
1293 } catch (Exception ex)
1295 System.err.println("Failed to create a file URL for "
1296 + tfile.getAbsoluteFile());
1303 Map<String, Object> vbinding = new HashMap<>();
1304 vbinding.put("Jalview", this);
1307 vbinding.put("currentAlFrame", af);
1309 Binding gbinding = new Binding(vbinding);
1310 GroovyScriptEngine gse = new GroovyScriptEngine(new URL[] { sfile });
1311 gse.run(sfile.toString(), gbinding);
1312 if ("STDIN".equals(groovyscript))
1314 // delete temp file that we made -
1315 // only if it was successfully executed
1318 } catch (Exception e)
1320 System.err.println("Exception Whilst trying to execute file " + sfile
1321 + " as a groovy script.");
1322 e.printStackTrace(System.err);
1327 public AlignFrame[] getAlignFrames()
1329 return desktop == null ? new AlignFrame[] { getCurrentAlignFrame() }
1330 : Desktop.getAlignFrames();
1335 * Quit method delegates to Desktop.quit - unless running in headless mode
1336 * when it just ends the JVM
1340 if (jsFunctionExec != null)
1342 jsFunctionExec.tidyUp();
1343 jsFunctionExec = null;
1346 if (desktop != null)
1357 * Get the SwingJS applet ID and combine that with the frameType
1360 * "alignment", "desktop", etc., or null
1363 public static String getAppID(String frameType)
1365 String id = Cache.getProperty("Info.j2sAppletID");
1370 return id + (frameType == null ? "" : "-" + frameType);
1374 * Handle all JalviewLite applet parameters
1379 private void loadAppletParams(ArgsParser aparser, AlignFrame af)
1381 JalviewApp app = new JalviewApp()
1386 // These are methods that are in JalviewLite that various classes call
1387 // but are not in JalviewLiteJsApi. Or, even if they are, other classes
1389 // them to JalviewLite directly. Some may not be necessary, but they have
1391 // be at least mentioned here, or the classes calling them should
1393 // JalviewLite itself.
1395 private boolean alignPDBStructures; // From JalviewLite; not implemented
1397 private Hashtable<String, Hashtable<String, String[]>> jsmessages;
1399 private Hashtable<String, int[]> jshashes;
1402 public String getParameter(String name)
1404 return aparser.getAppletValue(name, null);
1408 public boolean getDefaultParameter(String name, boolean def)
1411 return ((stn = getParameter(name)) == null ? def
1412 : "true".equalsIgnoreCase(stn));
1416 * Get the applet-like document base even though this is an application.
1419 public URL getDocumentBase()
1421 return Platform.getDocumentBase();
1425 * Get the applet-like code base even though this is an application.
1428 public URL getCodeBase()
1430 return Platform.getCodeBase();
1434 public AlignViewportI getViewport()
1436 return af.getViewport();
1444 public boolean parseFeaturesFile(String filename,
1445 DataSourceType protocol)
1447 return af.parseFeaturesFile(filename, protocol);
1455 public boolean loadScoreFile(String sScoreFile) throws IOException
1457 af.loadJalviewDataFile(sScoreFile, null, null, null);
1462 * annotations, jpredfile, jnetfile
1466 public void updateForAnnotations()
1468 af.updateForAnnotations();
1472 public void loadTree(NewickFile fin, String treeFile)
1475 // n/a -- already done by standard Jalview command line processing
1479 public void setAlignPdbStructures(boolean defaultParameter)
1481 alignPDBStructures = true;
1485 public void newStructureView(PDBEntry pdb, SequenceI[] seqs,
1486 String[] chains, DataSourceType protocol)
1488 StructureViewer.launchStructureViewer(af.alignPanel, pdb, seqs);
1492 public void setFeatureGroupState(String[] groups, boolean state)
1494 af.setFeatureGroupState(groups, state);
1498 public void alignedStructureView(PDBEntry[] pdb, SequenceI[][] seqs,
1499 String[][] chains, String[] protocols)
1502 "Jalview applet interface alignedStructureView not implemented");
1506 public void newFeatureSettings()
1509 "Jalview applet interface newFeatureSettings not implemented");
1512 private Vector<Runnable> jsExecQueue;
1515 public Vector<Runnable> getJsExecQueue(JSFunctionExec exec)
1517 jsFunctionExec = exec;
1518 return (jsExecQueue == null ? (jsExecQueue = new Vector<>())
1523 public AppletContext getAppletContext()
1525 // TODO Auto-generated method stub
1530 public boolean isJsfallbackEnabled()
1532 // TODO Auto-generated method stub
1537 public JSObject getJSObject()
1539 // TODO Auto-generated method stub
1544 public StructureSelectionManagerProvider getStructureSelectionManagerProvider()
1546 // TODO Q: what exactly is this? BH
1551 public void updateColoursFromMouseOver(Object source,
1552 MouseOverStructureListener mouseOverStructureListener)
1554 // TODO Auto-generated method stub
1559 public Object[] getSelectionForListener(SequenceGroup seqsel,
1560 ColumnSelection colsel, HiddenColumns hidden,
1561 SelectionSource source, Object alignFrame)
1563 return appLoader.getSelectionForListener(getCurrentAlignFrame(),
1564 seqsel, colsel, hidden, source, alignFrame);
1568 public String arrayToSeparatorList(String[] array)
1570 return appLoader.arrayToSeparatorList(array);
1574 public Hashtable<String, int[]> getJSHashes()
1576 return (jshashes == null ? (jshashes = new Hashtable<>())
1581 public Hashtable<String, Hashtable<String, String[]>> getJSMessages()
1583 return (jsmessages == null ? (jsmessages = new Hashtable<>())
1588 public Object getFrameForSource(VamsasSource source)
1593 if (source instanceof jalview.gui.AlignViewport
1594 && source == (af = getCurrentAlignFrame()).getViewport())
1596 // should be valid if it just generated an event!
1599 // TODO: ensure that if '_af' is specified along with a handler
1600 // function, then only events from that alignFrame are sent to that
1607 public FeatureRenderer getNewFeatureRenderer(AlignViewportI vp)
1609 return new jalview.gui.FeatureRenderer((AlignmentPanel) vp);
1614 appLoader = new JalviewAppLoader(true);
1615 appLoader.load(app);
1620 * @see jalview.bin.JalviewLiteJsApi#getSelectedSequences()
1623 public String getSelectedSequences()
1625 return getSelectedSequencesFrom(getCurrentAlignFrame());
1630 * @see jalview.bin.JalviewLiteJsApi#getSelectedSequences(java.lang.String)
1633 public String getSelectedSequences(String sep)
1635 return getSelectedSequencesFrom(getCurrentAlignFrame(), sep);
1640 * @see jalview.bin.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
1644 public String getSelectedSequencesFrom(AlignFrameI alf)
1646 return getSelectedSequencesFrom(alf, null);
1651 * @see jalview.bin.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
1652 * .AlignFrame, java.lang.String)
1655 public String getSelectedSequencesFrom(AlignFrameI alf, String sep)
1657 return appLoader.getSelectedSequencesFrom(alf, sep);
1662 * @see jalview.bin.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
1663 * .AlignFrame, java.lang.String)
1666 public void highlight(String sequenceId, String position,
1667 String alignedPosition)
1669 highlightIn(getCurrentAlignFrame(), sequenceId, position,
1674 public void highlightIn(AlignFrameI alf, String sequenceId,
1675 String position, String alignedPosition)
1677 appLoader.highlightIn(alf, sequenceId, position, alignedPosition);
1681 public void select(String sequenceIds, String columns)
1683 selectIn(getCurrentAlignFrame(), sequenceIds, columns, null);
1687 public void select(String sequenceIds, String columns, String sep)
1689 selectIn(getCurrentAlignFrame(), sequenceIds, columns, sep);
1693 public void selectIn(AlignFrameI alf, String sequenceIds, String columns)
1695 selectIn(alf, sequenceIds, columns, null);
1699 public void selectIn(AlignFrameI alf, String sequenceIds, String columns,
1702 appLoader.selectIn(alf, sequenceIds, columns, sep);
1706 public String getSelectedSequencesAsAlignment(String format,
1709 return getSelectedSequencesAsAlignmentFrom(getCurrentAlignFrame(),
1714 public String getSelectedSequencesAsAlignmentFrom(AlignFrameI alf,
1715 String format, String sep)
1717 return appLoader.getSelectedSequencesAsAlignmentFrom(alf, format, sep);
1721 public String getAlignmentOrder()
1723 return getAlignmentFrom(getCurrentAlignFrame(), null);
1727 public String getAlignmentOrderFrom(AlignFrameI alf)
1729 return getAlignmentFrom(alf, null);
1733 public String getAlignmentOrderFrom(AlignFrameI alf, String sep)
1735 return appLoader.getAlignmentOrderFrom(alf, sep);
1739 public String orderBy(String order, String undoName)
1741 return orderBy(order, undoName, null);
1745 public String orderBy(String order, String undoName, String sep)
1747 return orderAlignmentBy(getCurrentAlignFrame(), order, undoName, sep);
1751 public String orderAlignmentBy(AlignFrameI alf, String order,
1752 String undoName, String sep)
1754 return appLoader.orderAlignmentBy(alf, order, undoName, sep);
1758 public String getAlignment(String format)
1760 return getAlignmentFrom(null, format, null);
1764 public String getAlignmentFrom(AlignFrameI alf, String format)
1766 return getAlignmentFrom(alf, format, null);
1770 public String getAlignment(String format, String suffix)
1772 return getAlignmentFrom(getCurrentAlignFrame(), format, suffix);
1776 public String getAlignmentFrom(AlignFrameI alf, String format,
1779 return appLoader.getAlignmentFrom(alf, format, suffix);
1783 public void loadAnnotation(String annotation)
1785 loadAnnotationFrom(getCurrentAlignFrame(), annotation);
1789 public void loadAnnotationFrom(AlignFrameI alf, String annotation)
1791 appLoader.loadAnnotationFrom(alf, annotation);
1795 public void loadFeatures(String features, boolean autoenabledisplay)
1797 loadFeaturesFrom(currentAlignFrame, features, autoenabledisplay);
1801 public boolean loadFeaturesFrom(AlignFrameI alf, String features,
1802 boolean autoenabledisplay)
1804 return appLoader.loadFeaturesFrom(alf, features, autoenabledisplay);
1808 public String getFeatures(String format)
1810 return getFeaturesFrom(getCurrentAlignFrame(), format);
1814 public String getFeaturesFrom(AlignFrameI alf, String format)
1816 return appLoader.getFeaturesFrom(alf, format);
1820 public String getAnnotation()
1822 return getAnnotationFrom(getCurrentAlignFrame());
1826 public String getAnnotationFrom(AlignFrameI alf)
1828 return appLoader.getAnnotationFrom(alf);
1832 public AlignFrameI newView()
1834 return newViewFrom(getCurrentAlignFrame(), null);
1838 public AlignFrameI newView(String name)
1840 return newViewFrom(getCurrentAlignFrame(), name);
1844 public AlignFrameI newViewFrom(AlignFrameI alf)
1846 return newViewFrom(alf, null);
1850 public AlignFrameI newViewFrom(AlignFrameI alf, String name)
1852 return appLoader.newViewFrom(alf, name);
1856 public AlignFrameI loadAlignment(String text, String title)
1858 return appLoader.loadAlignment(text, AlignFrame.DEFAULT_WIDTH,
1859 AlignFrame.DEFAULT_HEIGHT, title);
1863 public boolean addPdbFile(AlignFrameI alFrame, String sequenceId,
1864 String pdbEntryString, String pdbFile)
1866 return appLoader.addPdbFile(alFrame, sequenceId, pdbEntryString,
1871 public void scrollViewToIn(AlignFrameI alf, String topRow,
1872 String leftHandColumn)
1874 appLoader.scrollViewToIn(alf, topRow, leftHandColumn);
1878 public void scrollViewToRowIn(AlignFrameI alf, String topRow)
1880 appLoader.scrollViewToRowIn(alf, topRow);
1884 public void scrollViewToColumnIn(AlignFrameI alf, String leftHandColumn)
1886 appLoader.scrollViewToColumnIn(alf, leftHandColumn);
1890 public String getFeatureGroups()
1892 return getFeatureGroupsOn(getCurrentAlignFrame());
1896 public String getFeatureGroupsOn(AlignFrameI alf)
1898 return appLoader.getFeatureGroupsOn(alf);
1902 public String getFeatureGroupsOfState(boolean visible)
1904 return getFeatureGroupsOfStateOn(getCurrentAlignFrame(), visible);
1908 public String getFeatureGroupsOfStateOn(AlignFrameI alf, boolean visible)
1910 return appLoader.getFeatureGroupsOfStateOn(alf, visible);
1914 public void setFeatureGroupStateOn(AlignFrameI alf, String groups,
1917 setFeatureGroupStateOn(alf, groups, state);
1921 public void setFeatureGroupState(String groups, boolean state)
1923 appLoader.setFeatureGroupStateOn(getCurrentAlignFrame(), groups, state);
1927 public String getSeparator()
1929 return appLoader.getSeparator();
1933 public void setSeparator(String separator)
1935 appLoader.setSeparator(separator);
1939 public String getJsMessage(String messageclass, String viewId)
1941 // see http://www.jalview.org/examples/jalviewLiteJs.html
1946 * Open a new Tree panel on the desktop statically. Params are standard (not
1947 * set by Groovy). No dialog is opened.
1952 * @return null, or the string "label.you_need_at_least_n_sequences" if number
1953 * of sequences selected is inappropriate
1956 public Object openTreePanel(AlignFrame af, String treeType,
1959 return CalculationChooser.openTreePanel(af, treeType, modelName, null);
1963 * public static method for JalviewJS API to open a PCAPanel without
1964 * necessarily using a dialog.
1968 * @return the PCAPanel, or the string "label.you_need_at_least_n_sequences"
1969 * if number of sequences selected is inappropriate
1972 public Object openPcaPanel(AlignFrame af, String modelName)
1974 return CalculationChooser.openPcaPanel(af, modelName, null);
1978 public String getSelectedSequencesAsAlignment(String format,
1981 return getSelectedSequencesAsAlignmentFrom(getCurrentAlignFrame(),
1986 public String getSelectedSequencesAsAlignmentFrom(AlignFrameI alf,
1987 String format, boolean suffix)
1989 return appLoader.getSelectedSequencesAsAlignmentFrom(alf, format,
1994 public String arrayToSeparatorList(String[] array)
1996 return appLoader.arrayToSeparatorList(array);
2000 public String[] separatorListToArray(String list)
2002 return appLoader.separatorListToArray(list);
2005 //// probably not needed in JalviewJS -- From when Jmol and Jalview did not
2006 //// have a direct connection?
2009 public void setMouseoverListener(String listener)
2011 // TODO Auto-generated method stub
2016 public void setMouseoverListener(AlignFrameI af, String listener)
2018 // TODO Auto-generated method stub
2023 public void setSelectionListener(String listener)
2025 // TODO Auto-generated method stub
2030 public void setSelectionListener(AlignFrameI af, String listener)
2032 // TODO Auto-generated method stub
2037 public void setStructureListener(String listener, String modelSet)
2039 // TODO Auto-generated method stub
2044 public void removeJavascriptListener(AlignFrameI af, String listener)
2046 // TODO Auto-generated method stub
2051 public void mouseOverStructure(String pdbResNum, String chain,
2054 // TODO Auto-generated method stub
2059 public void showOverview()
2061 currentAlignFrame.overviewMenuItem_actionPerformed(null);
2064 public void notifyWorker(AlignCalcWorkerI worker, String status)
2066 // System.out.println("Jalview worker " + worker.getClass().getSimpleName()