3 import java.awt.EventQueue;
4 //import java.applet.AppletContext;
5 import java.io.IOException;
7 import java.util.ArrayList;
9 import java.util.StringTokenizer;
10 import java.util.Vector;
12 import jalview.bin.ArgsParser;
13 import jalview.bin.Jalview;
14 import jalview.bin.JalviewJSApi;
15 import jalview.datamodel.Alignment;
16 import jalview.datamodel.AlignmentI;
17 import jalview.datamodel.AlignmentOrder;
18 import jalview.datamodel.ColumnSelection;
19 import jalview.datamodel.HiddenColumns;
20 import jalview.datamodel.PDBEntry;
21 import jalview.datamodel.Sequence;
22 import jalview.datamodel.SequenceGroup;
23 import jalview.datamodel.SequenceI;
24 import jalview.gui.AlignFrame;
25 import jalview.gui.AlignViewport;
26 import jalview.gui.CalculationChooser;
27 import jalview.gui.Desktop;
28 import jalview.gui.StructureViewer;
29 import jalview.io.AnnotationFile;
30 import jalview.io.AppletFormatAdapter;
31 import jalview.io.DataSourceType;
32 import jalview.io.FeaturesFile;
33 import jalview.io.FileFormat;
34 import jalview.io.FileFormatI;
35 import jalview.io.FileFormats;
36 import jalview.io.IdentifyFile;
37 import jalview.io.JPredFile;
38 import jalview.io.JnetAnnotationMaker;
39 import jalview.io.NewickFile;
40 import jalview.structure.SelectionListener;
41 import jalview.structure.SelectionSource;
42 import jalview.structure.StructureSelectionManager;
43 import jalview.structure.VamsasSource;
44 import jalview.util.HttpUtils;
45 import jalview.util.MessageManager;
46 import jalview.util.Platform;
48 //import netscape.javascript.JSObject;
51 * Basically the JalviewLite application, but without JalviewLite
56 public class JalviewJSApp implements JalviewJSApi
58 private ArgsParser aparser;
60 private boolean debug;
62 private String[] ret = new String[1];
64 private String separator = "\u00AC"; // JalviewLite note: the default used to
65 // be '|', but many sequence IDS include
69 public JalviewJSApp(ArgsParser aparser)
71 this.aparser = aparser;
72 Platform.setAppClass(this);
76 public void load(AlignFrame af)
78 String sep = (String) getAppletParameter("separator", true);
87 throw new Error(MessageManager
88 .getString("error.invalid_separator_parameter"));
102 // These are methods that are in JalviewLite that various classes call
103 // but are not in JalviewLiteJsApi. Or, even if they are, other classes
105 // them to JalviewLite directly. Some may not be necessary, but they have
107 // be at least mentioned here, or the classes calling them should
109 // JalviewLite itself.
111 // private boolean alignPDBStructures; // From JalviewLite; not implemented
115 public String getParameter(String name)
117 return (String) getAppletParameter(name, true);
121 public Object getAppletParameter(String name, boolean asString)
123 return aparser.getAppletValue(name, null, asString);
127 * Get the applet-like code base even though this is an application.
131 public URL getCodeBase()
133 return Platform.getCodeBase();
137 * Get the applet-like document base even though this is an application.
141 public URL getDocumentBase()
143 return Platform.getDocumentBase();
147 public Object getFrameForSource(VamsasSource source)
152 if (source instanceof jalview.gui.AlignViewport
153 && source == (af = Jalview.getCurrentAlignFrame())
156 // should be valid if it just generated an event!
159 // TODO: ensure that if '_af' is specified along with a handler
160 // function, then only events from that alignFrame are sent to that
167 public Object[] getSelectionForListener(SequenceGroup seqsel,
168 ColumnSelection colsel, HiddenColumns hidden,
169 SelectionSource source, Object alignFrame)
171 return getSelectionForListener(null, seqsel, colsel, hidden, source,
181 public boolean loadScoreFile(String sScoreFile) throws IOException
183 return loadScoreFile(null, sScoreFile);
186 public boolean loadScoreFile(AlignFrame af, String sScoreFile) throws IOException
188 (af == null ? Jalview.getCurrentAlignFrame() : af).loadJalviewDataFile(sScoreFile, null, null, null);
192 public void loadTree(AlignFrame af, NewickFile nf, String treeFile) throws IOException
195 af = Jalview.getCurrentAlignFrame();
197 .setCurrentTree(af.showNewickTree(nf, treeFile).getTree());
201 public void newFeatureSettings()
204 "Jalview applet interface newFeatureSettings not implemented");
209 // public void setAlignPdbStructures(boolean defaultParameter)
211 // alignPDBStructures = true;
216 public void newStructureView(PDBEntry pdb, SequenceI[] seqs,
217 String[] chains, DataSourceType protocol)
219 newStructureView(null, pdb, seqs, chains, protocol);
224 * @j2sAlias showStructure
227 public void showStructure(AlignFrame af, String pdbID, String fileType) {
229 af = Jalview.getCurrentAlignFrame();
231 SequenceI[] seqs = null;
233 seqs = af.getViewport().getSequenceSelection();
234 if (seqs.length == 0)
235 seqs = af.getViewport().getAlignment().getSequencesArray();
236 for (int i = 0; i < seqs.length; i++) {
237 Vector<PDBEntry> list = seqs[i].getAllPDBEntries();
238 if (list.size() > 0) {
247 pe = new PDBEntry(pdbID, null, fileType);
248 List<SequenceI> list = af.getViewport().getAlignment().getSequences();
249 List<SequenceI> tmp = new ArrayList<SequenceI>();
250 for (int i = 0; i < list.size(); i++) {
251 SequenceI seq = list.get(i);
252 if (seq.getPDBEntry(pdbID) != null) {
256 seqs = tmp.toArray(new SequenceI[tmp.size()]);
257 af.alignPanel.selectSequences(tmp);
259 StructureViewer.launchStructureViewer(
264 public void newStructureView(AlignFrame af, PDBEntry pdb,
265 SequenceI[] seqs, String[] chains, DataSourceType protocol)
267 StructureViewer.launchStructureViewer(
268 (af == null ? Jalview.getCurrentAlignFrame() : af).alignPanel,
279 public boolean parseFeaturesFile(String filename, DataSourceType protocol)
281 return parseFeaturesFile(null, filename, protocol);
285 * @j2sAlias parseFeatureFile
292 public boolean parseFeaturesFile(AlignFrame af, String filename, DataSourceType protocol)
294 return (af == null ? Jalview.getCurrentAlignFrame() : af).parseFeaturesFile(filename, protocol);
298 * annotations, jpredfile, jnetfile
303 public void updateForAnnotations()
305 updateForAnnotations(null);
308 public void updateForAnnotations(AlignFrame af)
310 (af == null ? Jalview.getCurrentAlignFrame() : af).updateForAnnotations();
314 public boolean addPdbFile(AlignFrame alf, String sequenceId, String pdbId,
319 alf = Jalview.getCurrentAlignFrame();
321 SequenceI seq = alf.getViewport().getAlignment().findName(sequenceId);
324 Vector<PDBEntry> pdbe = seq.getAllPDBEntries();
325 PDBEntry pdbentry = null;
326 if (pdbe != null && pdbe.size() > 0)
328 for (int pe = 0, peSize = pdbe.size(); pe < peSize; pe++)
330 pdbentry = pdbe.elementAt(pe);
331 if (!pdbentry.getId().equals(pdbId)
332 || pdbFile != null && !pdbentry.getFile().equals(pdbFile))
338 if (pdbentry == null)
340 pdbentry = new PDBEntry(pdbId, null, pdbFile);
343 DataSourceType protocol = AppletFormatAdapter
344 .resolveProtocol(pdbFile, FileFormat.PDB);
345 if (protocol == null)
347 pdbentry.setProperty("protocol", protocol);
349 seq.addPDBId(pdbentry);
350 alf.alignPanel.getStructureSelectionManager()
351 .registerPDBEntry(pdbentry);
358 // public String arrayToSeparatorList(String[] array)
360 // return arrayToSeparatorList(array, separator);
364 // * concatenate the list with separator
367 // * @param separator
368 // * @return concatenated string
370 // public static String arrayToSeparatorList(String[] list, String separator)
372 // // TODO use StringUtils version
373 // StringBuffer v = new StringBuffer();
374 // if (list != null && list.length > 0)
376 // for (int i = 0, iSize = list.length; i < iSize; i++)
378 // if (list[i] != null)
382 // v.append(separator);
384 // v.append(list[i]);
390 // // .println("Returning '" + separator + "' separated List:\n");
391 // // System.err.println(v);
393 // return v.toString();
397 // // System.err.println(
398 // // "Returning empty '" + separator + "' separated List\n");
400 // return "" + separator;
404 public String getAlignment(String format)
406 return getAlignmentFrom(null, format, null);
410 * suffix string "true"/"false" (default true)
411 * passed to AlnFile class controls whether /START-END is added to
415 public String getAlignment(String format, String suffix)
417 return getAlignmentFrom(Jalview.getCurrentAlignFrame(), format, suffix);
421 public String getAlignmentFrom(AlignFrame alf, String format)
423 return getAlignmentFrom(alf, format, null);
427 public String getAlignmentFrom(AlignFrame alf, String format,
434 alf = Jalview.getCurrentAlignFrame();
436 boolean seqlimits = (suffix == null
437 || suffix.equalsIgnoreCase("true"));
439 FileFormatI theFormat = FileFormats.getInstance().forName(format);
440 String reply = new AppletFormatAdapter().formatSequences(theFormat,
441 alf.getViewport().getAlignment(), seqlimits);
443 } catch (IllegalArgumentException ex)
445 ex.printStackTrace();
446 return "Error retrieving alignment, possibly invalid format specifier: "
452 public String getAlignmentOrder()
454 return getAlignmentFrom(Jalview.getCurrentAlignFrame(), null);
458 public String[] getAlignmentOrderFrom(AlignFrame alf)
462 alf = Jalview.getCurrentAlignFrame();
464 AlignmentI alorder = alf.getViewport().getAlignment();
465 String[] order = new String[alorder.getHeight()];
466 for (int i = 0; i < order.length; i++)
468 order[i] = alorder.getSequenceAt(i).getName();
470 return order;// arrayToSeparatorList(order, sep);
474 public String getAnnotation()
476 return getAnnotationFrom(null);
480 public String getAnnotationFrom(AlignFrame alf)
484 alf = Jalview.getCurrentAlignFrame();
486 String annotation = new AnnotationFile()
487 .printAnnotationsForView(alf.getViewport());
492 public String[] getFeatureGroups()
494 return getFeatureGroupsOn(null);
498 public String[] getFeatureGroupsOfState(boolean visible)
500 return getFeatureGroupsOfStateOn(null, visible);
504 public String[] getFeatureGroupsOfStateOn(AlignFrame alf, boolean visible)
508 alf = Jalview.getCurrentAlignFrame();
510 return alf.getFeatureGroupsOfState(visible);
514 public String[] getFeatureGroupsOn(AlignFrame alf)
518 alf = Jalview.getCurrentAlignFrame();
520 return alf.getFeatureGroups();
524 public String getFeatures(String format)
526 return getFeaturesFrom(null, format);
530 * JavaScript interface to print the alignment frame
534 * "jalview" or "gff" with or without ";includeComplement" or
535 * ";includeNonpositional"; default with no ";" is
536 * ";includeNonpositional"
540 public String getFeaturesFrom(AlignFrame alf, String format)
544 alf = Jalview.getCurrentAlignFrame();
547 FeaturesFile formatter = new FeaturesFile();
548 format = format.toLowerCase();
549 if (format.indexOf(";") < 0)
550 format += ";includenonpositional";
551 boolean nonpos = format.indexOf(";includenonpositional") > 0;
552 boolean compl = format.indexOf(";includecomplement") >= 0;
553 if (format.startsWith("jalview"))
555 features = formatter.printJalviewFormat(
556 alf.getViewport().getAlignment().getSequencesArray(),
557 alf.alignPanel.getFeatureRenderer(), nonpos, compl);
561 features = formatter.printGffFormat(
562 alf.getViewport().getAlignment().getSequencesArray(),
563 alf.alignPanel.getFeatureRenderer(), nonpos, compl);
566 if (features == null)
575 * read sequence1...sequenceN as a raw alignment
580 public String getPastedSequence(JalviewJSApp jalviewApp)
582 StringBuffer data = new StringBuffer("PASTE");
585 while ((file = (String) getAppletParameter("sequence" + i,
588 data.append(file.toString() + "\n");
591 if (data.length() > 5)
593 file = data.toString();
600 * @see jalview.appletgui.js.JalviewLiteJsApi#getSelectedSequences()
603 public SequenceI[] getSelectedSequences()
605 return getSelectedSequencesFrom(Jalview.getCurrentAlignFrame());
610 * @see jalview.appletgui.js.JalviewLiteJsApi#getSelectedSequences(java.lang.String)
613 public SequenceI[] getSelectedSequences(String sep)
615 return getSelectedSequencesFrom(Jalview.getCurrentAlignFrame(), sep);
619 public String getSelectedSequencesAsAlignment(String format,
622 return getSelectedSequencesAsAlignmentFrom(null, format, suffix);
626 public String getSelectedSequencesAsAlignmentFrom(AlignFrame alf,
627 String format, String suffix)
632 alf = Jalview.getCurrentAlignFrame();
635 boolean seqlimits = (suffix == null || suffix.equalsIgnoreCase("true"));
638 AlignViewport vp = alf.getViewport();
639 FileFormatI theFormat = FileFormats.getInstance().forName(format);
640 if (vp.getSelectionGroup() != null)
642 // JBPNote: getSelectionAsNewSequence behaviour has changed - this
643 // method now returns a full copy of sequence data
644 // TODO consider using getSequenceSelection instead here
645 String reply = new AppletFormatAdapter().formatSequences(theFormat,
646 new Alignment(vp.getSelectionAsNewSequence()), seqlimits);
649 } catch (IllegalArgumentException ex)
651 ex.printStackTrace();
652 return "Error retrieving alignment, possibly invalid format specifier: "
660 * @see jalview.appletgui.js.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
664 public SequenceI[] getSelectedSequencesFrom(AlignFrame alf)
666 return getSelectedSequencesFrom(alf, null);
670 public SequenceI[] getSelectedSequencesFrom(AlignFrame alf, String sep)
674 alf = Jalview.getCurrentAlignFrame();
676 AlignViewport v = alf.getViewport();
677 if (v.getSelectionGroup() != null)
679 return v.getSelectionGroup()
680 .getSequencesInOrder(v.getAlignment());
686 public Object[] getSelectionForListener(AlignFrame alf,
687 SequenceGroup seqsel, ColumnSelection colsel,
688 HiddenColumns hidden, SelectionSource source, Object alignFrame)
692 alf = Jalview.getCurrentAlignFrame();
694 // System.err.println("Testing selection event relay to
695 // jsfunction:"+_listener);
697 AlignFrame src = (AlignFrame) alignFrame;
700 if (source instanceof AlignViewport && alf.getViewport() == source)
702 // should be valid if it just generated an event!
707 String[] seqs = new String[] {};
708 String[] cols = new String[] {};
709 int strt = 0, end = (src == null) ? -1
710 : src.alignPanel.av.getAlignment().getWidth();
711 if (seqsel != null && seqsel.getSize() > 0)
713 seqs = new String[seqsel.getSize()];
714 for (int i = 0; i < seqs.length; i++)
716 seqs[i] = seqsel.getSequenceAt(i).getName();
718 if (strt < seqsel.getStartRes())
720 strt = seqsel.getStartRes();
722 if (end == -1 || end > seqsel.getEndRes())
724 end = seqsel.getEndRes();
727 if (colsel != null && !colsel.isEmpty())
731 end = colsel.getMax() + 1;
733 cols = new String[colsel.getSelected().size()];
734 for (int i = 0; i < cols.length; i++)
736 cols[i] = "" + (1 + colsel.getSelected().get(i).intValue());
741 if (seqsel != null && seqsel.getSize() > 0)
743 // send a valid range, otherwise we send the empty selection
744 cols = new String[2];
745 cols[0] = "" + (1 + strt) + "-" + (1 + end);
748 return new Object[] { src, setid, seqs, cols };
753 * @see jalview.appletgui.js.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
754 * .AlignFrame, java.lang.String)
757 public void highlight(String sequenceId, String position,
758 String alignedPosition)
760 highlightIn(null, sequenceId, position, alignedPosition);
764 public void highlightIn(AlignFrame alf, final String sequenceId,
765 final String position, final String alignedPosition)
769 alf = Jalview.getCurrentAlignFrame();
771 // TODO: could try to highlight in all alignments if alf==null
772 jalview.analysis.SequenceIdMatcher matcher = new jalview.analysis.SequenceIdMatcher(
773 alf.getViewport().getAlignment().getSequencesArray());
774 final SequenceI sq = matcher.findIdMatch(sequenceId);
780 apos = Integer.valueOf(position).intValue();
782 } catch (NumberFormatException ex)
786 final int pos = apos;
787 // use vamsas listener to broadcast to all listeners in scope
788 if (alignedPosition != null && (alignedPosition.trim().length() == 0
789 || alignedPosition.toLowerCase().indexOf("false") > -1))
791 java.awt.EventQueue.invokeLater(new Runnable()
796 StructureSelectionManager
797 .getStructureSelectionManager(Desktop.getInstance())
798 .mouseOverVamsasSequence(sq, sq.findIndex(pos), null);
804 java.awt.EventQueue.invokeLater(new Runnable()
809 StructureSelectionManager
810 .getStructureSelectionManager(Desktop.getInstance())
811 .mouseOverVamsasSequence(sq, pos, null);
818 public AlignFrame loadAlignment(String text, int width, int height,
821 AlignmentI al = null;
825 FileFormatI format = new IdentifyFile().identify(text,
826 DataSourceType.PASTE);
827 al = new AppletFormatAdapter().readFile(text, DataSourceType.PASTE,
829 if (al.getHeight() > 0)
831 return new AlignFrame(al, width, height, title);
833 } catch (IOException ex)
835 ex.printStackTrace();
840 // public void setMouseoverListener(String listener)
842 // appLoader.setMouseoverListener(listener);
846 // public void setMouseoverListener(AlignFrame af, String listener)
852 public AlignFrame loadAlignment(String text, String title)
854 return loadAlignment(text, AlignFrame.DEFAULT_WIDTH,
855 AlignFrame.DEFAULT_HEIGHT, title);
859 public void loadAnnotation(String annotation)
861 loadAnnotationFrom(null, annotation);
865 public void loadAnnotationFrom(AlignFrame alf, String annotation)
869 alf = Jalview.getCurrentAlignFrame();
871 if (new AnnotationFile().annotateAlignmentView(alf.getViewport(),
872 annotation, DataSourceType.PASTE))
874 alf.alignPanel.fontChanged();
875 alf.alignPanel.setScrollValues(0, 0);
879 alf.parseFeaturesFile(annotation, DataSourceType.PASTE);
884 * Load annotations if specified by parameter. Returns true if loaded, else
891 protected boolean loadAnnotations(AlignFrame af)
893 boolean result = false;
894 String param = (String) getAppletParameter("annotations", true);
898 DataSourceType protocol = resolveFileProtocol(ret);
900 if (new AnnotationFile().annotateAlignmentView(af.getViewport(), param,
903 updateForAnnotations();
909 .println("Annotations were not added from annotation file '"
919 * Load features file and view settings as specified by parameters. Returns
920 * true if features were loaded, else false.
926 protected boolean loadFeatures(AlignFrame af)
928 boolean result = false;
929 // ///////////////////////////
930 // modify display of features
931 // we do this before any features have been loaded, ensuring any hidden
932 // groups are hidden when features first displayed
934 // hide specific groups
936 String param = (String) getAppletParameter("hidefeaturegroups", true);
939 setFeatureGroupState(af, separatorListToArray(param, separator), false);
940 // setFeatureGroupStateOn(newAlignFrame, param, false);
942 // show specific groups
943 param = (String) getAppletParameter("showfeaturegroups", true);
946 setFeatureGroupState(af, separatorListToArray(param, separator), true);
947 // setFeatureGroupStateOn(newAlignFrame, param, true);
949 // and now load features
950 param = (String) getAppletParameter("features", true);
954 DataSourceType protocol = resolveFileProtocol(ret);
956 result = parseFeaturesFile(af, ret[0], protocol);
959 param = (String) getAppletParameter("showFeatureSettings", true);
960 if (param != null && param.equalsIgnoreCase("true"))
962 newFeatureSettings();
968 public void loadFeatures(String features, boolean autoenabledisplay)
970 loadFeaturesFrom(null, features, autoenabledisplay);
974 public boolean loadFeaturesFrom(AlignFrame alf, String features,
975 boolean autoenabledisplay)
979 alf = Jalview.getCurrentAlignFrame();
981 boolean ret = alf.parseFeaturesFile(features, DataSourceType.PASTE);
986 if (autoenabledisplay)
988 alf.getViewport().setShowSequenceFeatures(true);
989 // this next was for a checkbox in JalviewLite
990 // ((AlignFrame) alf).getViewport().sequenceFeatures.setState(true);
996 * Load in a Jnetfile if specified by parameter. Returns true if loaded, else
1002 protected boolean loadJnetFile(AlignFrame af)
1004 boolean result = false;
1005 String param = (String) getAppletParameter("jnetfile", true);
1008 // jnet became jpred around 2016
1009 param = (String) getAppletParameter("jpredfile", true);
1016 DataSourceType protocol = resolveFileProtocol(ret);
1017 JPredFile predictions = new JPredFile(ret[0], protocol);
1018 JnetAnnotationMaker.add_annotation(predictions,
1019 af.getViewport().getAlignment(), 0, false);
1020 // false == do not add sequence profile from concise output
1021 af.getViewport().getAlignment().setupJPredAlignment();
1022 updateForAnnotations();
1024 } catch (Exception ex)
1026 ex.printStackTrace();
1033 * Load PDBFiles if any specified by parameter(s). Returns true if loaded,
1036 * @param loaderFrame
1039 protected boolean loadPdbFiles(AlignFrame af)
1041 boolean result = false;
1043 * <param name="alignpdbfiles" value="false/true"/> Undocumented for 2.6 -
1044 * related to JAL-434
1047 // not supported (as for JalviewLite)
1048 // boolean doAlign = false;//"true".equalsIgnoreCase("" +
1049 // getAppletParameter("alignpdbfiles", false));
1050 // setAlignPdbStructures(doAlign);
1052 * <param name="PDBfile" value="1gaq.txt PDB|1GAQ|1GAQ|A PDB|1GAQ|1GAQ|B
1055 * <param name="PDBfile2" value="1gaq.txt A=SEQA B=SEQB C=SEQB">
1057 * <param name="PDBfile3" value="1q0o Q45135_9MICO">
1060 // Accumulate pdbs here if they are heading for the same view (if
1061 // alignPdbStructures is true)
1062 // ArrayList<Object[]> pdbs = new ArrayList<>();
1063 // create a lazy matcher if we're asked to
1064 boolean relaxed = "true".equalsIgnoreCase(
1065 "" + getAppletParameter("relaxedidmatch", false));
1066 jalview.analysis.SequenceIdMatcher matcher = relaxed
1067 ? new jalview.analysis.SequenceIdMatcher(
1068 af.getViewport().getAlignment().getSequencesArray())
1071 int pdbFileCount = 0;
1075 if (pdbFileCount > 0)
1077 param = (String) getAppletParameter("PDBFILE" + pdbFileCount, true);
1081 param = (String) getAppletParameter("PDBFILE", true);
1086 PDBEntry pdb = new PDBEntry();
1089 SequenceI[] seqs = null;
1090 String[] chains = null;
1092 StringTokenizer st = new StringTokenizer(param, " ");
1094 if (st.countTokens() < 2)
1096 String sequence = (String) getAppletParameter("PDBSEQ", true);
1097 if (sequence != null)
1099 seqs = new SequenceI[] { matcher == null
1100 ? (Sequence) af.getViewport().getAlignment()
1102 : matcher.findIdMatch(sequence) };
1108 param = st.nextToken();
1109 List<SequenceI> tmp = new ArrayList<>();
1110 List<String> tmp2 = new ArrayList<>();
1112 while (st.hasMoreTokens())
1114 seqstring = st.nextToken();
1115 StringTokenizer st2 = new StringTokenizer(seqstring, "=");
1116 if (st2.countTokens() > 1)
1118 // This is the chain
1119 tmp2.add(st2.nextToken());
1120 seqstring = st2.nextToken();
1122 tmp.add(matcher == null
1123 ? (Sequence) af.getViewport().getAlignment()
1124 .findName(seqstring)
1125 : matcher.findIdMatch(seqstring));
1128 seqs = tmp.toArray(new SequenceI[tmp.size()]);
1129 if (tmp2.size() == tmp.size())
1131 chains = tmp2.toArray(new String[tmp2.size()]);
1136 DataSourceType protocol = resolveFileProtocol(ret);
1137 // TODO check JAL-357 for files in a jar (CLASSLOADER)
1138 pdb.setFile(ret[0]);
1142 for (int i = 0; i < seqs.length; i++)
1144 if (seqs[i] != null)
1146 ((Sequence) seqs[i]).addPDBId(pdb);
1147 StructureSelectionManager
1148 .getStructureSelectionManager(
1149 (StructureSelectionManagerProvider) this)
1150 .registerPDBEntry(pdb);
1156 // this may not really be a problem but we give a warning
1159 "Warning: Possible input parsing error: Null sequence for attachment of PDB (sequence "
1167 // pdbs.add(new Object[] { pdb, seqs, chains, protocol });
1171 newStructureView(af, pdb, seqs, chains, protocol);
1177 } while (param != null || pdbFileCount < 10);
1179 // if (doAlign && pdbs.size() > 0)
1181 // SequenceI[][] seqs = new SequenceI[pdbs.size()][];
1182 // PDBEntry[] pdb = new PDBEntry[pdbs.size()];
1183 // String[][] chains = new String[pdbs.size()][];
1184 // String[] protocols = new String[pdbs.size()];
1185 // for (int pdbsi = 0, pdbsiSize = pdbs
1186 // .size(); pdbsi < pdbsiSize; pdbsi++)
1188 // Object[] o = pdbs.get(pdbsi);
1189 // pdb[pdbsi] = (PDBEntry) o[0];
1190 // seqs[pdbsi] = (SequenceI[]) o[1];
1191 // chains[pdbsi] = (String[]) o[2];
1192 // protocols[pdbsi] = (String) o[3];
1194 //// alignedStructureView(pdb, seqs, chains, protocols);
1201 * Load a score file if specified by parameter. Returns true if file was
1202 * loaded, else false.
1204 * @param loaderFrame
1206 protected boolean loadScoreFile()
1208 boolean result = false;
1209 String sScoreFile = (String) getAppletParameter("scoreFile", true);
1210 if (sScoreFile != null && !"".equals(sScoreFile))
1217 "Attempting to load T-COFFEE score file from the scoreFile parameter");
1219 result = loadScoreFile(sScoreFile);
1223 "Failed to parse T-COFFEE parameter as a valid score file ('"
1224 + sScoreFile + "')");
1226 } catch (Exception e)
1228 System.err.printf("Cannot read score file: '%s'. Cause: %s \n",
1229 sScoreFile, e.getMessage());
1236 * Load a tree for the alignment if specified by parameter. Returns true if a
1237 * tree was loaded, else false.
1241 protected boolean loadTree(AlignFrame af)
1243 boolean result = false;
1244 String treeFile = (String) getAppletParameter("tree", true);
1245 if (treeFile == null)
1247 treeFile = (String) getAppletParameter("treefile", true);
1250 if (treeFile != null)
1255 NewickFile fin = new NewickFile(treeFile, resolveFileProtocol(ret));
1258 if (fin.getTree() != null)
1260 loadTree(af, fin, ret[0]);
1264 System.out.println("Successfully imported tree.");
1272 "Tree parameter did not resolve to a valid tree.");
1275 } catch (Exception ex)
1277 ex.printStackTrace();
1284 * @j2sAlias openPcaPanel
1286 * public static method for JalviewJS API to open a PCAPanel without
1287 * necessarily using a dialog.
1291 * @return the PCAPanel, or the string "label.you_need_at_least_n_sequences"
1292 * if number of sequences selected is inappropriate
1295 public Object openPcaPanel(AlignFrame af, String modelName)
1299 af = Jalview.getCurrentAlignFrame();
1301 return CalculationChooser.openPcaPanel(af, modelName, null);
1305 * @j2sAlias openTreePanel
1307 * Open a new Tree panel on the desktop statically. Params are standard (not
1308 * set by Groovy). No dialog is opened.
1313 * @return null, or the string "label.you_need_at_least_n_sequences" if number
1314 * of sequences selected is inappropriate
1317 public Object openTreePanel(AlignFrame af, String treeType,
1322 af = Jalview.getCurrentAlignFrame();
1324 return CalculationChooser.openTreePanel(af, treeType, modelName, null);
1329 public String orderBy(String[] ids, String undoName)
1331 return orderAlignmentBy(null, ids, undoName);
1335 public String orderAlignmentBy(AlignFrame alf, String[] ids,
1339 alf = Jalview.getCurrentAlignFrame();
1340 SequenceI[] sqs = null;
1341 if (ids != null && ids.length > 0)
1343 jalview.analysis.SequenceIdMatcher matcher = new jalview.analysis.SequenceIdMatcher(
1344 alf.getViewport().getAlignment().getSequencesArray());
1346 sqs = new SequenceI[ids.length];
1347 for (int i = 0; i < ids.length; i++)
1349 if (ids[i].trim().length() == 0)
1353 SequenceI sq = matcher.findIdMatch(ids[i]);
1361 SequenceI[] sqq = new SequenceI[s];
1362 System.arraycopy(sqs, 0, sqq, 0, s);
1375 final AlignmentOrder aorder = new AlignmentOrder(sqs);
1377 if (undoName != null && undoName.trim().length() == 0)
1381 final String _undoName = undoName;
1382 // TODO: deal with synchronization here: cannot raise any events until after
1383 // this has returned.
1384 return alf.sortBy(aorder, _undoName) ? "true" : "";
1388 * Allow an outside entity to initiate the second half of argument parsing
1392 * @return null is good
1395 public Object parseArguments(String[] args)
1400 Jalview.getInstance().parseArguments(new ArgsParser(args), false);
1402 } catch (Throwable t)
1409 public void removeSelectionListener(AlignFrame af, String listener)
1412 List<SelectionListener> listeners = Desktop
1413 .getStructureSelectionManager().getListeners();
1414 for (int i = listeners.size(); --i >= 0;)
1416 SelectionListener l = listeners.get(i);
1417 if (l instanceof JsSelectionListener
1418 && ((JsSelectionListener) l).isFor(af, listener))
1420 listeners.remove(i);
1427 public void scrollViewToColumnIn(final AlignFrame alf,
1428 final String leftHandColumn)
1430 java.awt.EventQueue.invokeLater(new Runnable()
1438 (alf == null ? Jalview.getCurrentAlignFrame() : alf)
1440 Integer.valueOf(leftHandColumn).intValue());
1442 } catch (Exception ex)
1445 "Couldn't parse integer arguments (leftHandColumn='"
1446 + leftHandColumn + "')");
1447 ex.printStackTrace();
1455 public void scrollViewToIn(final AlignFrame alf, final String topRow,
1456 final String leftHandColumn)
1459 java.awt.EventQueue.invokeLater(new Runnable()
1466 (alf == null ? Jalview.getCurrentAlignFrame() : alf).scrollTo(
1467 Integer.valueOf(topRow).intValue(),
1468 Integer.valueOf(leftHandColumn).intValue());
1470 } catch (Exception ex)
1472 System.err.println("Couldn't parse integer arguments (topRow='"
1473 + topRow + "' and leftHandColumn='" + leftHandColumn
1475 ex.printStackTrace();
1482 public void scrollViewToRowIn(final AlignFrame alf, final String topRow)
1486 java.awt.EventQueue.invokeLater(new Runnable()
1493 (alf == null ? Jalview.getCurrentAlignFrame() : alf)
1494 .scrollToRow(Integer.valueOf(topRow).intValue());
1496 } catch (Exception ex)
1498 System.err.println("Couldn't parse integer arguments (topRow='"
1500 ex.printStackTrace();
1508 public void select(String sequenceIds, String columns)
1510 selectIn(Jalview.getCurrentAlignFrame(), sequenceIds, columns, null);
1514 public void select(String sequenceIds, String columns, String sep)
1516 selectIn(null, sequenceIds, columns, sep);
1520 // public AlignFrame newView()
1522 // return newViewFrom(null, null);
1526 // public AlignFrame newView(String name)
1528 // return newViewFrom(null, name);
1532 // public AlignFrame newViewFrom(AlignFrame alf)
1534 // return newViewFrom(alf, null);
1538 // public AlignFrame newViewFrom(AlignFrame alf, String name)
1542 // alf = Jalview.getCurrentAlignFrame();
1544 // return appLoader.newViewFrom(alf, name);
1548 public void selectIn(AlignFrame alf, String sequenceIds, String columns)
1550 selectIn(alf, sequenceIds, columns, null);
1554 public void selectIn(AlignFrame af, String sequenceIds, String columns,
1557 AlignFrame alf = (af == null ? Jalview.getCurrentAlignFrame() : af);
1559 if (sep == null || sep.length() == 0)
1567 System.err.println("Selecting region using separator string '"
1572 String[] ids = separatorListToArray(sequenceIds, sep);
1573 String[] cols = separatorListToArray(columns, sep);
1574 final SequenceGroup sel = new SequenceGroup();
1575 final ColumnSelection csel = new ColumnSelection();
1576 AlignmentI al = alf.getViewport().getAlignment();
1577 jalview.analysis.SequenceIdMatcher matcher = new jalview.analysis.SequenceIdMatcher(
1578 alf.getViewport().getAlignment().getSequencesArray());
1579 int start = 0, end = al.getWidth(), alw = al.getWidth();
1580 boolean seqsfound = true;
1581 if (ids != null && ids.length > 0)
1584 for (int i = 0; i < ids.length; i++)
1586 if (ids[i].trim().length() == 0)
1590 SequenceI sq = matcher.findIdMatch(ids[i]);
1594 sel.addSequence(sq, false);
1598 boolean inseqpos = false;
1599 if (cols != null && cols.length > 0)
1601 boolean seset = false;
1602 for (int i = 0; i < cols.length; i++)
1604 String cl = cols[i].trim();
1605 if (cl.length() == 0)
1610 if ((p = cl.indexOf("-")) > -1)
1612 int from = -1, to = -1;
1615 from = Integer.valueOf(cl.substring(0, p)).intValue();
1617 } catch (NumberFormatException ex)
1620 "ERROR: Couldn't parse first integer in range element column selection string '"
1621 + cl + "' - format is 'from-to'");
1626 to = Integer.valueOf(cl.substring(p + 1)).intValue();
1628 } catch (NumberFormatException ex)
1631 "ERROR: Couldn't parse second integer in range element column selection string '"
1632 + cl + "' - format is 'from-to'");
1635 if (from >= 0 && to >= 0)
1652 // comment to prevent range extension
1662 for (int r = from; r <= to; r++)
1664 if (r >= 0 && r < alw)
1671 System.err.println("Range '" + cl + "' deparsed as [" + from
1677 System.err.println("ERROR: Invalid Range '" + cl
1678 + "' deparsed as [" + from + "," + to + "]");
1686 r = Integer.valueOf(cl).intValue();
1688 } catch (NumberFormatException ex)
1690 if (cl.toLowerCase().equals("sequence"))
1692 // we are in the dataset sequence's coordinate frame.
1698 "ERROR: Couldn't parse integer from point selection element of column selection string '"
1703 if (r >= 0 && r <= alw)
1713 // comment to prevent range extension
1726 System.err.println("Point selection '" + cl
1727 + "' deparsed as [" + r + "]");
1732 System.err.println("ERROR: Invalid Point selection '" + cl
1733 + "' deparsed as [" + r + "]");
1740 // we only propagate the selection when it was the null selection, or the
1741 // given sequences were found in the alignment.
1742 if (inseqpos && sel.getSize() > 0)
1744 // assume first sequence provides reference frame ?
1745 SequenceI rs = sel.getSequenceAt(0);
1746 start = rs.findIndex(start);
1747 end = rs.findIndex(end);
1748 List<Integer> cs = new ArrayList<>(csel.getSelected());
1750 for (Integer selectedCol : cs)
1752 csel.addElement(rs.findIndex(selectedCol));
1755 sel.setStartRes(start);
1757 EventQueue.invokeLater(new Runnable()
1762 alf.select(sel, csel,
1763 alf.getCurrentView().getAlignment().getHiddenColumns());
1770 public void setFeatureGroupState(String[] groups, boolean state)
1772 setFeatureGroupState(null, groups, state);
1776 public void setFeatureGroupState(String groups, boolean state)
1777 { // JalviewLite API
1778 setFeatureGroupStateOn(null, groups, state);
1782 public void setFeatureGroupStateOn(final AlignFrame alf,
1783 final String groups, boolean state)
1785 setFeatureGroupState(alf, separatorListToArray(groups, separator), state);
1786 // java.awt.EventQueue.invokeLater(new Runnable()
1789 // public void run()
1791 // (alf == null ? Jalview.getCurrentAlignFrame() : alf)
1792 // .setFeatureGroupState(
1793 // separatorListToArray(groups, separator), state);
1798 public void setFeatureGroupState(AlignFrame af, String[] groups, boolean state) {
1799 (af == null ? Jalview.getCurrentAlignFrame() : af).setFeatureGroupState(groups, state);
1804 public void setSelectionListener(AlignFrame af, String listener)
1806 Desktop.getStructureSelectionManager()
1807 .addSelectionListener(new JsSelectionListener(af, listener));
1811 public void setSelectionListener(String listener)
1813 Desktop.getStructureSelectionManager()
1814 .addSelectionListener(new JsSelectionListener(null, listener));
1818 public void showOverview()
1820 Jalview.getCurrentAlignFrame().overviewMenuItem_actionPerformed(null);
1824 * Allowing for a JavaScript function here.
1826 public void callInitCallback()
1828 Object initjscallback = getAppletParameter("oninit", false);
1829 if (initjscallback != null)
1833 doSendCallback(initjscallback, new Object[0]);
1834 } catch (Exception e)
1836 System.err.println("Exception when executing _oninit callback '"
1837 + initjscallback + "'.");
1838 e.printStackTrace();
1844 * Pass the provided array prepended with Jalview.this
1846 * Appropriated from org.jmol.appletjs.Jmol
1849 * a window function or "alert"
1851 * @return String return from the callback method.
1853 public String doSendCallback(Object callback, Object[] data)
1855 Jalview me = Jalview.getInstance();
1857 if (me != null && callback != null)
1864 * if (callback == "alert") { alert(data[0]); return ""; } var
1865 * o; if (typeof callback == "function") { o = callback; } else
1866 * { if (!callback)return; var tokens = callback.split("."); o
1867 * = window[tokens[0]]; for (var i = 1; i < tokens.length; i++)
1868 * o = o[tokens[i]]; } var a = [me]; for (var i = 0; i <
1869 * data.length; i++) a.push(data[i] ? data[i].booleanValue &&
1870 * (data[i] = data[i].booleanValue()) : data[i]); return
1871 * o.apply(null,a) } catch (e) { System.out.println(callback +
1872 * " failed " + e); }
1878 private DataSourceType resolveFileProtocol(String[] retPath)
1880 String path = retPath[0];
1884 if (path.startsWith("PASTE"))
1886 retPath[0] = path.substring(5);
1887 return DataSourceType.PASTE;
1893 if (path.indexOf("://") >= 0)
1895 return DataSourceType.URL;
1899 * try relative to document root
1901 URL documentBase = getDocumentBase();
1902 String withDocBase = resolveUrlForLocalOrAbsolute(path, documentBase);
1903 if (HttpUtils.isValidUrl(withDocBase))
1907 // System.err.println("Prepended document base '" + documentBase
1908 // + "' to make: '" + withDocBase + "'");
1910 retPath[0] = withDocBase;
1911 return DataSourceType.URL;
1915 * try relative to codebase (if different to document base)
1917 URL codeBase = getCodeBase();
1918 String withCodeBase = resolveUrlForLocalOrAbsolute(path, codeBase);
1919 if (!withCodeBase.equals(withDocBase)
1920 && HttpUtils.isValidUrl(withCodeBase))
1924 // System.err.println("Prepended codebase '" + codeBase
1925 // + "' to make: '" + withCodeBase + "'");
1927 retPath[0] = withCodeBase;
1928 return DataSourceType.URL;
1932 * try locating by classloader; try this last so files in the directory
1933 * are resolved using document base
1935 if (inArchive(getClass(), path))
1937 return DataSourceType.CLASSLOADER;
1943 * Discovers whether the given file is in the Applet Archive
1949 private static boolean inArchive(Class<?> c, String f)
1951 // This might throw a security exception in certain browsers
1952 // Netscape Communicator for instance.
1955 boolean rtn = (c.getResourceAsStream("/" + f) != null);
1957 } catch (Exception ex)
1959 System.out.println("Exception checking resources: " + f + " " + ex);
1965 * form a complete URL given a path to a resource and a reference location on
1969 * - an absolute path on the same server as localref or a document
1970 * located relative to localref
1972 * - a URL on the same server as url
1973 * @return a complete URL for the resource located by url
1975 public static String resolveUrlForLocalOrAbsolute(String targetPath,
1978 String resolvedPath = "";
1979 if (targetPath.startsWith("/"))
1981 String codebase = localref.toString();
1982 String localfile = localref.getFile();
1983 resolvedPath = codebase.substring(0,
1984 codebase.length() - localfile.length()) + targetPath;
1985 return resolvedPath;
1989 * get URL path and strip off any trailing file e.g.
1990 * www.jalview.org/examples/index.html#applets?a=b is trimmed to
1991 * www.jalview.org/examples/
1993 String urlPath = localref.toString();
1994 String directoryPath = urlPath;
1995 int lastSeparator = directoryPath.lastIndexOf("/");
1996 if (lastSeparator > 0)
1998 directoryPath = directoryPath.substring(0, lastSeparator + 1);
2001 if (targetPath.startsWith("/"))
2004 * construct absolute URL to a file on the server - this is not allowed?
2006 // String localfile = localref.getFile();
2007 // resolvedPath = urlPath.substring(0,
2008 // urlPath.length() - localfile.length())
2010 resolvedPath = directoryPath + targetPath.substring(1);
2014 resolvedPath = directoryPath + targetPath;
2018 // System.err.println(
2019 // "resolveUrlForLocalOrAbsolute returning " + resolvedPath);
2021 return resolvedPath;
2025 * parse the string into a list
2029 * @return elements separated by separator
2031 public static String[] separatorListToArray(String list, String separator)
2033 // TODO use StringUtils version (slightly different...)
2034 int seplen = separator.length();
2035 if (list == null || list.equals("") || list.equals(separator))
2039 Vector<String> jv = new Vector<>();
2041 while ((pos = list.indexOf(separator, cp)) > cp)
2043 jv.addElement(list.substring(cp, pos));
2046 if (cp < list.length())
2048 String c = list.substring(cp);
2049 if (!c.equals(separator))
2056 String[] v = new String[jv.size()];
2057 for (int i = 0; i < v.length; i++)
2059 v[i] = jv.elementAt(i);
2061 jv.removeAllElements();
2067 public class JsSelectionListener
2068 implements jalview.structure.SelectionListener
2075 public JsSelectionListener(AlignFrame af, String listener)
2078 _listener = listener;
2082 public void selection(SequenceGroup seqsel, ColumnSelection colsel,
2083 HiddenColumns hidden, SelectionSource source)
2085 // System.err.println("Testing selection event relay to
2086 // jsfunction:"+_listener);
2088 AlignFrame src = _af;
2091 if (source instanceof AlignViewport
2092 && Jalview.getCurrentAlignFrame().getViewport() == source)
2094 src = Jalview.getCurrentAlignFrame();
2099 String[] seqs = new String[] {};
2100 String[] cols = new String[] {};
2101 int strt = 0, end = (src == null) ? -1
2102 : src.alignPanel.av.getAlignment().getWidth();
2103 if (seqsel != null && seqsel.getSize() > 0)
2105 seqs = new String[seqsel.getSize()];
2106 for (int i = 0; i < seqs.length; i++)
2108 seqs[i] = seqsel.getSequenceAt(i).getName();
2110 if (strt < seqsel.getStartRes())
2112 strt = seqsel.getStartRes();
2114 if (end == -1 || end > seqsel.getEndRes())
2116 end = seqsel.getEndRes();
2119 if (colsel != null && !colsel.isEmpty())
2123 end = colsel.getMax() + 1;
2125 cols = new String[colsel.getSelected().size()];
2126 for (int i = 0; i < cols.length; i++)
2128 cols[i] = "" + (1 + colsel.getSelected().get(i).intValue());
2133 if (seqsel != null && seqsel.getSize() > 0)
2135 // send a valid range, otherwise we send the empty selection
2136 cols = new String[1];
2137 cols[0] = "" + (1 + strt) + "-" + (1 + end);
2143 doSendCallback(_listener,
2145 { src, setid, seqs, cols });
2148 public boolean isFor(AlignFrame af, String listener)
2150 return _af == af && _listener.contentEquals(listener);
2156 public AlignViewportI getViewport()
2158 return Jalview.getCurrentAlignFrame().getViewport();