2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
23 import jalview.api.AlignFrameI;
24 import jalview.api.AlignViewportI;
25 import jalview.api.JalviewApp;
26 import jalview.api.StructureSelectionManagerProvider;
27 import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
28 import jalview.datamodel.ColumnSelection;
29 import jalview.datamodel.HiddenColumns;
30 import jalview.datamodel.PDBEntry;
31 import jalview.datamodel.SequenceGroup;
32 import jalview.datamodel.SequenceI;
33 import jalview.ext.so.SequenceOntology;
34 import jalview.gui.AlignFrame;
35 import jalview.gui.AlignViewport;
36 import jalview.gui.AlignmentPanel;
37 import jalview.gui.CalculationChooser;
38 import jalview.gui.Desktop;
39 import jalview.gui.Preferences;
40 import jalview.gui.PromptUserConfig;
41 import jalview.gui.StructureViewer;
42 import jalview.io.AppletFormatAdapter;
43 import jalview.io.BioJsHTMLOutput;
44 import jalview.io.DataSourceType;
45 import jalview.io.FileFormat;
46 import jalview.io.FileFormatException;
47 import jalview.io.FileFormatI;
48 import jalview.io.FileFormats;
49 import jalview.io.FileLoader;
50 import jalview.io.HtmlSvgOutput;
51 import jalview.io.IdentifyFile;
52 import jalview.io.NewickFile;
53 import jalview.io.gff.SequenceOntologyFactory;
54 import jalview.javascript.JSFunctionExec;
55 import jalview.javascript.MouseOverStructureListener;
56 import jalview.renderer.seqfeatures.FeatureRenderer;
57 import jalview.schemes.ColourSchemeI;
58 import jalview.schemes.ColourSchemeProperty;
59 import jalview.structure.SelectionSource;
60 import jalview.structure.VamsasSource;
61 import jalview.util.MessageManager;
62 import jalview.util.Platform;
63 import jalview.ws.jws2.Jws2Discoverer;
65 import java.applet.AppletContext;
66 import java.io.BufferedReader;
68 import java.io.FileOutputStream;
69 import java.io.IOException;
70 import java.io.InputStreamReader;
71 import java.io.OutputStreamWriter;
72 import java.io.PrintWriter;
73 import java.net.MalformedURLException;
75 import java.net.URISyntaxException;
77 import java.security.AllPermission;
78 import java.security.CodeSource;
79 import java.security.PermissionCollection;
80 import java.security.Permissions;
81 import java.security.Policy;
82 import java.util.HashMap;
83 import java.util.Hashtable;
85 import java.util.Vector;
86 import java.util.logging.ConsoleHandler;
87 import java.util.logging.Level;
88 import java.util.logging.Logger;
90 import javax.swing.LookAndFeel;
91 import javax.swing.UIManager;
93 import groovy.lang.Binding;
94 import groovy.util.GroovyScriptEngine;
95 import netscape.javascript.JSObject;
98 * Main class for Jalview Application <br>
100 * start with: java -classpath "$PATH_TO_LIB$/*:$PATH_TO_CLASSES$" \
101 * jalview.bin.Jalview
103 * or on Windows: java -classpath "$PATH_TO_LIB$/*;$PATH_TO_CLASSES$" \
104 * jalview.bin.Jalview jalview.bin.Jalview
106 * (ensure -classpath arg is quoted to avoid shell expansion of '*' and do not
107 * embellish '*' to e.g. '*.jar')
110 * @version $Revision$
112 public class Jalview implements ApplicationSingletonI, JalviewJSApi
115 public static Jalview getInstance()
117 return (Jalview) ApplicationSingletonProvider
118 .getInstance(Jalview.class);
127 Platform.getURLCommandArguments();
130 private boolean headless;
132 public static boolean isHeadlessMode()
134 return getInstance().headless;
137 private Desktop desktop;
139 private AlignFrame currentAlignFrame;
141 public boolean isJavaAppletTag;
143 public String appletResourcePath;
145 JalviewAppLoader appLoader;
147 protected JSFunctionExec jsFunctionExec;
149 private boolean noCalculation, noMenuBar, noStatus;
151 public boolean getStartCalculations()
153 return !noCalculation;
156 public boolean getAllowMenuBar()
161 public boolean getShowStatus()
167 public static AlignFrame getCurrentAlignFrame()
169 return getInstance().currentAlignFrame;
172 public static void setCurrentAlignFrame(AlignFrame currentAlignFrame)
174 getInstance().currentAlignFrame = currentAlignFrame;
179 if (!Platform.isJS())
186 // grab all the rights we can for the JVM
187 Policy.setPolicy(new Policy()
190 public PermissionCollection getPermissions(CodeSource codesource)
192 Permissions perms = new Permissions();
193 perms.add(new AllPermission());
198 public void refresh()
206 * keep track of feature fetching tasks.
214 * TODO: generalise to track all jalview events to orchestrate batch
218 private int queued = 0;
220 private int running = 0;
222 public FeatureFetcher()
227 public void addFetcher(final AlignFrame af,
228 final Vector<String> dasSources)
230 final long id = System.currentTimeMillis();
232 final FeatureFetcher us = this;
233 new Thread(new Runnable()
245 af.setProgressBar(MessageManager
246 .getString("status.das_features_being_retrived"), id);
247 af.featureSettings_actionPerformed(null);
248 af.setProgressBar(null, id);
257 public synchronized boolean allFinished()
259 return queued == 0 && running == 0;
265 * main class for Jalview application
268 * open <em>filename</em>
270 public static void main(String[] args)
272 // setLogging(); // BH - for event debugging in JavaScript
273 getInstance().doMain(args);
277 private static void logClass(String name)
279 // BH - for event debugging in JavaScript
280 ConsoleHandler consoleHandler = new ConsoleHandler();
281 consoleHandler.setLevel(Level.ALL);
282 Logger logger = Logger.getLogger(name);
283 logger.setLevel(Level.ALL);
284 logger.addHandler(consoleHandler);
287 @SuppressWarnings("unused")
288 private static void setLogging()
296 System.out.println("not in js");
299 // BH - for event debugging in JavaScript (Java mode only)
300 if (!Platform.isJS())
307 Logger.getLogger("").setLevel(Level.ALL);
308 logClass("java.awt.EventDispatchThread");
309 logClass("java.awt.EventQueue");
310 logClass("java.awt.Component");
311 logClass("java.awt.focus.Component");
312 logClass("java.awt.focus.DefaultKeyboardFocusManager");
320 void doMain(String[] args)
323 boolean isJS = Platform.isJS();
326 System.setSecurityManager(null);
330 .println("Java version: " + System.getProperty("java.version"));
331 System.out.println(System.getProperty("os.arch") + " "
332 + System.getProperty("os.name") + " "
333 + System.getProperty("os.version"));
335 ArgsParser aparser = new ArgsParser(args);
337 String usrPropsFile = aparser.getValue(ArgsParser.PROPS);
338 Cache.loadProperties(usrPropsFile);
341 isJavaAppletTag = aparser.isApplet();
344 Preferences.setAppletDefaults();
345 Cache.loadProperties(usrPropsFile); // again, because we
346 // might be changing defaults here?
349 "<Applet> found: " + aparser.getValue("Info.j2sAppletID"));
350 appletResourcePath = aparser.getValue("Info.resourcePath");
359 if (usrPropsFile != null)
362 "CMD [-props " + usrPropsFile + "] executed successfully!");
365 if (aparser.contains("help") || aparser.contains("h"))
370 if (aparser.contains(ArgsParser.NODISPLAY)
371 || aparser.contains(ArgsParser.NOGUI)
372 || aparser.contains(ArgsParser.HEADLESS)
373 || "true".equals(System.getProperty("java.awt.headless")))
380 final String jabawsUrl = aparser.getValue(ArgsParser.JABAWS);
381 if (jabawsUrl != null)
385 Jws2Discoverer.getInstance().setPreferredUrl(jabawsUrl);
387 "CMD [-jabaws " + jabawsUrl + "] executed successfully!");
388 } catch (MalformedURLException e)
391 "Invalid jabaws parameter: " + jabawsUrl + " ignored");
396 // check for property setting
397 String defs = aparser.getValue(ArgsParser.SETPROP);
400 int p = defs.indexOf('=');
403 System.err.println("Ignoring invalid setprop argument : " + defs);
407 System.out.println("Executing setprop argument: " + defs);
410 Cache.setProperty(defs.substring(0, p), defs.substring(p + 1));
413 defs = aparser.getValue(ArgsParser.SETPROP);
415 System.setProperty("http.agent",
416 "Jalview Desktop/" + Cache.getDefault("VERSION", "Unknown"));
420 } catch (NoClassDefFoundError error)
422 error.printStackTrace();
423 System.out.println("\nEssential logging libraries not found."
424 + "\nUse: java -classpath \"$PATH_TO_LIB$/*:$PATH_TO_CLASSES$\" jalview.bin.Jalview");
432 UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
433 } catch (Exception ex)
435 System.err.println("Unexpected Look and Feel Exception");
436 ex.printStackTrace();
438 if (Platform.isAMacAndNotJS())
441 LookAndFeel lookAndFeel = ch.randelshofer.quaqua.QuaquaManager
443 System.setProperty("com.apple.mrj.application.apple.menu.about.name",
445 System.setProperty("apple.laf.useScreenMenuBar", "true");
446 if (lookAndFeel != null)
450 UIManager.setLookAndFeel(lookAndFeel);
451 } catch (Throwable e)
454 "Failed to set QuaQua look and feel: " + e.toString());
457 if (lookAndFeel == null
458 || !(lookAndFeel.getClass().isAssignableFrom(
459 UIManager.getLookAndFeel().getClass()))
460 || !UIManager.getLookAndFeel().getClass().toString()
461 .toLowerCase().contains("quaqua"))
466 "Quaqua LaF not available on this plaform. Using VAqua(4).\nSee https://issues.jalview.org/browse/JAL-2976");
467 UIManager.setLookAndFeel("org.violetlib.aqua.AquaLookAndFeel");
468 } catch (Throwable e)
471 "Failed to reset look and feel: " + e.toString());
477 * configure 'full' SO model if preferences say to,
478 * else use the default (SO Lite)
480 if (Cache.getDefault(Preferences.USE_FULL_SO, false))
482 SequenceOntologyFactory.setSequenceOntology(new SequenceOntology());
487 desktop = Desktop.getInstance();
488 desktop.setInBatchMode(true); // indicate we are starting up
489 desktop.setVisible(true);
498 desktop.startServiceDiscovery();
499 if (!aparser.contains(ArgsParser.NOUSAGESTATS))
501 startUsageStats(desktop);
505 System.err.println("CMD [-nousagestats] executed successfully!");
508 if (!aparser.contains(ArgsParser.NOQUESTIONNAIRE))
510 String url = aparser.getValue(ArgsParser.QUESTIONNAIRE);
513 // Start the desktop questionnaire prompter with the specified
515 Cache.log.debug("Starting questionnaire url at " + url);
516 desktop.checkForQuestionnaire(url);
517 System.out.println("CMD questionnaire[-" + url
518 + "] executed successfully!");
522 if (Cache.getProperty(Preferences.NOQUESTIONNAIRES) == null)
524 // Start the desktop questionnaire prompter with the specified
527 // "http://anaplog.compbio.dundee.ac.uk/cgi-bin/questionnaire.pl";
529 String defurl = "http://www.jalview.org/cgi-bin/questionnaire.pl";
531 "Starting questionnaire with default url: " + defurl);
532 desktop.checkForQuestionnaire(defurl);
539 .println("CMD [-noquestionnaire] executed successfully!");
542 if (!aparser.contains(ArgsParser.NONEWS))
544 desktop.checkForNews();
547 BioJsHTMLOutput.updateBioJS();
551 parseArguments(aparser, true);
555 * Allow an outside entity to initiate the second half of argument parsing
559 * @return null is good
562 public Object parseArguments(String[] args)
567 ArgsParser aparser = new ArgsParser(args);
568 return parseArguments(aparser, false);
569 } catch (Throwable t)
581 private Object parseArguments(ArgsParser aparser, boolean isStartup)
583 boolean isJS = Platform.isJS();
585 Desktop desktop = (headless ? null : Desktop.getInstance());
586 // script to execute after all loading is
587 // completed one way or another
588 // extract groovy argument and execute if necessary
589 String groovyscript = (isJS ? null
590 : aparser.getValue(ArgsParser.GROOVY, true));
591 String file = aparser.getValue(ArgsParser.OPEN, true);
592 // BH this here to allow split frame; not working as of 5/17/2019
593 String file2 = aparser.getValue(ArgsParser.OPEN2, true);
594 String fileFormat = (isJavaAppletTag
595 ? aparser.getAppletValue("format", null)
597 FileFormatI format = null;
598 DataSourceType protocol = null;
600 if (file == null && desktop == null)
602 System.out.println("No files to open!");
605 boolean haveImport = checkStartVamas(aparser);
606 // Finally, deal with the remaining input data.
608 if (file == null && isJavaAppletTag)
610 // Maybe the sequences are added as parameters
611 StringBuffer data = new StringBuffer("PASTE");
613 while ((file = aparser.getAppletValue("sequence" + i, null)) != null)
615 data.append(file.toString() + "\n");
618 if (data.length() > 5)
620 file = data.toString();
631 desktop.setProgressBar(
633 .getString("status.processing_commandline_args"),
634 progress = System.currentTimeMillis());
639 * ignore in JavaScript -- can't just check file existence - could load
645 if (!file.startsWith("http://") && !file.startsWith("https://"))
646 // BH 2019 added https check for Java
648 if (!(new File(file)).exists())
650 System.out.println("Can't find " + file);
659 protocol = AppletFormatAdapter.checkProtocol(file);
663 format = (isJavaAppletTag && fileFormat != null
664 ? FileFormats.getInstance().forName(fileFormat)
668 format = new IdentifyFile().identify(file, protocol);
670 } catch (FileFormatException e1)
675 if (aparser.contains(ArgsParser.SHOWOVERVIEW))
677 jalview.bin.Cache.setPropertyNoSave(Preferences.SHOW_OVERVIEW,
680 System.out.println("CMD [showoverview] executed successfully!");
683 if (aparser.contains(ArgsParser.NOMENUBAR))
686 System.out.println("CMD [nomenu] executed successfully!");
689 if (aparser.contains(ArgsParser.NOSTATUS))
692 System.out.println("CMD [nostatus] executed successfully!");
695 if (aparser.contains(ArgsParser.NOCALCULATION))
697 noCalculation = true;
698 System.out.println("CMD [nocalculation] executed successfully!");
701 AlignFrame af = new FileLoader(!headless).loadFileWaitTillLoaded(file,
705 System.out.println("error");
710 .println("CMD [-open " + file + "] executed successfully!");
713 protocol = AppletFormatAdapter.checkProtocol(file2);
716 format = new IdentifyFile().identify(file2, protocol);
717 } catch (FileFormatException e1)
721 AlignFrame af2 = new FileLoader(!headless)
722 .loadFileWaitTillLoaded(file2, protocol, format);
725 System.out.println("error");
729 AlignViewport.openLinkedAlignmentAs(af,
730 af.getViewport().getAlignment(),
731 af2.getViewport().getAlignment(), "",
732 AlignViewport.SPLIT_FRAME);
734 "CMD [-open2 " + file2 + "] executed successfully!");
738 setCurrentAlignFrame(af);
740 // TODO: file2 How to implement file2 for the applet spit screen?
742 data = aparser.getValue(ArgsParser.COLOUR, true);
745 data.replaceAll("%20", " ");
747 ColourSchemeI cs = ColourSchemeProperty.getColourScheme(
748 af.getViewport(), af.getViewport().getAlignment(), data);
753 "CMD [-color " + data + "] executed successfully!");
758 // Must maintain ability to use the groups flag
759 data = aparser.getValue(ArgsParser.GROUPS, true);
762 af.parseFeaturesFile(data,
763 AppletFormatAdapter.checkProtocol(data));
764 // System.out.println("Added " + data);
766 "CMD groups[-" + data + "] executed successfully!");
768 data = aparser.getValue(ArgsParser.FEATURES, true);
771 af.parseFeaturesFile(data,
772 AppletFormatAdapter.checkProtocol(data));
773 // System.out.println("Added " + data);
775 "CMD [-features " + data + "] executed successfully!");
778 data = aparser.getValue(ArgsParser.ANNOTATIONS, true);
781 af.loadJalviewDataFile(data, null, null, null);
782 // System.out.println("Added " + data);
784 "CMD [-annotations " + data + "] executed successfully!");
786 // set or clear the sortbytree flag.
787 if (aparser.contains(ArgsParser.SORTBYTREE))
789 af.getViewport().setSortByTree(true);
790 if (af.getViewport().getSortByTree())
792 System.out.println("CMD [-sortbytree] executed successfully!");
796 boolean doUpdateAnnotation = false;
799 if (aparser.contains(ArgsParser.NOANNOTATION)
800 || aparser.contains(ArgsParser.NOANNOTATION2))
802 af.getViewport().setShowAnnotation(false);
803 if (!af.getViewport().isShowAnnotation())
805 doUpdateAnnotation = true;
806 System.out.println("CMD no-annotation executed successfully!");
809 if (aparser.contains(ArgsParser.NOSORTBYTREE))
811 af.getViewport().setSortByTree(false);
812 if (!af.getViewport().getSortByTree())
814 doUpdateAnnotation = true;
816 .println("CMD [-nosortbytree] executed successfully!");
819 if (doUpdateAnnotation)
821 af.setMenusForViewport();
822 af.alignPanel.updateLayout();
824 data = aparser.getValue(ArgsParser.TREE, true);
830 "CMD [-tree " + data + "] executed successfully!");
831 NewickFile nf = new NewickFile(data,
832 AppletFormatAdapter.checkProtocol(data));
834 .setCurrentTree(af.showNewickTree(nf, data).getTree());
835 } catch (IOException ex)
837 System.err.println("Couldn't add tree " + data);
838 ex.printStackTrace(System.err);
841 // TODO - load PDB structure(s) to alignment JAL-629
842 // (associate with identical sequence in alignment, or a specified
846 loadAppletParams(aparser, af);
855 if (groovyscript != null)
857 // Execute the groovy script after we've done all the rendering
859 // and before any images or figures are generated.
860 System.out.println("Executing script " + groovyscript);
861 executeGroovyScript(groovyscript, af);
862 System.out.println("CMD groovy[" + groovyscript
863 + "] executed successfully!");
866 checkOutputFile(aparser, af, format);
867 while (aparser.getSize() > 0)
869 System.out.println("Unknown arg: " + aparser.nextValue());
874 AlignFrame startUpAlframe = null;
875 // We'll only open the default file if the desktop is visible.
877 // ////////////////////
879 if (!isJS && !headless && file == null && !haveImport
880 && jalview.bin.Cache.getDefault("SHOW_STARTUP_FILE", true))
887 file = jalview.bin.Cache.getDefault("STARTUP_FILE",
888 jalview.bin.Cache.getDefault("www.jalview.org",
889 "http://www.jalview.org")
890 + "/examples/exampleFile_2_7.jar");
892 "http://www.jalview.org/examples/exampleFile_2_3.jar"))
894 // hardwire upgrade of the startup file
895 file.replace("_2_3.jar", "_2_7.jar");
896 // and remove the stale setting
897 jalview.bin.Cache.removeProperty("STARTUP_FILE");
900 protocol = DataSourceType.FILE;
902 if (file.indexOf("http:") > -1)
904 protocol = DataSourceType.URL;
907 if (file.endsWith(".jar"))
909 format = FileFormat.Jalview;
915 format = new IdentifyFile().identify(file, protocol);
916 } catch (FileFormatException e)
922 startUpAlframe = new FileLoader(!headless)
923 .loadFileWaitTillLoaded(file, protocol, format);
924 // extract groovy arguments before anything else.
927 // Once all other stuff is done, execute any groovy scripts (in order)
928 if (groovyscript != null)
930 if (Cache.groovyJarsPresent())
932 System.out.println("Executing script " + groovyscript);
933 executeGroovyScript(groovyscript, startUpAlframe);
938 "Sorry. Groovy Support is not available, so ignoring the provided groovy script "
942 // and finally, turn off batch mode indicator - if the desktop still exists
947 desktop.setProgressBar(null, progress);
949 desktop.setInBatchMode(false);
955 private boolean checkStartVamas(ArgsParser aparser)
957 String vamsasImport = aparser.getValue(ArgsParser.VDOC);
958 String vamsasSession = aparser.getValue(ArgsParser.VSESS);
959 if (vamsasImport == null && vamsasSession == null)
963 if (desktop == null || headless)
966 "Headless vamsas sessions not yet supported. Sorry.");
969 boolean haveImport = (vamsasImport != null);
972 // if we have a file, start a new session and import it.
973 boolean inSession = false;
976 DataSourceType viprotocol = AppletFormatAdapter
977 .checkProtocol(vamsasImport);
978 if (viprotocol == DataSourceType.FILE)
980 inSession = desktop.vamsasImport(new File(vamsasImport));
982 else if (viprotocol == DataSourceType.URL)
984 inSession = desktop.vamsasImport(new URL(vamsasImport));
987 } catch (Exception e)
989 System.err.println("Exeption when importing " + vamsasImport
990 + " as a vamsas document.");
995 System.err.println("Failed to import " + vamsasImport
996 + " as a vamsas document.");
1000 System.out.println("Imported Successfully into new session "
1001 + desktop.getVamsasApplication().getCurrentSession());
1004 if (vamsasSession != null)
1006 if (vamsasImport != null)
1008 // close the newly imported session and import the Jalview specific
1009 // remnants into the new session later on.
1010 desktop.vamsasStop_actionPerformed(null);
1012 // now join the new session
1015 if (desktop.joinVamsasSession(vamsasSession))
1018 "Successfully joined vamsas session " + vamsasSession);
1022 System.err.println("WARNING: Failed to join vamsas session "
1025 } catch (Exception e)
1028 "ERROR: Failed to join vamsas session " + vamsasSession);
1029 e.printStackTrace();
1031 if (vamsasImport != null)
1033 // the Jalview specific remnants can now be imported into the new
1034 // session at the user's leisure.
1036 "Skipping Push for import of data into existing vamsas session.");
1042 // desktop.getVamsasApplication().push_update();
1048 private void checkOutputFile(ArgsParser aparser, AlignFrame af,
1051 String imageName = "unnamed.png";
1052 while (aparser.getSize() > 1)
1057 // biojsmsa filename
1058 String outputFormat = aparser.nextValue();
1059 String file = aparser.nextValue();
1060 if (outputFormat.equalsIgnoreCase("png"))
1062 af.createPNG(new File(file));
1063 imageName = (new File(file)).getName();
1064 System.out.println("Creating PNG image: " + file);
1067 else if (outputFormat.equalsIgnoreCase("svg"))
1069 File imageFile = new File(file);
1070 imageName = imageFile.getName();
1071 af.createSVG(imageFile);
1072 System.out.println("Creating SVG image: " + file);
1075 else if (outputFormat.equalsIgnoreCase("html"))
1077 File imageFile = new File(file);
1078 imageName = imageFile.getName();
1079 HtmlSvgOutput htmlSVG = new HtmlSvgOutput(af.alignPanel);
1080 htmlSVG.exportHTML(file);
1082 System.out.println("Creating HTML image: " + file);
1085 else if (outputFormat.equalsIgnoreCase("biojsmsa"))
1089 System.err.println("The output html file must not be null");
1094 BioJsHTMLOutput.refreshVersionInfo(
1095 BioJsHTMLOutput.BJS_TEMPLATES_LOCAL_DIRECTORY);
1096 } catch (URISyntaxException e)
1098 e.printStackTrace();
1100 BioJsHTMLOutput bjs = new BioJsHTMLOutput(af.alignPanel);
1101 bjs.exportHTML(file);
1102 System.out.println("Creating BioJS MSA Viwer HTML file: " + file);
1105 else if (outputFormat.equalsIgnoreCase("imgMap"))
1107 af.createImageMap(new File(file), imageName);
1108 System.out.println("Creating image map: " + file);
1111 else if (outputFormat.equalsIgnoreCase("eps"))
1113 File outputFile = new File(file);
1115 "Creating EPS file: " + outputFile.getAbsolutePath());
1116 af.createEPS(outputFile);
1120 af.saveAlignment(file, format);
1121 if (af.isSaveAlignmentSuccessful())
1124 "Written alignment in " + format + " format to " + file);
1128 System.out.println("Error writing file " + file + " in " + format
1135 private static void showUsage()
1138 "Usage: jalview -open [FILE] [OUTPUT_FORMAT] [OUTPUT_FILE]\n\n"
1139 + "-nodisplay\tRun Jalview without User Interface.\n"
1140 + "-props FILE\tUse the given Jalview properties file instead of users default.\n"
1141 + "-colour COLOURSCHEME\tThe colourscheme to be applied to the alignment\n"
1142 + "-annotations FILE\tAdd precalculated annotations to the alignment.\n"
1143 + "-tree FILE\tLoad the given newick format tree file onto the alignment\n"
1144 + "-features FILE\tUse the given file to mark features on the alignment.\n"
1145 + "-fasta FILE\tCreate alignment file FILE in Fasta format.\n"
1146 + "-clustal FILE\tCreate alignment file FILE in Clustal format.\n"
1147 + "-pfam FILE\tCreate alignment file FILE in PFAM format.\n"
1148 + "-msf FILE\tCreate alignment file FILE in MSF format.\n"
1149 + "-pileup FILE\tCreate alignment file FILE in Pileup format\n"
1150 + "-pir FILE\tCreate alignment file FILE in PIR format.\n"
1151 + "-blc FILE\tCreate alignment file FILE in BLC format.\n"
1152 + "-json FILE\tCreate alignment file FILE in JSON format.\n"
1153 + "-jalview FILE\tCreate alignment file FILE in Jalview format.\n"
1154 + "-png FILE\tCreate PNG image FILE from alignment.\n"
1155 + "-svg FILE\tCreate SVG image FILE from alignment.\n"
1156 + "-html FILE\tCreate HTML file from alignment.\n"
1157 + "-biojsMSA FILE\tCreate BioJS MSA Viewer HTML file from alignment.\n"
1158 + "-imgMap FILE\tCreate HTML file FILE with image map of PNG image.\n"
1159 + "-eps FILE\tCreate EPS file FILE from alignment.\n"
1160 + "-questionnaire URL\tQueries the given URL for information about any Jalview user questionnaires.\n"
1161 + "-noquestionnaire\tTurn off questionnaire check.\n"
1162 + "-nonews\tTurn off check for Jalview news.\n"
1163 + "-nousagestats\tTurn off google analytics tracking for this session.\n"
1164 + "-sortbytree OR -nosortbytree\tEnable or disable sorting of the given alignment by the given tree\n"
1166 // "-setprop PROPERTY=VALUE\tSet the given Jalview property,
1167 // after all other properties files have been read\n\t
1168 // (quote the 'PROPERTY=VALUE' pair to ensure spaces are
1169 // passed in correctly)"
1170 + "-jabaws URL\tSpecify URL for Jabaws services (e.g. for a local installation).\n"
1171 + "-fetchfrom nickname\tQuery nickname for features for the alignments and display them.\n"
1173 // "-vdoc vamsas-document\tImport vamsas document into new
1174 // session or join existing session with same URN\n"
1175 // + "-vses vamsas-session\tJoin session with given URN\n"
1176 + "-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"
1177 + "\n~Read documentation in Application or visit http://www.jalview.org for description of Features and Annotations file~\n\n");
1180 private static void startUsageStats(final Desktop desktop)
1183 * start a User Config prompt asking if we can log usage statistics.
1185 PromptUserConfig prompter = new PromptUserConfig(
1186 Desktop.getDesktopPane(), "USAGESTATS",
1187 "Jalview Usage Statistics",
1188 "Do you want to help make Jalview better by enabling "
1189 + "the collection of usage statistics with Google Analytics ?"
1190 + "\n\n(you can enable or disable usage tracking in the preferences)",
1197 "Initialising googletracker for usage stats.");
1198 Cache.initGoogleTracker();
1199 Cache.log.debug("Tracking enabled.");
1206 Cache.log.debug("Not enabling Google Tracking.");
1209 desktop.addDialogThread(prompter);
1213 * Locate the given string as a file and pass it to the groovy interpreter.
1215 * @param groovyscript
1216 * the script to execute
1217 * @param jalviewContext
1218 * the Jalview Desktop object passed in to the groovy binding as the
1221 private void executeGroovyScript(String groovyscript, AlignFrame af)
1224 * for scripts contained in files
1231 if (groovyscript.trim().equals("STDIN"))
1233 // read from stdin into a tempfile and execute it
1236 tfile = File.createTempFile("jalview", "groovy");
1237 PrintWriter outfile = new PrintWriter(
1238 new OutputStreamWriter(new FileOutputStream(tfile)));
1239 BufferedReader br = new BufferedReader(
1240 new InputStreamReader(System.in));
1242 while ((line = br.readLine()) != null)
1244 outfile.write(line + "\n");
1250 } catch (Exception ex)
1252 System.err.println("Failed to read from STDIN into tempfile "
1253 + ((tfile == null) ? "(tempfile wasn't created)"
1254 : tfile.toString()));
1255 ex.printStackTrace();
1260 sfile = tfile.toURI().toURL();
1261 } catch (Exception x)
1264 "Unexpected Malformed URL Exception for temporary file created from STDIN: "
1266 x.printStackTrace();
1274 sfile = new URI(groovyscript).toURL();
1275 } catch (Exception x)
1277 tfile = new File(groovyscript);
1278 if (!tfile.exists())
1280 System.err.println("File '" + groovyscript + "' does not exist.");
1283 if (!tfile.canRead())
1285 System.err.println("File '" + groovyscript + "' cannot be read.");
1288 if (tfile.length() < 1)
1290 System.err.println("File '" + groovyscript + "' is empty.");
1295 sfile = tfile.getAbsoluteFile().toURI().toURL();
1296 } catch (Exception ex)
1298 System.err.println("Failed to create a file URL for "
1299 + tfile.getAbsoluteFile());
1306 Map<String, Object> vbinding = new HashMap<>();
1307 vbinding.put("Jalview", this);
1310 vbinding.put("currentAlFrame", af);
1312 Binding gbinding = new Binding(vbinding);
1313 GroovyScriptEngine gse = new GroovyScriptEngine(new URL[] { sfile });
1314 gse.run(sfile.toString(), gbinding);
1315 if ("STDIN".equals(groovyscript))
1317 // delete temp file that we made -
1318 // only if it was successfully executed
1321 } catch (Exception e)
1323 System.err.println("Exception Whilst trying to execute file " + sfile
1324 + " as a groovy script.");
1325 e.printStackTrace(System.err);
1330 public AlignFrame[] getAlignFrames()
1332 return desktop == null ? new AlignFrame[] { getCurrentAlignFrame() }
1333 : Desktop.getAlignFrames();
1338 * Quit method delegates to Desktop.quit - unless running in headless mode
1339 * when it just ends the JVM
1343 if (jsFunctionExec != null)
1345 jsFunctionExec.tidyUp();
1346 jsFunctionExec = null;
1349 if (desktop != null)
1360 * Get the SwingJS applet ID and combine that with the frameType
1363 * "alignment", "desktop", etc., or null
1366 public static String getAppID(String frameType)
1368 String id = Cache.getProperty("Info.j2sAppletID");
1373 return id + (frameType == null ? "" : "-" + frameType);
1377 * Handle all JalviewLite applet parameters
1382 private void loadAppletParams(ArgsParser aparser, AlignFrame af)
1384 JalviewApp app = new JalviewApp()
1389 // These are methods that are in JalviewLite that various classes call
1390 // but are not in JalviewLiteJsApi. Or, even if they are, other classes
1392 // them to JalviewLite directly. Some may not be necessary, but they have
1394 // be at least mentioned here, or the classes calling them should
1396 // JalviewLite itself.
1398 private boolean alignPDBStructures; // From JalviewLite; not implemented
1400 private Hashtable<String, Hashtable<String, String[]>> jsmessages;
1402 private Hashtable<String, int[]> jshashes;
1405 public String getParameter(String name)
1407 return aparser.getAppletValue(name, null);
1411 public boolean getDefaultParameter(String name, boolean def)
1414 return ((stn = getParameter(name)) == null ? def
1415 : "true".equalsIgnoreCase(stn));
1419 * Get the applet-like document base even though this is an application.
1422 public URL getDocumentBase()
1424 return Platform.getDocumentBase();
1428 * Get the applet-like code base even though this is an application.
1431 public URL getCodeBase()
1433 return Platform.getCodeBase();
1437 public AlignViewportI getViewport()
1439 return af.getViewport();
1447 public boolean parseFeaturesFile(String filename,
1448 DataSourceType protocol)
1450 return af.parseFeaturesFile(filename, protocol);
1458 public boolean loadScoreFile(String sScoreFile) throws IOException
1460 af.loadJalviewDataFile(sScoreFile, null, null, null);
1465 * annotations, jpredfile, jnetfile
1469 public void updateForAnnotations()
1471 af.updateForAnnotations();
1475 public void loadTree(NewickFile fin, String treeFile)
1478 // n/a -- already done by standard Jalview command line processing
1482 public void setAlignPdbStructures(boolean defaultParameter)
1484 alignPDBStructures = true;
1488 public void newStructureView(PDBEntry pdb, SequenceI[] seqs,
1489 String[] chains, DataSourceType protocol)
1491 StructureViewer.launchStructureViewer(af.alignPanel, pdb, seqs);
1495 public void setFeatureGroupState(String[] groups, boolean state)
1497 af.setFeatureGroupState(groups, state);
1501 public void alignedStructureView(PDBEntry[] pdb, SequenceI[][] seqs,
1502 String[][] chains, String[] protocols)
1505 "Jalview applet interface alignedStructureView not implemented");
1509 public void newFeatureSettings()
1512 "Jalview applet interface newFeatureSettings not implemented");
1515 private Vector<Runnable> jsExecQueue;
1518 public Vector<Runnable> getJsExecQueue(JSFunctionExec exec)
1520 jsFunctionExec = exec;
1521 return (jsExecQueue == null ? (jsExecQueue = new Vector<>())
1526 public AppletContext getAppletContext()
1528 // TODO Auto-generated method stub
1533 public boolean isJsfallbackEnabled()
1535 // TODO Auto-generated method stub
1540 public JSObject getJSObject()
1542 // TODO Auto-generated method stub
1547 public StructureSelectionManagerProvider getStructureSelectionManagerProvider()
1549 // TODO Q: what exactly is this? BH
1554 public void updateColoursFromMouseOver(Object source,
1555 MouseOverStructureListener mouseOverStructureListener)
1557 // TODO Auto-generated method stub
1562 public Object[] getSelectionForListener(SequenceGroup seqsel,
1563 ColumnSelection colsel, HiddenColumns hidden,
1564 SelectionSource source, Object alignFrame)
1566 return appLoader.getSelectionForListener(getCurrentAlignFrame(),
1567 seqsel, colsel, hidden, source, alignFrame);
1571 public String arrayToSeparatorList(String[] array)
1573 return appLoader.arrayToSeparatorList(array);
1577 public Hashtable<String, int[]> getJSHashes()
1579 return (jshashes == null ? (jshashes = new Hashtable<>())
1584 public Hashtable<String, Hashtable<String, String[]>> getJSMessages()
1586 return (jsmessages == null ? (jsmessages = new Hashtable<>())
1591 public Object getFrameForSource(VamsasSource source)
1596 if (source instanceof jalview.gui.AlignViewport
1597 && source == (af = getCurrentAlignFrame()).getViewport())
1599 // should be valid if it just generated an event!
1602 // TODO: ensure that if '_af' is specified along with a handler
1603 // function, then only events from that alignFrame are sent to that
1610 public FeatureRenderer getNewFeatureRenderer(AlignViewportI vp)
1612 return new jalview.gui.FeatureRenderer((AlignmentPanel) vp);
1617 appLoader = new JalviewAppLoader(true);
1618 appLoader.load(app);
1623 * @see jalview.bin.JalviewLiteJsApi#getSelectedSequences()
1626 public String getSelectedSequences()
1628 return getSelectedSequencesFrom(getCurrentAlignFrame());
1633 * @see jalview.bin.JalviewLiteJsApi#getSelectedSequences(java.lang.String)
1636 public String getSelectedSequences(String sep)
1638 return getSelectedSequencesFrom(getCurrentAlignFrame(), sep);
1643 * @see jalview.bin.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
1647 public String getSelectedSequencesFrom(AlignFrameI alf)
1649 return getSelectedSequencesFrom(alf, null);
1654 * @see jalview.bin.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
1655 * .AlignFrame, java.lang.String)
1658 public String getSelectedSequencesFrom(AlignFrameI alf, String sep)
1660 return appLoader.getSelectedSequencesFrom(alf, sep);
1665 * @see jalview.bin.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
1666 * .AlignFrame, java.lang.String)
1669 public void highlight(String sequenceId, String position,
1670 String alignedPosition)
1672 highlightIn(getCurrentAlignFrame(), sequenceId, position,
1677 public void highlightIn(AlignFrameI alf, String sequenceId,
1678 String position, String alignedPosition)
1680 appLoader.highlightIn(alf, sequenceId, position, alignedPosition);
1684 public void select(String sequenceIds, String columns)
1686 selectIn(getCurrentAlignFrame(), sequenceIds, columns, null);
1690 public void select(String sequenceIds, String columns, String sep)
1692 selectIn(getCurrentAlignFrame(), sequenceIds, columns, sep);
1696 public void selectIn(AlignFrameI alf, String sequenceIds, String columns)
1698 selectIn(alf, sequenceIds, columns, null);
1702 public void selectIn(AlignFrameI alf, String sequenceIds, String columns,
1705 appLoader.selectIn(alf, sequenceIds, columns, sep);
1709 public String getSelectedSequencesAsAlignment(String format,
1712 return getSelectedSequencesAsAlignmentFrom(getCurrentAlignFrame(),
1717 public String getSelectedSequencesAsAlignmentFrom(AlignFrameI alf,
1718 String format, String sep)
1720 return appLoader.getSelectedSequencesAsAlignmentFrom(alf, format, sep);
1724 public String getAlignmentOrder()
1726 return getAlignmentFrom(getCurrentAlignFrame(), null);
1730 public String getAlignmentOrderFrom(AlignFrameI alf)
1732 return getAlignmentFrom(alf, null);
1736 public String getAlignmentOrderFrom(AlignFrameI alf, String sep)
1738 return appLoader.getAlignmentOrderFrom(alf, sep);
1742 public String orderBy(String order, String undoName)
1744 return orderBy(order, undoName, null);
1748 public String orderBy(String order, String undoName, String sep)
1750 return orderAlignmentBy(getCurrentAlignFrame(), order, undoName, sep);
1754 public String orderAlignmentBy(AlignFrameI alf, String order,
1755 String undoName, String sep)
1757 return appLoader.orderAlignmentBy(alf, order, undoName, sep);
1761 public String getAlignment(String format)
1763 return getAlignmentFrom(null, format, null);
1767 public String getAlignmentFrom(AlignFrameI alf, String format)
1769 return getAlignmentFrom(alf, format, null);
1773 public String getAlignment(String format, String suffix)
1775 return getAlignmentFrom(getCurrentAlignFrame(), format, suffix);
1779 public String getAlignmentFrom(AlignFrameI alf, String format,
1782 return appLoader.getAlignmentFrom(alf, format, suffix);
1786 public void loadAnnotation(String annotation)
1788 loadAnnotationFrom(getCurrentAlignFrame(), annotation);
1792 public void loadAnnotationFrom(AlignFrameI alf, String annotation)
1794 appLoader.loadAnnotationFrom(alf, annotation);
1798 public void loadFeatures(String features, boolean autoenabledisplay)
1800 loadFeaturesFrom(currentAlignFrame, features, autoenabledisplay);
1804 public boolean loadFeaturesFrom(AlignFrameI alf, String features,
1805 boolean autoenabledisplay)
1807 return appLoader.loadFeaturesFrom(alf, features, autoenabledisplay);
1811 public String getFeatures(String format)
1813 return getFeaturesFrom(getCurrentAlignFrame(), format);
1817 public String getFeaturesFrom(AlignFrameI alf, String format)
1819 return appLoader.getFeaturesFrom(alf, format);
1823 public String getAnnotation()
1825 return getAnnotationFrom(getCurrentAlignFrame());
1829 public String getAnnotationFrom(AlignFrameI alf)
1831 return appLoader.getAnnotationFrom(alf);
1835 public AlignFrameI newView()
1837 return newViewFrom(getCurrentAlignFrame(), null);
1841 public AlignFrameI newView(String name)
1843 return newViewFrom(getCurrentAlignFrame(), name);
1847 public AlignFrameI newViewFrom(AlignFrameI alf)
1849 return newViewFrom(alf, null);
1853 public AlignFrameI newViewFrom(AlignFrameI alf, String name)
1855 return appLoader.newViewFrom(alf, name);
1859 public AlignFrameI loadAlignment(String text, String title)
1861 return appLoader.loadAlignment(text, AlignFrame.DEFAULT_WIDTH,
1862 AlignFrame.DEFAULT_HEIGHT, title);
1866 public boolean addPdbFile(AlignFrameI alFrame, String sequenceId,
1867 String pdbEntryString, String pdbFile)
1869 return appLoader.addPdbFile(alFrame, sequenceId, pdbEntryString,
1874 public void scrollViewToIn(AlignFrameI alf, String topRow,
1875 String leftHandColumn)
1877 appLoader.scrollViewToIn(alf, topRow, leftHandColumn);
1881 public void scrollViewToRowIn(AlignFrameI alf, String topRow)
1883 appLoader.scrollViewToRowIn(alf, topRow);
1887 public void scrollViewToColumnIn(AlignFrameI alf, String leftHandColumn)
1889 appLoader.scrollViewToColumnIn(alf, leftHandColumn);
1893 public String getFeatureGroups()
1895 return getFeatureGroupsOn(getCurrentAlignFrame());
1899 public String getFeatureGroupsOn(AlignFrameI alf)
1901 return appLoader.getFeatureGroupsOn(alf);
1905 public String getFeatureGroupsOfState(boolean visible)
1907 return getFeatureGroupsOfStateOn(getCurrentAlignFrame(), visible);
1911 public String getFeatureGroupsOfStateOn(AlignFrameI alf, boolean visible)
1913 return appLoader.getFeatureGroupsOfStateOn(alf, visible);
1917 public void setFeatureGroupStateOn(AlignFrameI alf, String groups,
1920 setFeatureGroupStateOn(alf, groups, state);
1924 public void setFeatureGroupState(String groups, boolean state)
1926 appLoader.setFeatureGroupStateOn(getCurrentAlignFrame(), groups, state);
1930 public String getSeparator()
1932 return appLoader.getSeparator();
1936 public void setSeparator(String separator)
1938 appLoader.setSeparator(separator);
1942 public String getJsMessage(String messageclass, String viewId)
1944 // see http://www.jalview.org/examples/jalviewLiteJs.html
1949 * Open a new Tree panel on the desktop statically. Params are standard (not
1950 * set by Groovy). No dialog is opened.
1955 * @return null, or the string "label.you_need_at_least_n_sequences" if number
1956 * of sequences selected is inappropriate
1959 public Object openTreePanel(AlignFrame af, String treeType,
1962 return CalculationChooser.openTreePanel(af, treeType, modelName, null);
1966 * public static method for JalviewJS API to open a PCAPanel without
1967 * necessarily using a dialog.
1971 * @return the PCAPanel, or the string "label.you_need_at_least_n_sequences"
1972 * if number of sequences selected is inappropriate
1975 public Object openPcaPanel(AlignFrame af, String modelName)
1977 return CalculationChooser.openPcaPanel(af, modelName, null);
1981 public String getSelectedSequencesAsAlignment(String format,
1984 return getSelectedSequencesAsAlignmentFrom(getCurrentAlignFrame(),
1989 public String getSelectedSequencesAsAlignmentFrom(AlignFrameI alf,
1990 String format, boolean suffix)
1992 return appLoader.getSelectedSequencesAsAlignmentFrom(alf, format,
1997 public String arrayToSeparatorList(String[] array)
1999 return appLoader.arrayToSeparatorList(array);
2003 public String[] separatorListToArray(String list)
2005 return appLoader.separatorListToArray(list);
2008 //// probably not needed in JalviewJS -- From when Jmol and Jalview did not
2009 //// have a direct connection?
2012 public void setMouseoverListener(String listener)
2014 // TODO Auto-generated method stub
2019 public void setMouseoverListener(AlignFrameI af, String listener)
2021 // TODO Auto-generated method stub
2026 public void setSelectionListener(String listener)
2028 // TODO Auto-generated method stub
2033 public void setSelectionListener(AlignFrameI af, String listener)
2035 // TODO Auto-generated method stub
2040 public void setStructureListener(String listener, String modelSet)
2042 // TODO Auto-generated method stub
2047 public void removeJavascriptListener(AlignFrameI af, String listener)
2049 // TODO Auto-generated method stub
2054 public void mouseOverStructure(String pdbResNum, String chain,
2057 // TODO Auto-generated method stub