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 // for testing those nasty messages you cannot ever find.
116 // System.setOut(new PrintStream(new ByteArrayOutputStream())
119 // public void println(Object o)
123 // System.err.println(o);
129 public static Jalview getInstance()
131 return (Jalview) ApplicationSingletonProvider
132 .getInstance(Jalview.class);
141 Platform.getURLCommandArguments();
144 private boolean headless;
146 public static boolean isHeadlessMode()
148 return getInstance().headless;
151 private Desktop desktop;
153 private AlignFrame currentAlignFrame;
155 public boolean isJavaAppletTag;
157 public String appletResourcePath;
159 JalviewAppLoader appLoader;
161 protected JSFunctionExec jsFunctionExec;
163 private boolean noCalculation, noMenuBar, noStatus;
165 private boolean noAnnotation;
167 public boolean getStartCalculations()
169 return !noCalculation;
172 public boolean getAllowMenuBar()
177 public boolean getShowStatus()
182 public boolean getShowAnnotation()
184 return !noAnnotation;
187 public static AlignFrame getCurrentAlignFrame()
189 return getInstance().currentAlignFrame;
192 public static void setCurrentAlignFrame(AlignFrame currentAlignFrame)
194 getInstance().currentAlignFrame = currentAlignFrame;
199 if (!Platform.isJS())
206 // grab all the rights we can for the JVM
207 Policy.setPolicy(new Policy()
210 public PermissionCollection getPermissions(CodeSource codesource)
212 Permissions perms = new Permissions();
213 perms.add(new AllPermission());
218 public void refresh()
226 * keep track of feature fetching tasks.
234 * TODO: generalise to track all jalview events to orchestrate batch
238 private int queued = 0;
240 private int running = 0;
242 public FeatureFetcher()
247 public void addFetcher(final AlignFrame af,
248 final Vector<String> dasSources)
250 final long id = System.currentTimeMillis();
252 final FeatureFetcher us = this;
253 new Thread(new Runnable()
265 af.setProgressBar(MessageManager
266 .getString("status.das_features_being_retrived"), id);
267 af.featureSettings_actionPerformed(null);
268 af.setProgressBar(null, id);
277 public synchronized boolean allFinished()
279 return queued == 0 && running == 0;
285 * main class for Jalview application
288 * open <em>filename</em>
290 public static void main(String[] args)
292 // Platform.startJavaLogging();
293 getInstance().doMain(args);
297 @SuppressWarnings("unused")
301 void doMain(String[] args)
304 boolean isJS = Platform.isJS();
307 Platform.setAppClass(this);
311 System.setSecurityManager(null);
315 .println("Java version: " + System.getProperty("java.version"));
316 System.out.println(System.getProperty("os.arch") + " "
317 + System.getProperty("os.name") + " "
318 + System.getProperty("os.version"));
320 ArgsParser aparser = new ArgsParser(args);
322 String usrPropsFile = aparser.getValue(ArgsParser.PROPS);
323 Cache.loadProperties(usrPropsFile);
325 if (aparser.contains(ArgsParser.NODISPLAY)
326 || aparser.contains(ArgsParser.NOGUI)
327 || aparser.contains(ArgsParser.HEADLESS)
328 || "true".equals(System.getProperty("java.awt.headless")))
335 isJavaAppletTag = aparser.isApplet();
338 Preferences.setAppletDefaults();
339 Cache.loadProperties(usrPropsFile); // again, because we
340 // might be changing defaults here?
343 "<Applet> found: " + aparser.getValue("Info.j2sAppletID"));
344 appletResourcePath = aparser.getValue("Info.resourcePath");
353 if (usrPropsFile != null)
356 "CMD [-props " + usrPropsFile + "] executed successfully!");
359 if (aparser.contains("help") || aparser.contains("h"))
368 final String jabawsUrl = aparser.getValue(ArgsParser.JABAWS);
369 if (jabawsUrl != null)
373 Jws2Discoverer.getInstance().setPreferredUrl(jabawsUrl);
375 "CMD [-jabaws " + jabawsUrl + "] executed successfully!");
376 } catch (MalformedURLException e)
379 "Invalid jabaws parameter: " + jabawsUrl + " ignored");
384 // check for property setting
385 String defs = aparser.getValue(ArgsParser.SETPROP);
388 int p = defs.indexOf('=');
391 System.err.println("Ignoring invalid setprop argument : " + defs);
395 System.out.println("Executing setprop argument: " + defs);
398 Cache.setProperty(defs.substring(0, p), defs.substring(p + 1));
401 defs = aparser.getValue(ArgsParser.SETPROP);
403 System.setProperty("http.agent",
404 "Jalview Desktop/" + Cache.getDefault("VERSION", "Unknown"));
408 } catch (NoClassDefFoundError error)
410 error.printStackTrace();
411 System.out.println("\nEssential logging libraries not found."
412 + "\nUse: java -classpath \"$PATH_TO_LIB$/*:$PATH_TO_CLASSES$\" jalview.bin.Jalview");
420 if (!isJS && Platform.isWin())
422 UIManager.setLookAndFeel(
423 headless ? "javax.swing.plaf.metal.MetalLookAndFeel"
424 : UIManager.getSystemLookAndFeelClassName());
425 // UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
427 } catch (Exception ex)
429 System.err.println("Unexpected Look and Feel Exception");
430 ex.printStackTrace();
432 if (Platform.isAMacAndNotJS())
435 LookAndFeel lookAndFeel = ch.randelshofer.quaqua.QuaquaManager
437 System.setProperty("com.apple.mrj.application.apple.menu.about.name",
439 System.setProperty("apple.laf.useScreenMenuBar", "true");
440 if (lookAndFeel != null)
444 UIManager.setLookAndFeel(lookAndFeel);
445 } catch (Throwable e)
448 "Failed to set QuaQua look and feel: " + e.toString());
451 if (lookAndFeel == null
452 || !(lookAndFeel.getClass().isAssignableFrom(
453 UIManager.getLookAndFeel().getClass()))
454 || !UIManager.getLookAndFeel().getClass().toString()
455 .toLowerCase().contains("quaqua"))
460 "Quaqua LaF not available on this plaform. Using VAqua(4).\nSee https://issues.jalview.org/browse/JAL-2976");
461 UIManager.setLookAndFeel("org.violetlib.aqua.AquaLookAndFeel");
462 } catch (Throwable e)
465 "Failed to reset look and feel: " + e.toString());
471 * configure 'full' SO model if preferences say to,
472 * else use the default (SO Lite)
474 if (Cache.getDefault(Preferences.USE_FULL_SO, false))
476 SequenceOntologyFactory.setSequenceOntology(new SequenceOntology());
481 desktop = Desktop.getInstance();
482 desktop.setInBatchMode(true); // indicate we are starting up
483 desktop.setVisible(true);
492 desktop.startServiceDiscovery();
493 if (!aparser.contains(ArgsParser.NOUSAGESTATS))
495 startUsageStats(desktop);
499 System.err.println("CMD [-nousagestats] executed successfully!");
502 if (!aparser.contains(ArgsParser.NOQUESTIONNAIRE))
504 String url = aparser.getValue(ArgsParser.QUESTIONNAIRE);
507 // Start the desktop questionnaire prompter with the specified
509 Cache.log.debug("Starting questionnaire url at " + url);
510 desktop.checkForQuestionnaire(url);
511 System.out.println("CMD questionnaire[-" + url
512 + "] executed successfully!");
516 if (Cache.getProperty(Preferences.NOQUESTIONNAIRES) == null)
518 // Start the desktop questionnaire prompter with the specified
521 // "http://anaplog.compbio.dundee.ac.uk/cgi-bin/questionnaire.pl";
523 String defurl = "http://www.jalview.org/cgi-bin/questionnaire.pl";
525 "Starting questionnaire with default url: " + defurl);
526 desktop.checkForQuestionnaire(defurl);
533 .println("CMD [-noquestionnaire] executed successfully!");
536 if (!aparser.contains(ArgsParser.NONEWS))
538 desktop.checkForNews();
541 BioJsHTMLOutput.updateBioJS();
545 parseArguments(aparser, true);
549 * Allow an outside entity to initiate the second half of argument parsing
553 * @return null is good
556 public Object parseArguments(String[] args)
561 ArgsParser aparser = new ArgsParser(args);
562 return parseArguments(aparser, false);
563 } catch (Throwable t)
575 private Object parseArguments(ArgsParser aparser, boolean isStartup)
577 boolean isJS = Platform.isJS();
579 Desktop desktop = (headless ? null : Desktop.getInstance());
580 // script to execute after all loading is
581 // completed one way or another
582 // extract groovy argument and execute if necessary
583 String groovyscript = (isJS ? null
584 : aparser.getValue(ArgsParser.GROOVY, true));
585 String file = aparser.getValue(ArgsParser.OPEN, true);
586 // BH this here to allow split frame; not working as of 5/17/2019
587 String file2 = aparser.getValue(ArgsParser.OPEN2, true);
588 String fileFormat = (isJavaAppletTag
589 ? aparser.getAppletValue("format", null)
591 FileFormatI format = null;
592 DataSourceType protocol = null;
594 if (file == null && desktop == null)
596 System.out.println("No files to open!");
599 boolean haveImport = checkStartVamas(aparser);
600 // Finally, deal with the remaining input data.
602 if (file == null && isJavaAppletTag)
604 // Maybe the sequences are added as parameters
605 StringBuffer data = new StringBuffer("PASTE");
607 while ((file = aparser.getAppletValue("sequence" + i, null)) != null)
609 data.append(file.toString() + "\n");
612 if (data.length() > 5)
614 file = data.toString();
625 desktop.setProgressBar(
627 .getString("status.processing_commandline_args"),
628 progress = System.currentTimeMillis());
633 * ignore in JavaScript -- can't just check file existence - could load
639 if (!file.startsWith("http://") && !file.startsWith("https://"))
640 // BH 2019 added https check for Java
642 if (!(new File(file)).exists())
644 System.out.println("Can't find " + file);
653 protocol = AppletFormatAdapter.checkProtocol(file);
657 format = (isJavaAppletTag && fileFormat != null
658 ? FileFormats.getInstance().forName(fileFormat)
662 format = new IdentifyFile().identify(file, protocol);
664 } catch (FileFormatException e1)
669 if (aparser.contains(ArgsParser.NOMENUBAR))
672 System.out.println("CMD [nomenu] executed successfully!");
675 if (aparser.contains(ArgsParser.NOSTATUS))
678 System.out.println("CMD [nostatus] executed successfully!");
681 if (aparser.contains(ArgsParser.NOANNOTATION)
682 || aparser.contains(ArgsParser.NOANNOTATION2))
685 System.out.println("CMD no-annotation executed successfully!");
687 if (aparser.contains(ArgsParser.NOCALCULATION))
689 noCalculation = true;
690 System.out.println("CMD [nocalculation] executed successfully!");
693 AlignFrame af = new FileLoader(!headless).loadFileWaitTillLoaded(file,
697 System.out.println("error");
702 .println("CMD [-open " + file + "] executed successfully!");
705 protocol = AppletFormatAdapter.checkProtocol(file2);
708 format = new IdentifyFile().identify(file2, protocol);
709 } catch (FileFormatException e1)
713 AlignFrame af2 = new FileLoader(!headless)
714 .loadFileWaitTillLoaded(file2, protocol, format);
717 System.out.println("error");
721 AlignViewport.openLinkedAlignmentAs(af,
722 af.getViewport().getAlignment(),
723 af2.getViewport().getAlignment(), "",
724 AlignViewport.SPLIT_FRAME);
726 "CMD [-open2 " + file2 + "] executed successfully!");
730 setCurrentAlignFrame(af);
732 // TODO: file2 How to implement file2 for the applet spit screen?
734 data = aparser.getValue(ArgsParser.COLOUR, true);
737 data.replaceAll("%20", " ");
739 ColourSchemeI cs = ColourSchemeProperty.getColourScheme(
740 af.getViewport(), af.getViewport().getAlignment(), data);
745 "CMD [-color " + data + "] executed successfully!");
750 // Must maintain ability to use the groups flag
751 data = aparser.getValue(ArgsParser.GROUPS, true);
754 af.parseFeaturesFile(data,
755 AppletFormatAdapter.checkProtocol(data));
756 // System.out.println("Added " + data);
758 "CMD groups[-" + data + "] executed successfully!");
760 data = aparser.getValue(ArgsParser.FEATURES, true);
763 af.parseFeaturesFile(data,
764 AppletFormatAdapter.checkProtocol(data));
765 // System.out.println("Added " + data);
767 "CMD [-features " + data + "] executed successfully!");
770 data = aparser.getValue(ArgsParser.ANNOTATIONS, true);
773 af.loadJalviewDataFile(data, null, null, null);
774 // System.out.println("Added " + data);
776 "CMD [-annotations " + data + "] executed successfully!");
779 if (aparser.contains(ArgsParser.SHOWOVERVIEW))
781 af.overviewMenuItem_actionPerformed(null);
782 System.out.println("CMD [showoverview] executed successfully!");
785 // set or clear the sortbytree flag.
786 if (aparser.contains(ArgsParser.SORTBYTREE))
788 af.getViewport().setSortByTree(true);
789 if (af.getViewport().getSortByTree())
791 System.out.println("CMD [-sortbytree] executed successfully!");
795 boolean doUpdateAnnotation = false;
798 * we do this earlier in JalviewJS because of a complication with
801 * For now, just fixing this in JalviewJS.
808 if (aparser.contains(ArgsParser.NOANNOTATION)
809 || aparser.contains(ArgsParser.NOANNOTATION2))
811 af.getViewport().setShowAnnotation(false);
812 if (!af.getViewport().isShowAnnotation())
814 doUpdateAnnotation = true;
816 .println("CMD no-annotation executed successfully!");
820 if (aparser.contains(ArgsParser.NOSORTBYTREE))
822 af.getViewport().setSortByTree(false);
823 if (!af.getViewport().getSortByTree())
825 doUpdateAnnotation = true;
827 .println("CMD [-nosortbytree] executed successfully!");
830 if (doUpdateAnnotation)
832 af.setMenusForViewport();
833 af.alignPanel.updateLayout();
835 data = aparser.getValue(ArgsParser.TREE, true);
841 "CMD [-tree " + data + "] executed successfully!");
842 NewickFile nf = new NewickFile(data,
843 AppletFormatAdapter.checkProtocol(data));
845 .setCurrentTree(af.showNewickTree(nf, data).getTree());
846 } catch (IOException ex)
848 System.err.println("Couldn't add tree " + data);
849 ex.printStackTrace(System.err);
852 // TODO - load PDB structure(s) to alignment JAL-629
853 // (associate with identical sequence in alignment, or a specified
857 loadAppletParams(aparser, af);
866 if (groovyscript != null)
868 // Execute the groovy script after we've done all the rendering
870 // and before any images or figures are generated.
871 System.out.println("Executing script " + groovyscript);
872 executeGroovyScript(groovyscript, af);
873 System.out.println("CMD groovy[" + groovyscript
874 + "] executed successfully!");
878 createOutputFiles(aparser, af, format);
879 while (aparser.getSize() > 0)
881 System.out.println("Unknown arg: " + aparser.nextValue());
885 AlignFrame startUpAlframe = null;
886 // We'll only open the default file if the desktop is visible.
888 // ////////////////////
890 if (!isJS && !headless && file == null && !haveImport
891 && jalview.bin.Cache.getDefault("SHOW_STARTUP_FILE", true))
898 file = jalview.bin.Cache.getDefault("STARTUP_FILE",
899 jalview.bin.Cache.getDefault("www.jalview.org",
900 "http://www.jalview.org")
901 + "/examples/exampleFile_2_7.jar");
903 "http://www.jalview.org/examples/exampleFile_2_3.jar"))
905 // hardwire upgrade of the startup file
906 file.replace("_2_3.jar", "_2_7.jar");
907 // and remove the stale setting
908 jalview.bin.Cache.removeProperty("STARTUP_FILE");
911 protocol = DataSourceType.FILE;
913 if (file.indexOf("http:") > -1)
915 protocol = DataSourceType.URL;
918 if (file.endsWith(".jar"))
920 format = FileFormat.Jalview;
926 format = new IdentifyFile().identify(file, protocol);
927 } catch (FileFormatException e)
933 startUpAlframe = new FileLoader(!headless)
934 .loadFileWaitTillLoaded(file, protocol, format);
935 // extract groovy arguments before anything else.
938 // Once all other stuff is done, execute any groovy scripts (in order)
939 if (groovyscript != null)
941 if (Cache.groovyJarsPresent())
943 System.out.println("Executing script " + groovyscript);
944 executeGroovyScript(groovyscript, startUpAlframe);
949 "Sorry. Groovy Support is not available, so ignoring the provided groovy script "
953 // and finally, turn off batch mode indicator - if the desktop still exists
958 desktop.setProgressBar(null, progress);
960 desktop.setInBatchMode(false);
966 private boolean checkStartVamas(ArgsParser aparser)
968 String vamsasImport = aparser.getValue(ArgsParser.VDOC);
969 String vamsasSession = aparser.getValue(ArgsParser.VSESS);
970 if (vamsasImport == null && vamsasSession == null)
974 if (desktop == null || headless)
977 "Headless vamsas sessions not yet supported. Sorry.");
980 boolean haveImport = (vamsasImport != null);
983 // if we have a file, start a new session and import it.
984 boolean inSession = false;
987 DataSourceType viprotocol = AppletFormatAdapter
988 .checkProtocol(vamsasImport);
989 if (viprotocol == DataSourceType.FILE)
991 inSession = desktop.vamsasImport(new File(vamsasImport));
993 else if (viprotocol == DataSourceType.URL)
995 inSession = desktop.vamsasImport(new URL(vamsasImport));
998 } catch (Exception e)
1000 System.err.println("Exeption when importing " + vamsasImport
1001 + " as a vamsas document.");
1002 e.printStackTrace();
1006 System.err.println("Failed to import " + vamsasImport
1007 + " as a vamsas document.");
1011 System.out.println("Imported Successfully into new session "
1012 + desktop.getVamsasApplication().getCurrentSession());
1015 if (vamsasSession != null)
1017 if (vamsasImport != null)
1019 // close the newly imported session and import the Jalview specific
1020 // remnants into the new session later on.
1021 desktop.vamsasStop_actionPerformed(null);
1023 // now join the new session
1026 if (desktop.joinVamsasSession(vamsasSession))
1029 "Successfully joined vamsas session " + vamsasSession);
1033 System.err.println("WARNING: Failed to join vamsas session "
1036 } catch (Exception e)
1039 "ERROR: Failed to join vamsas session " + vamsasSession);
1040 e.printStackTrace();
1042 if (vamsasImport != null)
1044 // the Jalview specific remnants can now be imported into the new
1045 // session at the user's leisure.
1047 "Skipping Push for import of data into existing vamsas session.");
1053 // desktop.getVamsasApplication().push_update();
1060 * Writes an output file for each format (if any) specified in the
1061 * command-line arguments. Supported formats are currently
1070 * A format parameter should be followed by a parameter specifying the output
1071 * file name. {@code imgMap} parameters should follow those for the
1072 * corresponding alignment image output.
1078 private void createOutputFiles(ArgsParser aparser, AlignFrame af,
1081 String imageName = "unnamed.png";
1082 while (aparser.getSize() > 1)
1084 String outputFormat = aparser.nextValue();
1085 String file = aparser.nextValue();
1086 // System.out.println("format " + outputFormat);
1088 if (outputFormat.equalsIgnoreCase("png"))
1090 af.createPNG(new File(file));
1091 imageName = (new File(file)).getName();
1092 System.out.println("Creating PNG image: " + file);
1095 else if (outputFormat.equalsIgnoreCase("svg"))
1097 File imageFile = new File(file);
1098 imageName = imageFile.getName();
1099 af.createSVG(imageFile);
1100 System.out.println("Creating SVG image: " + file);
1103 else if (outputFormat.equalsIgnoreCase("html"))
1105 File imageFile = new File(file);
1106 imageName = imageFile.getName();
1107 HtmlSvgOutput htmlSVG = new HtmlSvgOutput(af.alignPanel);
1108 htmlSVG.exportHTML(file);
1110 System.out.println("Creating HTML image: " + file);
1113 else if (outputFormat.equalsIgnoreCase("biojsmsa"))
1117 System.err.println("The output html file must not be null");
1122 BioJsHTMLOutput.refreshVersionInfo(
1123 BioJsHTMLOutput.BJS_TEMPLATES_LOCAL_DIRECTORY);
1124 } catch (URISyntaxException e)
1126 e.printStackTrace();
1128 BioJsHTMLOutput bjs = new BioJsHTMLOutput(af.alignPanel);
1129 bjs.exportHTML(file);
1130 System.out.println("Creating BioJS MSA Viwer HTML file: " + file);
1133 else if (outputFormat.equalsIgnoreCase("imgMap"))
1135 af.createImageMap(new File(file), imageName);
1136 System.out.println("Creating image map: " + file);
1139 else if (outputFormat.equalsIgnoreCase("eps"))
1141 File outputFile = new File(file);
1143 "Creating EPS file: " + outputFile.getAbsolutePath());
1144 af.createEPS(outputFile);
1148 af.saveAlignment(file, format);
1149 if (af.isSaveAlignmentSuccessful())
1152 "Written alignment in " + format + " format to " + file);
1156 System.out.println("Error writing file " + file + " in " + format
1163 private static void showUsage()
1166 "Usage: jalview -open [FILE] [OUTPUT_FORMAT] [OUTPUT_FILE]\n\n"
1167 + "-nodisplay\tRun Jalview without User Interface.\n"
1168 + "-props FILE\tUse the given Jalview properties file instead of users default.\n"
1169 + "-colour COLOURSCHEME\tThe colourscheme to be applied to the alignment\n"
1170 + "-annotations FILE\tAdd precalculated annotations to the alignment.\n"
1171 + "-tree FILE\tLoad the given newick format tree file onto the alignment\n"
1172 + "-features FILE\tUse the given file to mark features on the alignment.\n"
1173 + "-fasta FILE\tCreate alignment file FILE in Fasta format.\n"
1174 + "-clustal FILE\tCreate alignment file FILE in Clustal format.\n"
1175 + "-pfam FILE\tCreate alignment file FILE in PFAM format.\n"
1176 + "-msf FILE\tCreate alignment file FILE in MSF format.\n"
1177 + "-pileup FILE\tCreate alignment file FILE in Pileup format\n"
1178 + "-pir FILE\tCreate alignment file FILE in PIR format.\n"
1179 + "-blc FILE\tCreate alignment file FILE in BLC format.\n"
1180 + "-json FILE\tCreate alignment file FILE in JSON format.\n"
1181 + "-jalview FILE\tCreate alignment file FILE in Jalview format.\n"
1182 + "-png FILE\tCreate PNG image FILE from alignment.\n"
1183 + "-svg FILE\tCreate SVG image FILE from alignment.\n"
1184 + "-html FILE\tCreate HTML file from alignment.\n"
1185 + "-biojsMSA FILE\tCreate BioJS MSA Viewer HTML file from alignment.\n"
1186 + "-imgMap FILE\tCreate HTML file FILE with image map of PNG image.\n"
1187 + "-eps FILE\tCreate EPS file FILE from alignment.\n"
1188 + "-questionnaire URL\tQueries the given URL for information about any Jalview user questionnaires.\n"
1189 + "-noquestionnaire\tTurn off questionnaire check.\n"
1190 + "-nonews\tTurn off check for Jalview news.\n"
1191 + "-nousagestats\tTurn off google analytics tracking for this session.\n"
1192 + "-sortbytree OR -nosortbytree\tEnable or disable sorting of the given alignment by the given tree\n"
1194 // "-setprop PROPERTY=VALUE\tSet the given Jalview property,
1195 // after all other properties files have been read\n\t
1196 // (quote the 'PROPERTY=VALUE' pair to ensure spaces are
1197 // passed in correctly)"
1198 + "-jabaws URL\tSpecify URL for Jabaws services (e.g. for a local installation).\n"
1199 + "-fetchfrom nickname\tQuery nickname for features for the alignments and display them.\n"
1201 // "-vdoc vamsas-document\tImport vamsas document into new
1202 // session or join existing session with same URN\n"
1203 // + "-vses vamsas-session\tJoin session with given URN\n"
1204 + "-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"
1205 + "\n~Read documentation in Application or visit http://www.jalview.org for description of Features and Annotations file~\n\n");
1208 private static void startUsageStats(final Desktop desktop)
1211 * start a User Config prompt asking if we can log usage statistics.
1213 PromptUserConfig prompter = new PromptUserConfig(
1214 Desktop.getDesktopPane(), "USAGESTATS",
1215 "Jalview Usage Statistics",
1216 "Do you want to help make Jalview better by enabling "
1217 + "the collection of usage statistics with Google Analytics ?"
1218 + "\n\n(you can enable or disable usage tracking in the preferences)",
1225 "Initialising googletracker for usage stats.");
1226 Cache.initGoogleTracker();
1227 Cache.log.debug("Tracking enabled.");
1234 Cache.log.debug("Not enabling Google Tracking.");
1237 desktop.addDialogThread(prompter);
1241 * Locate the given string as a file and pass it to the groovy interpreter.
1243 * @param groovyscript
1244 * the script to execute
1245 * @param jalviewContext
1246 * the Jalview Desktop object passed in to the groovy binding as the
1249 private void executeGroovyScript(String groovyscript, AlignFrame af)
1252 * for scripts contained in files
1259 if (groovyscript.trim().equals("STDIN"))
1261 // read from stdin into a tempfile and execute it
1264 tfile = File.createTempFile("jalview", "groovy");
1265 PrintWriter outfile = new PrintWriter(
1266 new OutputStreamWriter(new FileOutputStream(tfile)));
1267 BufferedReader br = new BufferedReader(
1268 new InputStreamReader(System.in));
1270 while ((line = br.readLine()) != null)
1272 outfile.write(line + "\n");
1278 } catch (Exception ex)
1280 System.err.println("Failed to read from STDIN into tempfile "
1281 + ((tfile == null) ? "(tempfile wasn't created)"
1282 : tfile.toString()));
1283 ex.printStackTrace();
1288 sfile = tfile.toURI().toURL();
1289 } catch (Exception x)
1292 "Unexpected Malformed URL Exception for temporary file created from STDIN: "
1294 x.printStackTrace();
1302 sfile = new URI(groovyscript).toURL();
1303 } catch (Exception x)
1305 tfile = new File(groovyscript);
1306 if (!tfile.exists())
1308 System.err.println("File '" + groovyscript + "' does not exist.");
1311 if (!tfile.canRead())
1313 System.err.println("File '" + groovyscript + "' cannot be read.");
1316 if (tfile.length() < 1)
1318 System.err.println("File '" + groovyscript + "' is empty.");
1323 sfile = tfile.getAbsoluteFile().toURI().toURL();
1324 } catch (Exception ex)
1326 System.err.println("Failed to create a file URL for "
1327 + tfile.getAbsoluteFile());
1334 Map<String, Object> vbinding = new HashMap<>();
1335 vbinding.put("Jalview", this);
1338 vbinding.put("currentAlFrame", af);
1340 Binding gbinding = new Binding(vbinding);
1341 GroovyScriptEngine gse = new GroovyScriptEngine(new URL[] { sfile });
1342 gse.run(sfile.toString(), gbinding);
1343 if ("STDIN".equals(groovyscript))
1345 // delete temp file that we made -
1346 // only if it was successfully executed
1349 } catch (Exception e)
1351 System.err.println("Exception Whilst trying to execute file " + sfile
1352 + " as a groovy script.");
1353 e.printStackTrace(System.err);
1358 public AlignFrame[] getAlignFrames()
1360 return desktop == null ? new AlignFrame[] { getCurrentAlignFrame() }
1361 : Desktop.getAlignFrames();
1366 * Quit method delegates to Desktop.quit - unless running in headless mode
1367 * when it just ends the JVM
1371 if (jsFunctionExec != null)
1373 jsFunctionExec.tidyUp();
1374 jsFunctionExec = null;
1377 if (desktop != null)
1388 * Get the SwingJS applet ID and combine that with the frameType
1391 * "alignment", "desktop", etc., or null
1394 public static String getAppID(String frameType)
1396 String id = Cache.getProperty("Info.j2sAppletID");
1401 return id + (frameType == null ? "" : "-" + frameType);
1405 * Handle all JalviewLite applet parameters
1410 private void loadAppletParams(ArgsParser aparser, AlignFrame af)
1412 JalviewApp app = new JalviewApp()
1417 // These are methods that are in JalviewLite that various classes call
1418 // but are not in JalviewLiteJsApi. Or, even if they are, other classes
1420 // them to JalviewLite directly. Some may not be necessary, but they have
1422 // be at least mentioned here, or the classes calling them should
1424 // JalviewLite itself.
1426 private boolean alignPDBStructures; // From JalviewLite; not implemented
1428 private Hashtable<String, Hashtable<String, String[]>> jsmessages;
1430 private Hashtable<String, int[]> jshashes;
1433 public String getParameter(String name)
1435 return aparser.getAppletValue(name, null);
1439 public boolean getDefaultParameter(String name, boolean def)
1442 return ((stn = getParameter(name)) == null ? def
1443 : "true".equalsIgnoreCase(stn));
1447 * Get the applet-like document base even though this is an application.
1450 public URL getDocumentBase()
1452 return Platform.getDocumentBase();
1456 * Get the applet-like code base even though this is an application.
1459 public URL getCodeBase()
1461 return Platform.getCodeBase();
1465 public AlignViewportI getViewport()
1467 return af.getViewport();
1475 public boolean parseFeaturesFile(String filename,
1476 DataSourceType protocol)
1478 return af.parseFeaturesFile(filename, protocol);
1486 public boolean loadScoreFile(String sScoreFile) throws IOException
1488 af.loadJalviewDataFile(sScoreFile, null, null, null);
1493 * annotations, jpredfile, jnetfile
1497 public void updateForAnnotations()
1499 af.updateForAnnotations();
1503 public void loadTree(NewickFile fin, String treeFile)
1506 // n/a -- already done by standard Jalview command line processing
1510 public void setAlignPdbStructures(boolean defaultParameter)
1512 alignPDBStructures = true;
1516 public void newStructureView(PDBEntry pdb, SequenceI[] seqs,
1517 String[] chains, DataSourceType protocol)
1519 StructureViewer.launchStructureViewer(af.alignPanel, pdb, seqs);
1523 public void setFeatureGroupState(String[] groups, boolean state)
1525 af.setFeatureGroupState(groups, state);
1529 public void alignedStructureView(PDBEntry[] pdb, SequenceI[][] seqs,
1530 String[][] chains, String[] protocols)
1533 "Jalview applet interface alignedStructureView not implemented");
1537 public void newFeatureSettings()
1540 "Jalview applet interface newFeatureSettings not implemented");
1543 private Vector<Runnable> jsExecQueue;
1546 public Vector<Runnable> getJsExecQueue(JSFunctionExec exec)
1548 jsFunctionExec = exec;
1549 return (jsExecQueue == null ? (jsExecQueue = new Vector<>())
1554 public AppletContext getAppletContext()
1556 // TODO Auto-generated method stub
1561 public boolean isJsfallbackEnabled()
1563 // TODO Auto-generated method stub
1568 public JSObject getJSObject()
1570 // TODO Auto-generated method stub
1575 public StructureSelectionManagerProvider getStructureSelectionManagerProvider()
1577 // TODO Q: what exactly is this? BH
1582 public void updateColoursFromMouseOver(Object source,
1583 MouseOverStructureListener mouseOverStructureListener)
1585 // TODO Auto-generated method stub
1590 public Object[] getSelectionForListener(SequenceGroup seqsel,
1591 ColumnSelection colsel, HiddenColumns hidden,
1592 SelectionSource source, Object alignFrame)
1594 return appLoader.getSelectionForListener(getCurrentAlignFrame(),
1595 seqsel, colsel, hidden, source, alignFrame);
1599 public String arrayToSeparatorList(String[] array)
1601 return appLoader.arrayToSeparatorList(array);
1605 public Hashtable<String, int[]> getJSHashes()
1607 return (jshashes == null ? (jshashes = new Hashtable<>())
1612 public Hashtable<String, Hashtable<String, String[]>> getJSMessages()
1614 return (jsmessages == null ? (jsmessages = new Hashtable<>())
1619 public Object getFrameForSource(VamsasSource source)
1624 if (source instanceof jalview.gui.AlignViewport
1625 && source == (af = getCurrentAlignFrame()).getViewport())
1627 // should be valid if it just generated an event!
1630 // TODO: ensure that if '_af' is specified along with a handler
1631 // function, then only events from that alignFrame are sent to that
1638 public FeatureRenderer getNewFeatureRenderer(AlignViewportI vp)
1640 return new jalview.gui.FeatureRenderer((AlignmentPanel) vp);
1645 appLoader = new JalviewAppLoader(true);
1646 appLoader.load(app);
1651 * @see jalview.bin.JalviewLiteJsApi#getSelectedSequences()
1654 public String getSelectedSequences()
1656 return getSelectedSequencesFrom(getCurrentAlignFrame());
1661 * @see jalview.bin.JalviewLiteJsApi#getSelectedSequences(java.lang.String)
1664 public String getSelectedSequences(String sep)
1666 return getSelectedSequencesFrom(getCurrentAlignFrame(), sep);
1671 * @see jalview.bin.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
1675 public String getSelectedSequencesFrom(AlignFrameI alf)
1679 alf = getCurrentAlignFrame();
1681 return getSelectedSequencesFrom(alf, null);
1686 * @see jalview.bin.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
1687 * .AlignFrame, java.lang.String)
1690 public String getSelectedSequencesFrom(AlignFrameI alf, String sep)
1694 alf = getCurrentAlignFrame();
1696 return appLoader.getSelectedSequencesFrom(alf, sep);
1701 * @see jalview.bin.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
1702 * .AlignFrame, java.lang.String)
1705 public void highlight(String sequenceId, String position,
1706 String alignedPosition)
1708 highlightIn(null, sequenceId, position,
1713 public void highlightIn(AlignFrameI alf, String sequenceId,
1714 String position, String alignedPosition)
1718 alf = getCurrentAlignFrame();
1720 appLoader.highlightIn(alf, sequenceId, position, alignedPosition);
1724 public void select(String sequenceIds, String columns)
1726 selectIn(getCurrentAlignFrame(), sequenceIds, columns, null);
1730 public void select(String sequenceIds, String columns, String sep)
1732 selectIn(null, sequenceIds, columns, sep);
1736 public void selectIn(AlignFrameI alf, String sequenceIds, String columns)
1738 selectIn(alf, sequenceIds, columns, null);
1742 public void selectIn(AlignFrameI alf, String sequenceIds, String columns,
1747 alf = getCurrentAlignFrame();
1749 appLoader.selectIn(alf, sequenceIds, columns, sep);
1753 public String getSelectedSequencesAsAlignment(String format,
1756 return getSelectedSequencesAsAlignmentFrom(null,
1761 public String getSelectedSequencesAsAlignmentFrom(AlignFrameI alf,
1762 String format, String sep)
1766 alf = getCurrentAlignFrame();
1768 return appLoader.getSelectedSequencesAsAlignmentFrom(alf, format, sep);
1772 public String getAlignmentOrder()
1774 return getAlignmentFrom(getCurrentAlignFrame(), null);
1778 public String getAlignmentOrderFrom(AlignFrameI alf)
1780 return getAlignmentFrom(alf, null);
1784 public String getAlignmentOrderFrom(AlignFrameI alf, String sep)
1788 alf = getCurrentAlignFrame();
1790 return appLoader.getAlignmentOrderFrom(alf, sep);
1794 public String orderBy(String order, String undoName)
1796 return orderBy(order, undoName, null);
1800 public String orderBy(String order, String undoName, String sep)
1802 return orderAlignmentBy(getCurrentAlignFrame(), order, undoName, sep);
1806 public String orderAlignmentBy(AlignFrameI alf, String order,
1807 String undoName, String sep)
1811 alf = getCurrentAlignFrame();
1813 return appLoader.orderAlignmentBy(alf, order, undoName, sep);
1817 public String getAlignment(String format)
1819 return getAlignmentFrom(null, format, null);
1823 public String getAlignmentFrom(AlignFrameI alf, String format)
1825 return getAlignmentFrom(alf, format, null);
1829 public String getAlignment(String format, String suffix)
1831 return getAlignmentFrom(getCurrentAlignFrame(), format, suffix);
1835 public String getAlignmentFrom(AlignFrameI alf, String format,
1838 return appLoader.getAlignmentFrom(alf, format, suffix);
1842 public void loadAnnotation(String annotation)
1844 loadAnnotationFrom(getCurrentAlignFrame(), annotation);
1848 public void loadAnnotationFrom(AlignFrameI alf, String annotation)
1852 alf = getCurrentAlignFrame();
1854 appLoader.loadAnnotationFrom(alf, annotation);
1858 public void loadFeatures(String features, boolean autoenabledisplay)
1860 loadFeaturesFrom(currentAlignFrame, features, autoenabledisplay);
1864 public boolean loadFeaturesFrom(AlignFrameI alf, String features,
1865 boolean autoenabledisplay)
1869 alf = getCurrentAlignFrame();
1871 return appLoader.loadFeaturesFrom(alf, features, autoenabledisplay);
1875 public String getFeatures(String format)
1877 return getFeaturesFrom(null, format);
1881 public String getFeaturesFrom(AlignFrameI alf, String format)
1885 alf = getCurrentAlignFrame();
1887 return appLoader.getFeaturesFrom(alf, format);
1891 public String getAnnotation()
1893 return getAnnotationFrom(null);
1897 public String getAnnotationFrom(AlignFrameI alf)
1901 alf = getCurrentAlignFrame();
1903 return appLoader.getAnnotationFrom(alf);
1907 public AlignFrameI newView()
1909 return newViewFrom(null, null);
1913 public AlignFrameI newView(String name)
1915 return newViewFrom(null, name);
1919 public AlignFrameI newViewFrom(AlignFrameI alf)
1921 return newViewFrom(alf, null);
1925 public AlignFrameI newViewFrom(AlignFrameI alf, String name)
1929 alf = getCurrentAlignFrame();
1931 return appLoader.newViewFrom(alf, name);
1935 public AlignFrameI loadAlignment(String text, String title)
1937 return appLoader.loadAlignment(text, AlignFrame.DEFAULT_WIDTH,
1938 AlignFrame.DEFAULT_HEIGHT, title);
1942 public boolean addPdbFile(AlignFrameI alFrame, String sequenceId,
1943 String pdbEntryString, String pdbFile)
1945 if (alFrame == null)
1947 alFrame = getCurrentAlignFrame();
1949 return appLoader.addPdbFile(alFrame, sequenceId, pdbEntryString,
1954 public void scrollViewToIn(AlignFrameI alf, String topRow,
1955 String leftHandColumn)
1959 alf = getCurrentAlignFrame();
1961 appLoader.scrollViewToIn(alf, topRow, leftHandColumn);
1965 public void scrollViewToRowIn(AlignFrameI alf, String topRow)
1969 alf = getCurrentAlignFrame();
1971 appLoader.scrollViewToRowIn(alf, topRow);
1975 public void scrollViewToColumnIn(AlignFrameI alf, String leftHandColumn)
1979 alf = getCurrentAlignFrame();
1981 appLoader.scrollViewToColumnIn(alf, leftHandColumn);
1985 public String getFeatureGroups()
1987 return getFeatureGroupsOn(null);
1991 public String getFeatureGroupsOn(AlignFrameI alf)
1995 alf = getCurrentAlignFrame();
1997 return appLoader.getFeatureGroupsOn(alf);
2001 public String getFeatureGroupsOfState(boolean visible)
2003 return getFeatureGroupsOfStateOn(null, visible);
2007 public String getFeatureGroupsOfStateOn(AlignFrameI alf, boolean visible)
2011 alf = getCurrentAlignFrame();
2013 return appLoader.getFeatureGroupsOfStateOn(alf, visible);
2017 public void setFeatureGroupState(String groups, boolean state)
2018 { // JalviewLite API
2019 setFeatureGroupStateOn(null, groups, state);
2023 public void setFeatureGroupStateOn(AlignFrameI alf, String groups,
2028 alf = getCurrentAlignFrame();
2030 appLoader.setFeatureGroupStateOn(alf, groups, state);
2034 public String getSeparator()
2036 return appLoader.getSeparator();
2040 public void setSeparator(String separator)
2042 appLoader.setSeparator(separator);
2046 public String getJsMessage(String messageclass, String viewId)
2048 // see http://www.jalview.org/examples/jalviewLiteJs.html
2053 * Open a new Tree panel on the desktop statically. Params are standard (not
2054 * set by Groovy). No dialog is opened.
2059 * @return null, or the string "label.you_need_at_least_n_sequences" if number
2060 * of sequences selected is inappropriate
2063 public Object openTreePanel(AlignFrame af, String treeType,
2068 af = getCurrentAlignFrame();
2070 return CalculationChooser.openTreePanel(af, treeType, modelName, null);
2074 * public static method for JalviewJS API to open a PCAPanel without
2075 * necessarily using a dialog.
2079 * @return the PCAPanel, or the string "label.you_need_at_least_n_sequences"
2080 * if number of sequences selected is inappropriate
2083 public Object openPcaPanel(AlignFrame af, String modelName)
2087 af = getCurrentAlignFrame();
2089 return CalculationChooser.openPcaPanel(af, modelName, null);
2093 public String getSelectedSequencesAsAlignment(String format,
2096 return getSelectedSequencesAsAlignmentFrom(null,
2101 public String getSelectedSequencesAsAlignmentFrom(AlignFrameI alf,
2102 String format, boolean suffix)
2106 alf = getCurrentAlignFrame();
2108 return appLoader.getSelectedSequencesAsAlignmentFrom(alf, format,
2113 public String arrayToSeparatorList(String[] array)
2115 return appLoader.arrayToSeparatorList(array);
2119 public String[] separatorListToArray(String list)
2121 return appLoader.separatorListToArray(list);
2124 //// probably not needed in JalviewJS -- From when Jmol and Jalview did not
2125 //// have a direct connection?
2128 public void setMouseoverListener(String listener)
2130 // TODO Auto-generated method stub
2135 public void setMouseoverListener(AlignFrameI af, String listener)
2137 // TODO Auto-generated method stub
2142 public void setSelectionListener(String listener)
2144 // TODO Auto-generated method stub
2149 public void setSelectionListener(AlignFrameI af, String listener)
2151 // TODO Auto-generated method stub
2156 public void setStructureListener(String listener, String modelSet)
2158 // TODO Auto-generated method stub
2163 public void removeJavascriptListener(AlignFrameI af, String listener)
2165 // TODO Auto-generated method stub
2170 public void mouseOverStructure(String pdbResNum, String chain,
2173 // TODO Auto-generated method stub
2178 public void showOverview()
2180 currentAlignFrame.overviewMenuItem_actionPerformed(null);
2183 public void notifyWorker(AlignCalcWorkerI worker, String status)
2185 // System.out.println("Jalview worker " + worker.getClass().getSimpleName()