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);
310 isJavaAppletTag = aparser.isApplet();
313 Preferences.setAppletDefaults();
314 Cache.loadProperties(usrPropsFile); // again, because we
315 // might be changing defaults here?
318 "<Applet> found: " + aparser.getValue("Info.j2sAppletID"));
319 appletResourcePath = aparser.getValue("Info.resourcePath");
328 if (usrPropsFile != null)
331 "CMD [-props " + usrPropsFile + "] executed successfully!");
334 if (aparser.contains("help") || aparser.contains("h"))
339 if (aparser.contains(ArgsParser.NODISPLAY)
340 || aparser.contains(ArgsParser.NOGUI)
341 || aparser.contains(ArgsParser.HEADLESS)
342 || "true".equals(System.getProperty("java.awt.headless")))
349 final String jabawsUrl = aparser.getValue(ArgsParser.JABAWS);
350 if (jabawsUrl != null)
354 Jws2Discoverer.getInstance().setPreferredUrl(jabawsUrl);
356 "CMD [-jabaws " + jabawsUrl + "] executed successfully!");
357 } catch (MalformedURLException e)
360 "Invalid jabaws parameter: " + jabawsUrl + " ignored");
365 // check for property setting
366 String defs = aparser.getValue(ArgsParser.SETPROP);
369 int p = defs.indexOf('=');
372 System.err.println("Ignoring invalid setprop argument : " + defs);
376 System.out.println("Executing setprop argument: " + defs);
379 Cache.setProperty(defs.substring(0, p), defs.substring(p + 1));
382 defs = aparser.getValue(ArgsParser.SETPROP);
384 System.setProperty("http.agent",
385 "Jalview Desktop/" + Cache.getDefault("VERSION", "Unknown"));
389 } catch (NoClassDefFoundError error)
391 error.printStackTrace();
392 System.out.println("\nEssential logging libraries not found."
393 + "\nUse: java -classpath \"$PATH_TO_LIB$/*:$PATH_TO_CLASSES$\" jalview.bin.Jalview");
401 if (Platform.isWin())
403 UIManager.setLookAndFeel(
404 headless ? "javax.swing.plaf.metal.MetalLookAndFeel"
405 : UIManager.getSystemLookAndFeelClassName());
406 // UIManager.setLookAndFeel(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())
625 System.out.println("Can't find " + file);
634 protocol = AppletFormatAdapter.checkProtocol(file);
638 format = (isJavaAppletTag && fileFormat != null
639 ? FileFormats.getInstance().forName(fileFormat)
643 format = new IdentifyFile().identify(file, protocol);
645 } catch (FileFormatException e1)
650 if (aparser.contains(ArgsParser.NOMENUBAR))
653 System.out.println("CMD [nomenu] executed successfully!");
656 if (aparser.contains(ArgsParser.NOSTATUS))
659 System.out.println("CMD [nostatus] executed successfully!");
662 if (aparser.contains(ArgsParser.NOANNOTATION)
663 || aparser.contains(ArgsParser.NOANNOTATION2))
666 System.out.println("CMD no-annotation executed successfully!");
668 if (aparser.contains(ArgsParser.NOCALCULATION))
670 noCalculation = true;
671 System.out.println("CMD [nocalculation] executed successfully!");
674 AlignFrame af = new FileLoader(!headless).loadFileWaitTillLoaded(file,
678 System.out.println("error");
683 .println("CMD [-open " + file + "] executed successfully!");
686 protocol = AppletFormatAdapter.checkProtocol(file2);
689 format = new IdentifyFile().identify(file2, protocol);
690 } catch (FileFormatException e1)
694 AlignFrame af2 = new FileLoader(!headless)
695 .loadFileWaitTillLoaded(file2, protocol, format);
698 System.out.println("error");
702 AlignViewport.openLinkedAlignmentAs(af,
703 af.getViewport().getAlignment(),
704 af2.getViewport().getAlignment(), "",
705 AlignViewport.SPLIT_FRAME);
707 "CMD [-open2 " + file2 + "] executed successfully!");
711 setCurrentAlignFrame(af);
713 // TODO: file2 How to implement file2 for the applet spit screen?
715 data = aparser.getValue(ArgsParser.COLOUR, true);
718 data.replaceAll("%20", " ");
720 ColourSchemeI cs = ColourSchemeProperty.getColourScheme(
721 af.getViewport(), af.getViewport().getAlignment(), data);
726 "CMD [-color " + data + "] executed successfully!");
731 // Must maintain ability to use the groups flag
732 data = aparser.getValue(ArgsParser.GROUPS, true);
735 af.parseFeaturesFile(data,
736 AppletFormatAdapter.checkProtocol(data));
737 // System.out.println("Added " + data);
739 "CMD groups[-" + data + "] executed successfully!");
741 data = aparser.getValue(ArgsParser.FEATURES, true);
744 af.parseFeaturesFile(data,
745 AppletFormatAdapter.checkProtocol(data));
746 // System.out.println("Added " + data);
748 "CMD [-features " + data + "] executed successfully!");
751 data = aparser.getValue(ArgsParser.ANNOTATIONS, true);
754 af.loadJalviewDataFile(data, null, null, null);
755 // System.out.println("Added " + data);
757 "CMD [-annotations " + data + "] executed successfully!");
760 if (aparser.contains(ArgsParser.SHOWOVERVIEW))
762 af.overviewMenuItem_actionPerformed(null);
763 System.out.println("CMD [showoverview] executed successfully!");
766 // set or clear the sortbytree flag.
767 if (aparser.contains(ArgsParser.SORTBYTREE))
769 af.getViewport().setSortByTree(true);
770 if (af.getViewport().getSortByTree())
772 System.out.println("CMD [-sortbytree] executed successfully!");
776 boolean doUpdateAnnotation = false;
779 * we do this earlier in JalviewJS because of a complication with
782 * For now, just fixing this in JalviewJS.
789 if (aparser.contains(ArgsParser.NOANNOTATION)
790 || aparser.contains(ArgsParser.NOANNOTATION2))
792 af.getViewport().setShowAnnotation(false);
793 if (!af.getViewport().isShowAnnotation())
795 doUpdateAnnotation = true;
797 .println("CMD no-annotation executed successfully!");
801 if (aparser.contains(ArgsParser.NOSORTBYTREE))
803 af.getViewport().setSortByTree(false);
804 if (!af.getViewport().getSortByTree())
806 doUpdateAnnotation = true;
808 .println("CMD [-nosortbytree] executed successfully!");
811 if (doUpdateAnnotation)
813 af.setMenusForViewport();
814 af.alignPanel.updateLayout();
816 data = aparser.getValue(ArgsParser.TREE, true);
822 "CMD [-tree " + data + "] executed successfully!");
823 NewickFile nf = new NewickFile(data,
824 AppletFormatAdapter.checkProtocol(data));
826 .setCurrentTree(af.showNewickTree(nf, data).getTree());
827 } catch (IOException ex)
829 System.err.println("Couldn't add tree " + data);
830 ex.printStackTrace(System.err);
833 // TODO - load PDB structure(s) to alignment JAL-629
834 // (associate with identical sequence in alignment, or a specified
838 loadAppletParams(aparser, af);
847 if (groovyscript != null)
849 // Execute the groovy script after we've done all the rendering
851 // and before any images or figures are generated.
852 System.out.println("Executing script " + groovyscript);
853 executeGroovyScript(groovyscript, af);
854 System.out.println("CMD groovy[" + groovyscript
855 + "] executed successfully!");
858 checkOutputFile(aparser, af, format);
859 while (aparser.getSize() > 0)
861 System.out.println("Unknown arg: " + aparser.nextValue());
866 AlignFrame startUpAlframe = null;
867 // We'll only open the default file if the desktop is visible.
869 // ////////////////////
871 if (!isJS && !headless && file == null && !haveImport
872 && jalview.bin.Cache.getDefault("SHOW_STARTUP_FILE", true))
879 file = jalview.bin.Cache.getDefault("STARTUP_FILE",
880 jalview.bin.Cache.getDefault("www.jalview.org",
881 "http://www.jalview.org")
882 + "/examples/exampleFile_2_7.jar");
884 "http://www.jalview.org/examples/exampleFile_2_3.jar"))
886 // hardwire upgrade of the startup file
887 file.replace("_2_3.jar", "_2_7.jar");
888 // and remove the stale setting
889 jalview.bin.Cache.removeProperty("STARTUP_FILE");
892 protocol = DataSourceType.FILE;
894 if (file.indexOf("http:") > -1)
896 protocol = DataSourceType.URL;
899 if (file.endsWith(".jar"))
901 format = FileFormat.Jalview;
907 format = new IdentifyFile().identify(file, protocol);
908 } catch (FileFormatException e)
914 startUpAlframe = new FileLoader(!headless)
915 .loadFileWaitTillLoaded(file, protocol, format);
916 // extract groovy arguments before anything else.
919 // Once all other stuff is done, execute any groovy scripts (in order)
920 if (groovyscript != null)
922 if (Cache.groovyJarsPresent())
924 System.out.println("Executing script " + groovyscript);
925 executeGroovyScript(groovyscript, startUpAlframe);
930 "Sorry. Groovy Support is not available, so ignoring the provided groovy script "
934 // and finally, turn off batch mode indicator - if the desktop still exists
939 desktop.setProgressBar(null, progress);
941 desktop.setInBatchMode(false);
947 private boolean checkStartVamas(ArgsParser aparser)
949 String vamsasImport = aparser.getValue(ArgsParser.VDOC);
950 String vamsasSession = aparser.getValue(ArgsParser.VSESS);
951 if (vamsasImport == null && vamsasSession == null)
955 if (desktop == null || headless)
958 "Headless vamsas sessions not yet supported. Sorry.");
961 boolean haveImport = (vamsasImport != null);
964 // if we have a file, start a new session and import it.
965 boolean inSession = false;
968 DataSourceType viprotocol = AppletFormatAdapter
969 .checkProtocol(vamsasImport);
970 if (viprotocol == DataSourceType.FILE)
972 inSession = desktop.vamsasImport(new File(vamsasImport));
974 else if (viprotocol == DataSourceType.URL)
976 inSession = desktop.vamsasImport(new URL(vamsasImport));
979 } catch (Exception e)
981 System.err.println("Exeption when importing " + vamsasImport
982 + " as a vamsas document.");
987 System.err.println("Failed to import " + vamsasImport
988 + " as a vamsas document.");
992 System.out.println("Imported Successfully into new session "
993 + desktop.getVamsasApplication().getCurrentSession());
996 if (vamsasSession != null)
998 if (vamsasImport != null)
1000 // close the newly imported session and import the Jalview specific
1001 // remnants into the new session later on.
1002 desktop.vamsasStop_actionPerformed(null);
1004 // now join the new session
1007 if (desktop.joinVamsasSession(vamsasSession))
1010 "Successfully joined vamsas session " + vamsasSession);
1014 System.err.println("WARNING: Failed to join vamsas session "
1017 } catch (Exception e)
1020 "ERROR: Failed to join vamsas session " + vamsasSession);
1021 e.printStackTrace();
1023 if (vamsasImport != null)
1025 // the Jalview specific remnants can now be imported into the new
1026 // session at the user's leisure.
1028 "Skipping Push for import of data into existing vamsas session.");
1034 // desktop.getVamsasApplication().push_update();
1040 private void checkOutputFile(ArgsParser aparser, AlignFrame af,
1043 String imageName = "unnamed.png";
1044 while (aparser.getSize() > 1)
1049 // biojsmsa filename
1050 String outputFormat = aparser.nextValue();
1051 String file = aparser.nextValue();
1052 if (outputFormat.equalsIgnoreCase("png"))
1054 af.createPNG(new File(file));
1055 imageName = (new File(file)).getName();
1056 System.out.println("Creating PNG image: " + file);
1059 else if (outputFormat.equalsIgnoreCase("svg"))
1061 File imageFile = new File(file);
1062 imageName = imageFile.getName();
1063 af.createSVG(imageFile);
1064 System.out.println("Creating SVG image: " + file);
1067 else if (outputFormat.equalsIgnoreCase("html"))
1069 File imageFile = new File(file);
1070 imageName = imageFile.getName();
1071 HtmlSvgOutput htmlSVG = new HtmlSvgOutput(af.alignPanel);
1072 htmlSVG.exportHTML(file);
1074 System.out.println("Creating HTML image: " + file);
1077 else if (outputFormat.equalsIgnoreCase("biojsmsa"))
1081 System.err.println("The output html file must not be null");
1086 BioJsHTMLOutput.refreshVersionInfo(
1087 BioJsHTMLOutput.BJS_TEMPLATES_LOCAL_DIRECTORY);
1088 } catch (URISyntaxException e)
1090 e.printStackTrace();
1092 BioJsHTMLOutput bjs = new BioJsHTMLOutput(af.alignPanel);
1093 bjs.exportHTML(file);
1094 System.out.println("Creating BioJS MSA Viwer HTML file: " + file);
1097 else if (outputFormat.equalsIgnoreCase("imgMap"))
1099 af.createImageMap(new File(file), imageName);
1100 System.out.println("Creating image map: " + file);
1103 else if (outputFormat.equalsIgnoreCase("eps"))
1105 File outputFile = new File(file);
1107 "Creating EPS file: " + outputFile.getAbsolutePath());
1108 af.createEPS(outputFile);
1112 af.saveAlignment(file, format);
1113 if (af.isSaveAlignmentSuccessful())
1116 "Written alignment in " + format + " format to " + file);
1120 System.out.println("Error writing file " + file + " in " + format
1127 private static void showUsage()
1130 "Usage: jalview -open [FILE] [OUTPUT_FORMAT] [OUTPUT_FILE]\n\n"
1131 + "-nodisplay\tRun Jalview without User Interface.\n"
1132 + "-props FILE\tUse the given Jalview properties file instead of users default.\n"
1133 + "-colour COLOURSCHEME\tThe colourscheme to be applied to the alignment\n"
1134 + "-annotations FILE\tAdd precalculated annotations to the alignment.\n"
1135 + "-tree FILE\tLoad the given newick format tree file onto the alignment\n"
1136 + "-features FILE\tUse the given file to mark features on the alignment.\n"
1137 + "-fasta FILE\tCreate alignment file FILE in Fasta format.\n"
1138 + "-clustal FILE\tCreate alignment file FILE in Clustal format.\n"
1139 + "-pfam FILE\tCreate alignment file FILE in PFAM format.\n"
1140 + "-msf FILE\tCreate alignment file FILE in MSF format.\n"
1141 + "-pileup FILE\tCreate alignment file FILE in Pileup format\n"
1142 + "-pir FILE\tCreate alignment file FILE in PIR format.\n"
1143 + "-blc FILE\tCreate alignment file FILE in BLC format.\n"
1144 + "-json FILE\tCreate alignment file FILE in JSON format.\n"
1145 + "-jalview FILE\tCreate alignment file FILE in Jalview format.\n"
1146 + "-png FILE\tCreate PNG image FILE from alignment.\n"
1147 + "-svg FILE\tCreate SVG image FILE from alignment.\n"
1148 + "-html FILE\tCreate HTML file from alignment.\n"
1149 + "-biojsMSA FILE\tCreate BioJS MSA Viewer HTML file from alignment.\n"
1150 + "-imgMap FILE\tCreate HTML file FILE with image map of PNG image.\n"
1151 + "-eps FILE\tCreate EPS file FILE from alignment.\n"
1152 + "-questionnaire URL\tQueries the given URL for information about any Jalview user questionnaires.\n"
1153 + "-noquestionnaire\tTurn off questionnaire check.\n"
1154 + "-nonews\tTurn off check for Jalview news.\n"
1155 + "-nousagestats\tTurn off google analytics tracking for this session.\n"
1156 + "-sortbytree OR -nosortbytree\tEnable or disable sorting of the given alignment by the given tree\n"
1158 // "-setprop PROPERTY=VALUE\tSet the given Jalview property,
1159 // after all other properties files have been read\n\t
1160 // (quote the 'PROPERTY=VALUE' pair to ensure spaces are
1161 // passed in correctly)"
1162 + "-jabaws URL\tSpecify URL for Jabaws services (e.g. for a local installation).\n"
1163 + "-fetchfrom nickname\tQuery nickname for features for the alignments and display them.\n"
1165 // "-vdoc vamsas-document\tImport vamsas document into new
1166 // session or join existing session with same URN\n"
1167 // + "-vses vamsas-session\tJoin session with given URN\n"
1168 + "-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"
1169 + "\n~Read documentation in Application or visit http://www.jalview.org for description of Features and Annotations file~\n\n");
1172 private static void startUsageStats(final Desktop desktop)
1175 * start a User Config prompt asking if we can log usage statistics.
1177 PromptUserConfig prompter = new PromptUserConfig(
1178 Desktop.getDesktopPane(), "USAGESTATS",
1179 "Jalview Usage Statistics",
1180 "Do you want to help make Jalview better by enabling "
1181 + "the collection of usage statistics with Google Analytics ?"
1182 + "\n\n(you can enable or disable usage tracking in the preferences)",
1189 "Initialising googletracker for usage stats.");
1190 Cache.initGoogleTracker();
1191 Cache.log.debug("Tracking enabled.");
1198 Cache.log.debug("Not enabling Google Tracking.");
1201 desktop.addDialogThread(prompter);
1205 * Locate the given string as a file and pass it to the groovy interpreter.
1207 * @param groovyscript
1208 * the script to execute
1209 * @param jalviewContext
1210 * the Jalview Desktop object passed in to the groovy binding as the
1213 private void executeGroovyScript(String groovyscript, AlignFrame af)
1216 * for scripts contained in files
1223 if (groovyscript.trim().equals("STDIN"))
1225 // read from stdin into a tempfile and execute it
1228 tfile = File.createTempFile("jalview", "groovy");
1229 PrintWriter outfile = new PrintWriter(
1230 new OutputStreamWriter(new FileOutputStream(tfile)));
1231 BufferedReader br = new BufferedReader(
1232 new InputStreamReader(System.in));
1234 while ((line = br.readLine()) != null)
1236 outfile.write(line + "\n");
1242 } catch (Exception ex)
1244 System.err.println("Failed to read from STDIN into tempfile "
1245 + ((tfile == null) ? "(tempfile wasn't created)"
1246 : tfile.toString()));
1247 ex.printStackTrace();
1252 sfile = tfile.toURI().toURL();
1253 } catch (Exception x)
1256 "Unexpected Malformed URL Exception for temporary file created from STDIN: "
1258 x.printStackTrace();
1266 sfile = new URI(groovyscript).toURL();
1267 } catch (Exception x)
1269 tfile = new File(groovyscript);
1270 if (!tfile.exists())
1272 System.err.println("File '" + groovyscript + "' does not exist.");
1275 if (!tfile.canRead())
1277 System.err.println("File '" + groovyscript + "' cannot be read.");
1280 if (tfile.length() < 1)
1282 System.err.println("File '" + groovyscript + "' is empty.");
1287 sfile = tfile.getAbsoluteFile().toURI().toURL();
1288 } catch (Exception ex)
1290 System.err.println("Failed to create a file URL for "
1291 + tfile.getAbsoluteFile());
1298 Map<String, Object> vbinding = new HashMap<>();
1299 vbinding.put("Jalview", this);
1302 vbinding.put("currentAlFrame", af);
1304 Binding gbinding = new Binding(vbinding);
1305 GroovyScriptEngine gse = new GroovyScriptEngine(new URL[] { sfile });
1306 gse.run(sfile.toString(), gbinding);
1307 if ("STDIN".equals(groovyscript))
1309 // delete temp file that we made -
1310 // only if it was successfully executed
1313 } catch (Exception e)
1315 System.err.println("Exception Whilst trying to execute file " + sfile
1316 + " as a groovy script.");
1317 e.printStackTrace(System.err);
1322 public AlignFrame[] getAlignFrames()
1324 return desktop == null ? new AlignFrame[] { getCurrentAlignFrame() }
1325 : Desktop.getAlignFrames();
1330 * Quit method delegates to Desktop.quit - unless running in headless mode
1331 * when it just ends the JVM
1335 if (jsFunctionExec != null)
1337 jsFunctionExec.tidyUp();
1338 jsFunctionExec = null;
1341 if (desktop != null)
1352 * Get the SwingJS applet ID and combine that with the frameType
1355 * "alignment", "desktop", etc., or null
1358 public static String getAppID(String frameType)
1360 String id = Cache.getProperty("Info.j2sAppletID");
1365 return id + (frameType == null ? "" : "-" + frameType);
1369 * Handle all JalviewLite applet parameters
1374 private void loadAppletParams(ArgsParser aparser, AlignFrame af)
1376 JalviewApp app = new JalviewApp()
1381 // These are methods that are in JalviewLite that various classes call
1382 // but are not in JalviewLiteJsApi. Or, even if they are, other classes
1384 // them to JalviewLite directly. Some may not be necessary, but they have
1386 // be at least mentioned here, or the classes calling them should
1388 // JalviewLite itself.
1390 private boolean alignPDBStructures; // From JalviewLite; not implemented
1392 private Hashtable<String, Hashtable<String, String[]>> jsmessages;
1394 private Hashtable<String, int[]> jshashes;
1397 public String getParameter(String name)
1399 return aparser.getAppletValue(name, null);
1403 public boolean getDefaultParameter(String name, boolean def)
1406 return ((stn = getParameter(name)) == null ? def
1407 : "true".equalsIgnoreCase(stn));
1411 * Get the applet-like document base even though this is an application.
1414 public URL getDocumentBase()
1416 return Platform.getDocumentBase();
1420 * Get the applet-like code base even though this is an application.
1423 public URL getCodeBase()
1425 return Platform.getCodeBase();
1429 public AlignViewportI getViewport()
1431 return af.getViewport();
1439 public boolean parseFeaturesFile(String filename,
1440 DataSourceType protocol)
1442 return af.parseFeaturesFile(filename, protocol);
1450 public boolean loadScoreFile(String sScoreFile) throws IOException
1452 af.loadJalviewDataFile(sScoreFile, null, null, null);
1457 * annotations, jpredfile, jnetfile
1461 public void updateForAnnotations()
1463 af.updateForAnnotations();
1467 public void loadTree(NewickFile fin, String treeFile)
1470 // n/a -- already done by standard Jalview command line processing
1474 public void setAlignPdbStructures(boolean defaultParameter)
1476 alignPDBStructures = true;
1480 public void newStructureView(PDBEntry pdb, SequenceI[] seqs,
1481 String[] chains, DataSourceType protocol)
1483 StructureViewer.launchStructureViewer(af.alignPanel, pdb, seqs);
1487 public void setFeatureGroupState(String[] groups, boolean state)
1489 af.setFeatureGroupState(groups, state);
1493 public void alignedStructureView(PDBEntry[] pdb, SequenceI[][] seqs,
1494 String[][] chains, String[] protocols)
1497 "Jalview applet interface alignedStructureView not implemented");
1501 public void newFeatureSettings()
1504 "Jalview applet interface newFeatureSettings not implemented");
1507 private Vector<Runnable> jsExecQueue;
1510 public Vector<Runnable> getJsExecQueue(JSFunctionExec exec)
1512 jsFunctionExec = exec;
1513 return (jsExecQueue == null ? (jsExecQueue = new Vector<>())
1518 public AppletContext getAppletContext()
1520 // TODO Auto-generated method stub
1525 public boolean isJsfallbackEnabled()
1527 // TODO Auto-generated method stub
1532 public JSObject getJSObject()
1534 // TODO Auto-generated method stub
1539 public StructureSelectionManagerProvider getStructureSelectionManagerProvider()
1541 // TODO Q: what exactly is this? BH
1546 public void updateColoursFromMouseOver(Object source,
1547 MouseOverStructureListener mouseOverStructureListener)
1549 // TODO Auto-generated method stub
1554 public Object[] getSelectionForListener(SequenceGroup seqsel,
1555 ColumnSelection colsel, HiddenColumns hidden,
1556 SelectionSource source, Object alignFrame)
1558 return appLoader.getSelectionForListener(getCurrentAlignFrame(),
1559 seqsel, colsel, hidden, source, alignFrame);
1563 public String arrayToSeparatorList(String[] array)
1565 return appLoader.arrayToSeparatorList(array);
1569 public Hashtable<String, int[]> getJSHashes()
1571 return (jshashes == null ? (jshashes = new Hashtable<>())
1576 public Hashtable<String, Hashtable<String, String[]>> getJSMessages()
1578 return (jsmessages == null ? (jsmessages = new Hashtable<>())
1583 public Object getFrameForSource(VamsasSource source)
1588 if (source instanceof jalview.gui.AlignViewport
1589 && source == (af = getCurrentAlignFrame()).getViewport())
1591 // should be valid if it just generated an event!
1594 // TODO: ensure that if '_af' is specified along with a handler
1595 // function, then only events from that alignFrame are sent to that
1602 public FeatureRenderer getNewFeatureRenderer(AlignViewportI vp)
1604 return new jalview.gui.FeatureRenderer((AlignmentPanel) vp);
1609 appLoader = new JalviewAppLoader(true);
1610 appLoader.load(app);
1615 * @see jalview.bin.JalviewLiteJsApi#getSelectedSequences()
1618 public String getSelectedSequences()
1620 return getSelectedSequencesFrom(getCurrentAlignFrame());
1625 * @see jalview.bin.JalviewLiteJsApi#getSelectedSequences(java.lang.String)
1628 public String getSelectedSequences(String sep)
1630 return getSelectedSequencesFrom(getCurrentAlignFrame(), sep);
1635 * @see jalview.bin.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
1639 public String getSelectedSequencesFrom(AlignFrameI alf)
1641 return getSelectedSequencesFrom(alf, null);
1646 * @see jalview.bin.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
1647 * .AlignFrame, java.lang.String)
1650 public String getSelectedSequencesFrom(AlignFrameI alf, String sep)
1652 return appLoader.getSelectedSequencesFrom(alf, sep);
1657 * @see jalview.bin.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
1658 * .AlignFrame, java.lang.String)
1661 public void highlight(String sequenceId, String position,
1662 String alignedPosition)
1664 highlightIn(getCurrentAlignFrame(), sequenceId, position,
1669 public void highlightIn(AlignFrameI alf, String sequenceId,
1670 String position, String alignedPosition)
1672 appLoader.highlightIn(alf, sequenceId, position, alignedPosition);
1676 public void select(String sequenceIds, String columns)
1678 selectIn(getCurrentAlignFrame(), sequenceIds, columns, null);
1682 public void select(String sequenceIds, String columns, String sep)
1684 selectIn(getCurrentAlignFrame(), sequenceIds, columns, sep);
1688 public void selectIn(AlignFrameI alf, String sequenceIds, String columns)
1690 selectIn(alf, sequenceIds, columns, null);
1694 public void selectIn(AlignFrameI alf, String sequenceIds, String columns,
1697 appLoader.selectIn(alf, sequenceIds, columns, sep);
1701 public String getSelectedSequencesAsAlignment(String format,
1704 return getSelectedSequencesAsAlignmentFrom(getCurrentAlignFrame(),
1709 public String getSelectedSequencesAsAlignmentFrom(AlignFrameI alf,
1710 String format, String sep)
1712 return appLoader.getSelectedSequencesAsAlignmentFrom(alf, format, sep);
1716 public String getAlignmentOrder()
1718 return getAlignmentFrom(getCurrentAlignFrame(), null);
1722 public String getAlignmentOrderFrom(AlignFrameI alf)
1724 return getAlignmentFrom(alf, null);
1728 public String getAlignmentOrderFrom(AlignFrameI alf, String sep)
1730 return appLoader.getAlignmentOrderFrom(alf, sep);
1734 public String orderBy(String order, String undoName)
1736 return orderBy(order, undoName, null);
1740 public String orderBy(String order, String undoName, String sep)
1742 return orderAlignmentBy(getCurrentAlignFrame(), order, undoName, sep);
1746 public String orderAlignmentBy(AlignFrameI alf, String order,
1747 String undoName, String sep)
1749 return appLoader.orderAlignmentBy(alf, order, undoName, sep);
1753 public String getAlignment(String format)
1755 return getAlignmentFrom(null, format, null);
1759 public String getAlignmentFrom(AlignFrameI alf, String format)
1761 return getAlignmentFrom(alf, format, null);
1765 public String getAlignment(String format, String suffix)
1767 return getAlignmentFrom(getCurrentAlignFrame(), format, suffix);
1771 public String getAlignmentFrom(AlignFrameI alf, String format,
1774 return appLoader.getAlignmentFrom(alf, format, suffix);
1778 public void loadAnnotation(String annotation)
1780 loadAnnotationFrom(getCurrentAlignFrame(), annotation);
1784 public void loadAnnotationFrom(AlignFrameI alf, String annotation)
1786 appLoader.loadAnnotationFrom(alf, annotation);
1790 public void loadFeatures(String features, boolean autoenabledisplay)
1792 loadFeaturesFrom(currentAlignFrame, features, autoenabledisplay);
1796 public boolean loadFeaturesFrom(AlignFrameI alf, String features,
1797 boolean autoenabledisplay)
1799 return appLoader.loadFeaturesFrom(alf, features, autoenabledisplay);
1803 public String getFeatures(String format)
1805 return getFeaturesFrom(getCurrentAlignFrame(), format);
1809 public String getFeaturesFrom(AlignFrameI alf, String format)
1811 return appLoader.getFeaturesFrom(alf, format);
1815 public String getAnnotation()
1817 return getAnnotationFrom(getCurrentAlignFrame());
1821 public String getAnnotationFrom(AlignFrameI alf)
1823 return appLoader.getAnnotationFrom(alf);
1827 public AlignFrameI newView()
1829 return newViewFrom(getCurrentAlignFrame(), null);
1833 public AlignFrameI newView(String name)
1835 return newViewFrom(getCurrentAlignFrame(), name);
1839 public AlignFrameI newViewFrom(AlignFrameI alf)
1841 return newViewFrom(alf, null);
1845 public AlignFrameI newViewFrom(AlignFrameI alf, String name)
1847 return appLoader.newViewFrom(alf, name);
1851 public AlignFrameI loadAlignment(String text, String title)
1853 return appLoader.loadAlignment(text, AlignFrame.DEFAULT_WIDTH,
1854 AlignFrame.DEFAULT_HEIGHT, title);
1858 public boolean addPdbFile(AlignFrameI alFrame, String sequenceId,
1859 String pdbEntryString, String pdbFile)
1861 return appLoader.addPdbFile(alFrame, sequenceId, pdbEntryString,
1866 public void scrollViewToIn(AlignFrameI alf, String topRow,
1867 String leftHandColumn)
1869 appLoader.scrollViewToIn(alf, topRow, leftHandColumn);
1873 public void scrollViewToRowIn(AlignFrameI alf, String topRow)
1875 appLoader.scrollViewToRowIn(alf, topRow);
1879 public void scrollViewToColumnIn(AlignFrameI alf, String leftHandColumn)
1881 appLoader.scrollViewToColumnIn(alf, leftHandColumn);
1885 public String getFeatureGroups()
1887 return getFeatureGroupsOn(getCurrentAlignFrame());
1891 public String getFeatureGroupsOn(AlignFrameI alf)
1893 return appLoader.getFeatureGroupsOn(alf);
1897 public String getFeatureGroupsOfState(boolean visible)
1899 return getFeatureGroupsOfStateOn(getCurrentAlignFrame(), visible);
1903 public String getFeatureGroupsOfStateOn(AlignFrameI alf, boolean visible)
1905 return appLoader.getFeatureGroupsOfStateOn(alf, visible);
1909 public void setFeatureGroupStateOn(AlignFrameI alf, String groups,
1912 setFeatureGroupStateOn(alf, groups, state);
1916 public void setFeatureGroupState(String groups, boolean state)
1918 appLoader.setFeatureGroupStateOn(getCurrentAlignFrame(), groups, state);
1922 public String getSeparator()
1924 return appLoader.getSeparator();
1928 public void setSeparator(String separator)
1930 appLoader.setSeparator(separator);
1934 public String getJsMessage(String messageclass, String viewId)
1936 // see http://www.jalview.org/examples/jalviewLiteJs.html
1941 * Open a new Tree panel on the desktop statically. Params are standard (not
1942 * set by Groovy). No dialog is opened.
1947 * @return null, or the string "label.you_need_at_least_n_sequences" if number
1948 * of sequences selected is inappropriate
1951 public Object openTreePanel(AlignFrame af, String treeType,
1954 return CalculationChooser.openTreePanel(af, treeType, modelName, null);
1958 * public static method for JalviewJS API to open a PCAPanel without
1959 * necessarily using a dialog.
1963 * @return the PCAPanel, or the string "label.you_need_at_least_n_sequences"
1964 * if number of sequences selected is inappropriate
1967 public Object openPcaPanel(AlignFrame af, String modelName)
1969 return CalculationChooser.openPcaPanel(af, modelName, null);
1973 public String getSelectedSequencesAsAlignment(String format,
1976 return getSelectedSequencesAsAlignmentFrom(getCurrentAlignFrame(),
1981 public String getSelectedSequencesAsAlignmentFrom(AlignFrameI alf,
1982 String format, boolean suffix)
1984 return appLoader.getSelectedSequencesAsAlignmentFrom(alf, format,
1989 public String arrayToSeparatorList(String[] array)
1991 return appLoader.arrayToSeparatorList(array);
1995 public String[] separatorListToArray(String list)
1997 return appLoader.separatorListToArray(list);
2000 //// probably not needed in JalviewJS -- From when Jmol and Jalview did not
2001 //// have a direct connection?
2004 public void setMouseoverListener(String listener)
2006 // TODO Auto-generated method stub
2011 public void setMouseoverListener(AlignFrameI af, String listener)
2013 // TODO Auto-generated method stub
2018 public void setSelectionListener(String listener)
2020 // TODO Auto-generated method stub
2025 public void setSelectionListener(AlignFrameI af, String listener)
2027 // TODO Auto-generated method stub
2032 public void setStructureListener(String listener, String modelSet)
2034 // TODO Auto-generated method stub
2039 public void removeJavascriptListener(AlignFrameI af, String listener)
2041 // TODO Auto-generated method stub
2046 public void mouseOverStructure(String pdbResNum, String chain,
2049 // TODO Auto-generated method stub
2054 public void showOverview()
2056 currentAlignFrame.overviewMenuItem_actionPerformed(null);
2059 public void notifyWorker(AlignCalcWorkerI worker, String status)
2061 // System.out.println("Jalview worker " + worker.getClass().getSimpleName()