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 javax.swing.SwingUtilities;
14 import jalview.api.JalviewJSApi;
15 import jalview.api.StructureSelectionManagerProvider;
16 import jalview.datamodel.Alignment;
17 import jalview.datamodel.AlignmentI;
18 import jalview.datamodel.AlignmentOrder;
19 import jalview.datamodel.ColumnSelection;
20 import jalview.datamodel.HiddenColumns;
21 import jalview.datamodel.PDBEntry;
22 import jalview.datamodel.Sequence;
23 import jalview.datamodel.SequenceGroup;
24 import jalview.datamodel.SequenceI;
25 import jalview.gui.AlignFrame;
26 import jalview.gui.AlignViewport;
27 import jalview.gui.CalculationChooser;
28 import jalview.gui.Desktop;
29 import jalview.gui.StructureViewer;
30 import jalview.io.AnnotationFile;
31 import jalview.io.AppletFormatAdapter;
32 import jalview.io.DataSourceType;
33 import jalview.io.FeaturesFile;
34 import jalview.io.FileFormat;
35 import jalview.io.FileFormatI;
36 import jalview.io.FileFormats;
37 import jalview.io.IdentifyFile;
38 import jalview.io.JPredFile;
39 import jalview.io.JnetAnnotationMaker;
40 import jalview.io.NewickFile;
41 import jalview.structure.SelectionListener;
42 import jalview.structure.SelectionSource;
43 import jalview.structure.StructureSelectionManager;
44 import jalview.util.HttpUtils;
45 import jalview.util.Platform;
48 * Basically the JalviewLite application, but without JalviewLite
50 * Processing all "applet parameters" and also all "applet interface" methods.
55 public class JalviewJSApp implements JalviewJSApi
57 private ArgsParser aparser;
59 private String[] ret = new String[1];
61 // private boolean alignPDBStructures; From JalviewLite; not implemented
63 private String separator = "\u00AC"; // JalviewLite note: the default used to
64 // be '|', but many sequence IDS include
68 * We maintain a pointer to the jalview instance here, because only with that
69 * do we have a direct connection from the JavaScript "applet" object to the
70 * proper instance of Jalview in case there are multiple applets on a page.
72 private Jalview jalview;
74 public class JsSelectionListener
75 implements jalview.structure.SelectionListener
82 public JsSelectionListener(AlignFrame alf, String listener)
88 public boolean isFor(AlignFrame alf, String listener)
90 return (_alf == null || _alf == alf) && _listener.equals(listener);
94 public void selection(SequenceGroup seqsel, ColumnSelection colsel,
95 HiddenColumns hidden, SelectionSource source)
97 // System.err.println("Testing selection event relay to
98 // jsfunction:"+_listener);
100 AlignFrame srcFrame = (_alf == null ? getCurrentAlignFrame() : _alf);
103 if (source instanceof AlignViewport
104 && srcFrame.getViewport() != source)
109 String[] seqs = new String[] {};
110 String[] cols = new String[] {};
111 int strt = 0, end = (srcFrame == null) ? -1
112 : srcFrame.alignPanel.av.getAlignment().getWidth();
113 if (seqsel != null && seqsel.getSize() > 0)
115 seqs = new String[seqsel.getSize()];
116 for (int i = 0; i < seqs.length; i++)
118 seqs[i] = seqsel.getSequenceAt(i).getName();
120 if (strt < seqsel.getStartRes())
122 strt = seqsel.getStartRes();
124 if (end == -1 || end > seqsel.getEndRes())
126 end = seqsel.getEndRes();
129 if (colsel != null && !colsel.isEmpty())
133 end = colsel.getMax() + 1;
135 cols = new String[colsel.getSelected().size()];
136 for (int i = 0; i < cols.length; i++)
138 cols[i] = "" + (1 + colsel.getSelected().get(i).intValue());
143 if (seqsel != null && seqsel.getSize() > 0)
145 // send a valid range, otherwise we send the empty selection
146 cols = new String[1];
147 cols[0] = "" + (1 + strt) + "-" + (1 + end);
150 doSendCallback(_listener,
152 { Jalview.getInstance().j2sAppletID, srcFrame, source, setid,
158 public JalviewJSApp(Jalview jalview, ArgsParser aparser)
160 Platform.setAppClass(this);
161 this.jalview = jalview;
162 this.aparser = aparser;
166 public boolean addPdbFile(String sequenceId, String pdbId, String pdbFile,
171 alf = getCurrentAlignFrame();
173 SequenceI seq = alf.getViewport().getAlignment().findName(sequenceId);
176 Vector<PDBEntry> pdbe = seq.getAllPDBEntries();
177 PDBEntry pdbentry = null;
178 if (pdbe != null && pdbe.size() > 0)
180 for (int pe = 0, peSize = pdbe.size(); pe < peSize; pe++)
182 pdbentry = pdbe.elementAt(pe);
183 if (!pdbentry.getId().equals(pdbId)
184 || pdbFile != null && !pdbentry.getFile().equals(pdbFile))
190 if (pdbentry == null)
192 pdbentry = new PDBEntry(pdbId, null, pdbFile);
195 DataSourceType protocol = AppletFormatAdapter
196 .resolveProtocol(pdbFile, FileFormat.PDB);
197 if (protocol == null)
199 pdbentry.setProperty("protocol", protocol);
201 seq.addPDBId(pdbentry);
202 alf.alignPanel.getStructureSelectionManager()
203 .registerPDBEntry(pdbentry);
210 public String getAlignment(String format, boolean addSuffix,
217 alf = getCurrentAlignFrame();
220 FileFormatI theFormat = FileFormats.getInstance().forName(format);
221 String reply = new AppletFormatAdapter().formatSequences(theFormat,
222 alf.getViewport().getAlignment(), addSuffix);
224 } catch (IllegalArgumentException ex)
226 ex.printStackTrace();
227 return "Error retrieving alignment, possibly invalid format specifier: "
233 public String[] getAlignmentOrder(AlignFrame alf)
237 alf = getCurrentAlignFrame();
239 AlignmentI alorder = alf.getViewport().getAlignment();
240 String[] order = new String[alorder.getHeight()];
241 for (int i = 0; i < order.length; i++)
243 order[i] = alorder.getSequenceAt(i).getName();
245 return order;// arrayToSeparatorList(order, sep);
249 public String getAnnotation(AlignFrame alf)
253 alf = getCurrentAlignFrame();
255 String annotation = new AnnotationFile()
256 .printAnnotationsForView(alf.getViewport());
261 * Get the applet-like code base even though this is an application.
265 public URL getCodeBase()
267 return Platform.getCodeBase();
271 public AlignFrame getCurrentAlignFrame()
273 // if (jalview != Jalview.getInstance() || jalview.currentAlignFrame !=
274 // Jalview.getCurrentAlignFrame()) {
275 // /** @j2sNative debugger */
277 return jalview.currentAlignFrame;
281 * Get the applet-like document base even though this is an application.
285 public URL getDocumentBase()
287 return Platform.getDocumentBase();
291 public String[] getFeatureGroups(AlignFrame alf)
295 alf = getCurrentAlignFrame();
297 return alf.getFeatureGroups();
301 public String[] getFeatureGroupsOfState(boolean visible, AlignFrame alf)
305 alf = getCurrentAlignFrame();
307 return alf.getFeatureGroupsOfState(visible);
311 * JavaScript interface to print the alignment frame
314 * "jalview" or "gff" with or without ";includeComplement" or
315 * ";includeNonpositional"; default with no ";" is
316 * ";includeNonpositional"
322 public String getFeatures(String format, AlignFrame alf)
326 alf = getCurrentAlignFrame();
329 FeaturesFile formatter = new FeaturesFile();
330 format = format.toLowerCase();
331 if (format.indexOf(";") < 0)
332 format += ";includenonpositional";
333 boolean nonpos = format.indexOf(";includenonpositional") >= 0;
334 boolean compl = format.indexOf(";includecomplement") >= 0;
335 if (format.startsWith("jalview"))
337 features = formatter.printJalviewFormat(
338 alf.getViewport().getAlignment().getSequencesArray(),
339 alf.alignPanel.getFeatureRenderer(), nonpos, compl);
343 features = formatter.printGffFormat(
344 alf.getViewport().getAlignment().getSequencesArray(),
345 alf.alignPanel.getFeatureRenderer(), nonpos, compl);
348 if (features == null)
357 * Get an applet parameter as a string.
361 public String getParameter(String name)
363 return (String) aparser.getAppletValue(name, null, true);
367 * Get an applet parameter as an Object.
371 public Object getParameterAsObject(String name)
373 return aparser.getAppletValue(name, null, false);
377 * read sequence1...sequenceN as a raw alignment
382 public String getPastedSequence(JalviewJSApp jalviewApp)
384 StringBuffer data = new StringBuffer("PASTE");
387 while ((file = getParameter("sequence" + i)) != null)
389 data.append(file.toString() + "\n");
392 if (data.length() > 5)
394 file = data.toString();
400 * @j2sAlias getSelectedSequences
402 * @see jalview.appletgui.js.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
406 public SequenceI[] getSelectedSequences(AlignFrame alf)
408 // return getSelectedSequencesFrom(alf, null);
412 // public SequenceI[] getSelectedSequencesFrom(AlignFrame alf, String sep)
416 alf = getCurrentAlignFrame();
418 AlignViewport v = alf.getViewport();
419 if (v.getSelectionGroup() != null)
421 return v.getSelectionGroup().getSequencesInOrder(v.getAlignment());
428 // jalview.appletgui.js.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
429 // * .AlignFrame, java.lang.String)
432 // public void highlight(String sequenceId, String position,
433 // String alignedPosition)
435 // highlightIn(null, sequenceId, position, alignedPosition);
439 * @j2sAlias getSelectedSequencesAsAlignment
442 public String getSelectedSequencesAsAlignment(String format,
443 boolean addSuffix, AlignFrame alf)
448 alf = getCurrentAlignFrame();
452 AlignViewport vp = alf.getViewport();
453 FileFormatI theFormat = FileFormats.getInstance().forName(format);
454 if (vp.getSelectionGroup() != null)
456 // JBPNote: getSelectionAsNewSequence behaviour has changed - this
457 // method now returns a full copy of sequence data
458 // TODO consider using getSequenceSelection instead here
459 String reply = new AppletFormatAdapter().formatSequences(theFormat,
460 new Alignment(vp.getSelectionAsNewSequence()), addSuffix);
463 } catch (IllegalArgumentException ex)
465 ex.printStackTrace();
466 return "Error retrieving alignment, possibly invalid format specifier: "
473 public void highlight(String sequenceId, String position,
474 String alignedPosition, AlignFrame alf)
478 alf = getCurrentAlignFrame();
480 // TODO: could try to highlight in all alignments if alf==null
481 jalview.analysis.SequenceIdMatcher matcher = new jalview.analysis.SequenceIdMatcher(
482 alf.getViewport().getAlignment().getSequencesArray());
483 final SequenceI sq = matcher.findIdMatch(sequenceId);
489 apos = Integer.valueOf(position).intValue();
491 } catch (NumberFormatException ex)
495 final int pos = apos;
496 // use vamsas listener to broadcast to all listeners in scope
497 if (alignedPosition != null && (alignedPosition.trim().length() == 0
498 || alignedPosition.toLowerCase().indexOf("false") > -1))
500 java.awt.EventQueue.invokeLater(new Runnable()
505 StructureSelectionManager
506 .getStructureSelectionManager(Desktop.getInstance())
507 .mouseOverVamsasSequence(sq, sq.findIndex(pos), null);
513 java.awt.EventQueue.invokeLater(new Runnable()
518 StructureSelectionManager
519 .getStructureSelectionManager(Desktop.getInstance())
520 .mouseOverVamsasSequence(sq, pos, null);
528 public AlignFrame loadAlignment(String text, String title, int width,
531 AlignmentI al = null;
535 FileFormatI format = new IdentifyFile().identify(text,
536 DataSourceType.PASTE);
537 al = new AppletFormatAdapter().readFile(text, DataSourceType.PASTE,
539 if (al.getHeight() > 0)
541 return new AlignFrame(al,
542 width > 0 ? width : AlignFrame.DEFAULT_WIDTH,
543 height > 0 ? height : AlignFrame.DEFAULT_HEIGHT, title);
545 } catch (IOException ex)
547 ex.printStackTrace();
553 public void loadAnnotation(String annotation, AlignFrame alf)
557 alf = getCurrentAlignFrame();
559 if (new AnnotationFile().annotateAlignmentView(alf.getViewport(),
560 annotation, DataSourceType.PASTE))
562 alf.alignPanel.fontChanged();
563 alf.alignPanel.setScrollValues(0, 0);
567 alf.parseFeaturesFile(annotation, DataSourceType.PASTE);
572 public boolean loadFeatures(String features, boolean autoenabledisplay,
577 alf = getCurrentAlignFrame();
579 boolean ret = alf.parseFeaturesFile(features, DataSourceType.PASTE);
584 if (autoenabledisplay)
586 alf.getViewport().setShowSequenceFeatures(true);
587 // this next was for a checkbox in JalviewLite
588 // ((AlignFrame) alf).getViewport().sequenceFeatures.setState(true);
594 public boolean loadScoreFile(String fileName, AlignFrame alf)
598 (alf == null ? getCurrentAlignFrame() : alf)
599 .loadJalviewDataFile(fileName, null, null, null);
601 } catch (Throwable t)
608 * @j2sAlias openPcaPanel
610 * public static method for JalviewJS API to open a PCAPanel without
611 * necessarily using a dialog.
615 * @return the PCAPanel, or the string "label.you_need_at_least_n_sequences"
616 * if number of sequences selected is inappropriate
619 public Object openPcaPanel(String modelName, AlignFrame alf)
623 alf = getCurrentAlignFrame();
625 return CalculationChooser.openPcaPanel(alf, modelName, null);
629 * @j2sAlias openTreePanel
631 * Open a new Tree panel on the desktop statically. Params are
632 * standard (not set by Groovy). No dialog is opened.
637 * @return null, or the string "label.you_need_at_least_n_sequences" if number
638 * of sequences selected is inappropriate
641 public Object openTreePanel(String treeType, String modelName,
646 alf = getCurrentAlignFrame();
648 return CalculationChooser.openTreePanel(alf, treeType, modelName, null);
652 public boolean orderAlignment(String[] ids, String undoName,
656 alf = getCurrentAlignFrame();
657 SequenceI[] sqs = null;
658 if (ids != null && ids.length > 0)
660 jalview.analysis.SequenceIdMatcher matcher = new jalview.analysis.SequenceIdMatcher(
661 alf.getViewport().getAlignment().getSequencesArray());
663 sqs = new SequenceI[ids.length];
664 for (int i = 0; i < ids.length; i++)
666 if (ids[i].trim().length() == 0)
670 SequenceI sq = matcher.findIdMatch(ids[i]);
678 SequenceI[] sqq = new SequenceI[s];
679 System.arraycopy(sqs, 0, sqq, 0, s);
692 final AlignmentOrder aorder = new AlignmentOrder(sqs);
694 if (undoName != null && undoName.trim().length() == 0)
698 final String _undoName = undoName;
699 // TODO: deal with synchronization here: cannot raise any events until
701 // this has returned.
702 return alf.sortBy(aorder, _undoName);
706 * Allow an outside entity to initiate the second half of argument parsing
710 * @return null is good
713 public Object parseArguments(String[] args)
718 jalview.parseArguments(new ArgsParser(args), false);
720 } catch (Throwable t)
727 * @j2sAlias parseFeatureFile
734 public boolean parseFeaturesFile(String filename, AlignFrame alf)
737 DataSourceType protocol = resolveFileProtocol(ret);
738 if (protocol == null)
740 return (alf == null ? getCurrentAlignFrame() : alf)
741 .parseFeaturesFile(ret[0], protocol);
745 public void removeSelectionListener(String listener, AlignFrame alf)
748 List<SelectionListener> listeners = Desktop
749 .getStructureSelectionManager().getListeners();
750 for (int i = listeners.size(); --i >= 0;)
752 SelectionListener l = listeners.get(i);
753 if (l instanceof JsSelectionListener
754 && ((JsSelectionListener) l).isFor(alf, listener))
762 private DataSourceType resolveFileProtocol(String[] retPath)
764 String path = retPath[0];
768 if (path.startsWith("PASTE"))
770 retPath[0] = path.substring(5);
771 return DataSourceType.PASTE;
777 if (path.indexOf("://") >= 0)
779 return DataSourceType.URL;
783 * try relative to document root
785 URL documentBase = getDocumentBase();
786 String withDocBase = resolveUrlForLocalOrAbsolute(path, documentBase);
787 if (HttpUtils.isValidUrl(withDocBase))
791 // System.err.println("Prepended document base '" + documentBase
792 // + "' to make: '" + withDocBase + "'");
794 retPath[0] = withDocBase;
795 return DataSourceType.URL;
799 * try relative to codebase (if different to document base)
801 URL codeBase = getCodeBase();
802 String withCodeBase = resolveUrlForLocalOrAbsolute(path, codeBase);
803 if (!withCodeBase.equals(withDocBase)
804 && HttpUtils.isValidUrl(withCodeBase))
808 // System.err.println("Prepended codebase '" + codeBase
809 // + "' to make: '" + withCodeBase + "'");
811 retPath[0] = withCodeBase;
812 return DataSourceType.URL;
816 * try locating by classloader; try this last so files in the directory
817 * are resolved using document base
819 if (inArchive(getClass(), path))
821 return DataSourceType.CLASSLOADER;
827 public void scrollViewTo(int topRow, int leftHandColumn, AlignFrame alf)
830 java.awt.EventQueue.invokeLater(new Runnable()
837 (alf == null ? getCurrentAlignFrame() : alf).scrollTo(topRow,
839 } catch (Exception ex)
841 System.err.println("Couldn't parse integer arguments (topRow='"
842 + topRow + "' and leftHandColumn='" + leftHandColumn
844 ex.printStackTrace();
851 public void select(String ids[], String cols[], AlignFrame alf)
854 alf = getCurrentAlignFrame();
855 final SequenceGroup sel = new SequenceGroup();
856 final ColumnSelection csel = new ColumnSelection();
857 AlignmentI al = alf.getViewport().getAlignment();
858 jalview.analysis.SequenceIdMatcher matcher = new jalview.analysis.SequenceIdMatcher(
859 alf.getViewport().getAlignment().getSequencesArray());
860 int start = 0, end = al.getWidth(), alw = al.getWidth();
861 boolean seqsfound = true;
862 if (ids != null && ids.length > 0)
865 for (int i = 0; i < ids.length; i++)
867 if (ids[i].trim().length() == 0)
871 SequenceI sq = matcher.findIdMatch(ids[i]);
875 sel.addSequence(sq, false);
879 boolean inseqpos = false;
880 if (cols != null && cols.length > 0)
882 boolean seset = false;
883 for (int i = 0; i < cols.length; i++)
885 String cl = cols[i].trim();
886 if (cl.length() == 0)
891 if ((p = cl.indexOf("-")) > -1)
893 int from = -1, to = -1;
896 from = Integer.valueOf(cl.substring(0, p)).intValue();
898 } catch (NumberFormatException ex)
901 "ERROR: Couldn't parse first integer in range element column selection string '"
902 + cl + "' - format is 'from-to'");
907 to = Integer.valueOf(cl.substring(p + 1)).intValue();
909 } catch (NumberFormatException ex)
912 "ERROR: Couldn't parse second integer in range element column selection string '"
913 + cl + "' - format is 'from-to'");
916 if (from >= 0 && to >= 0)
933 // comment to prevent range extension
943 for (int r = from; r <= to; r++)
945 if (r >= 0 && r < alw)
953 System.err.println("ERROR: Invalid Range '" + cl
954 + "' deparsed as [" + from + "," + to + "]");
962 r = Integer.valueOf(cl).intValue();
964 } catch (NumberFormatException ex)
966 if (cl.toLowerCase().equals("sequence"))
968 // we are in the dataset sequence's coordinate frame.
974 "ERROR: Couldn't parse integer from point selection element of column selection string '"
979 if (r >= 0 && r <= alw)
989 // comment to prevent range extension
1003 System.err.println("ERROR: Invalid Point selection '" + cl
1004 + "' deparsed as [" + r + "]");
1011 // we only propagate the selection when it was the null selection, or the
1012 // given sequences were found in the alignment.
1013 if (inseqpos && sel.getSize() > 0)
1015 // assume first sequence provides reference frame ?
1016 SequenceI rs = sel.getSequenceAt(0);
1017 start = rs.findIndex(start);
1018 end = rs.findIndex(end);
1019 List<Integer> cs = new ArrayList<>(csel.getSelected());
1021 for (Integer selectedCol : cs)
1023 csel.addElement(rs.findIndex(selectedCol));
1026 sel.setStartRes(start);
1028 AlignFrame af = alf;
1029 EventQueue.invokeLater(new Runnable()
1034 af.select(sel, csel,
1035 af.getCurrentView().getAlignment().getHiddenColumns());
1043 // public void setFeatureGroupState(String[] groups, boolean state)
1045 // setFeatureGroupState(null, groups, state);
1049 // public void setFeatureGroupState(String[] groups, boolean state)
1050 // { // JalviewLite API
1051 // setFeatureGroupStateOn(null, groups, state);
1055 public void setFeatureGroupState(final String[] groups,
1056 boolean state, AlignFrame alf)
1058 // setFeatureGroupState(alf, groups, state);
1059 // java.awt.EventQueue.invokeLater(new Runnable()
1062 // public void run()
1064 // (alf == null ? getCurrentAlignFrame() : alf)
1065 // .setFeatureGroupState(
1066 // separatorListToArray(groups, separator), state);
1071 // public void setFeatureGroupState(AlignFrame alf, String[] groups, boolean
1073 (alf == null ? getCurrentAlignFrame() : alf)
1074 .setFeatureGroupState(groups, state);
1078 public void setSelectionListener(String listener, AlignFrame alf)
1080 Desktop.getStructureSelectionManager()
1081 .addSelectionListener(new JsSelectionListener(alf, listener));
1085 public void showOverview()
1087 getCurrentAlignFrame().overviewMenuItem_actionPerformed(null);
1091 * @j2sAlias showStructure
1094 public void showStructure(String pdbID, String fileType, AlignFrame alf)
1097 alf = getCurrentAlignFrame();
1099 SequenceI[] seqs = null;
1102 seqs = alf.getViewport().getSequenceSelection();
1103 if (seqs.length == 0)
1104 seqs = alf.getViewport().getAlignment().getSequencesArray();
1105 for (int i = 0; i < seqs.length; i++)
1107 Vector<PDBEntry> list = seqs[i].getAllPDBEntries();
1108 if (list.size() > 0)
1119 pe = new PDBEntry(pdbID, null, fileType);
1120 List<SequenceI> list = alf.getViewport().getAlignment()
1122 List<SequenceI> tmp = new ArrayList<SequenceI>();
1123 for (int i = 0; i < list.size(); i++)
1125 SequenceI seq = list.get(i);
1126 if (seq.getPDBEntry(pdbID) != null)
1131 seqs = tmp.toArray(new SequenceI[tmp.size()]);
1132 alf.alignPanel.selectSequences(tmp);
1134 StructureViewer.launchStructureViewer(alf.alignPanel, pe, seqs);
1137 // private or package-private methods
1140 * form a complete URL given a path to a resource and a reference location on
1144 * - an absolute path on the same server as localref or a document
1145 * located relative to localref
1147 * - a URL on the same server as url
1148 * @return a complete URL for the resource located by url
1150 private static String resolveUrlForLocalOrAbsolute(String targetPath,
1153 String resolvedPath = "";
1154 if (targetPath.startsWith("/"))
1156 String codebase = localref.toString();
1157 String localfile = localref.getFile();
1158 resolvedPath = codebase.substring(0,
1159 codebase.length() - localfile.length()) + targetPath;
1160 return resolvedPath;
1164 * get URL path and strip off any trailing file e.g.
1165 * www.jalview.org/examples/index.html#applets?a=b is trimmed to
1166 * www.jalview.org/examples/
1168 String urlPath = localref.toString();
1169 String directoryPath = urlPath;
1170 int lastSeparator = directoryPath.lastIndexOf("/");
1171 if (lastSeparator > 0)
1173 directoryPath = directoryPath.substring(0, lastSeparator + 1);
1176 if (targetPath.startsWith("/"))
1179 * construct absolute URL to a file on the server - this is not allowed?
1181 // String localfile = localref.getFile();
1182 // resolvedPath = urlPath.substring(0,
1183 // urlPath.length() - localfile.length())
1185 resolvedPath = directoryPath + targetPath.substring(1);
1189 resolvedPath = directoryPath + targetPath;
1193 // System.err.println(
1194 // "resolveUrlForLocalOrAbsolute returning " + resolvedPath);
1196 return resolvedPath;
1200 * parse the string into a list
1204 * @return elements separated by separator
1206 private static String[] separatorListToArray(String list,
1209 // TODO use StringUtils version (slightly different...)
1210 int seplen = separator.length();
1211 if (list == null || list.equals("") || list.equals(separator))
1215 Vector<String> jv = new Vector<>();
1217 while ((pos = list.indexOf(separator, cp)) > cp)
1219 jv.addElement(list.substring(cp, pos));
1222 if (cp < list.length())
1224 String c = list.substring(cp);
1225 if (!c.equals(separator))
1232 String[] v = new String[jv.size()];
1233 for (int i = 0; i < v.length; i++)
1235 v[i] = jv.elementAt(i);
1237 jv.removeAllElements();
1244 * Discovers whether the given file is in the Applet Archive
1250 private static boolean inArchive(Class<?> c, String f)
1252 // This might throw a security exception in certain browsers
1253 // Netscape Communicator for instance.
1256 boolean rtn = (c.getResourceAsStream("/" + f) != null);
1258 } catch (Exception ex)
1260 System.out.println("Exception checking resources: " + f + " " + ex);
1266 * Allowing for a JavaScript function here.
1268 void callInitCallback()
1270 Object initjscallback = getParameterAsObject("oninit");
1271 if (initjscallback != null)
1273 SwingUtilities.invokeLater(new Runnable() {
1280 doSendCallback(initjscallback, new Object[] {this});
1281 } catch (Exception e)
1283 System.err.println("Exception when executing _oninit callback '"
1284 + initjscallback + "'.");
1285 e.printStackTrace();
1294 * Pass the provided array prepended with Jalview.this
1296 * Appropriated from org.jmol.appletjs.Jmol
1299 * a window function or "alert"
1301 * @return String return from the callback method.
1303 String doSendCallback(Object callback, Object[] data)
1305 Jalview me = jalview;
1307 if (me != null && callback != null)
1314 * if (callback == "alert") { alert(data[0]); return ""; } var
1315 * o; if (typeof callback == "function") { o = callback; } else
1316 * { if (!callback)return; var tokens = callback.split("."); o
1317 * = window[tokens[0]]; for (var i = 1; i < tokens.length; i++)
1318 * o = o[tokens[i]]; } var a = [me]; for (var i = 0; i <
1319 * data.length; i++) a.push(data[i] ? data[i].booleanValue &&
1320 * (data[i] = data[i].booleanValue()) : data[i]); return
1321 * o.apply(null,a) } catch (e) { System.out.println(callback +
1322 * " failed " + e); }
1329 * Initialize from Info.key/value pairs that match the old JalviewLite applet
1332 * See http://www.jalview.org/old/v2_8/examples/appletParameters.html
1334 * Note that some of these parameters are handled as command-line arguments,
1335 * as determined in ArgsParser.
1339 void initFromParams(AlignFrame alf)
1341 String sep = getParameter("separator");
1342 if (sep != null && sep.length() > 0)
1349 initAnnotations(alf);
1355 * Load annotations if specified by parameter. Returns true if loaded, else
1362 private boolean initAnnotations(AlignFrame alf)
1365 String param = getParameter("annotations");
1369 DataSourceType protocol = resolveFileProtocol(ret);
1371 if (!new AnnotationFile().annotateAlignmentView(alf.getViewport(),
1374 System.err.println("Annotations were not added from annotation file '"
1378 updateForAnnotations();
1383 * Load features file and view settings as specified by parameters. Returns
1384 * true if features were loaded, else false.
1391 private boolean initFeatures(AlignFrame alf)
1394 // ///////////////////////////
1395 // modify display of features
1396 // we do this before any features have been loaded, ensuring any hidden
1397 // groups are hidden when features first displayed
1399 // hide specific groups
1401 String param = getParameter("hidefeaturegroups");
1404 setFeatureGroupState(separatorListToArray(param, separator),
1406 // setFeatureGroupStateOn(newAlignFrame, param, false);
1408 // show specific groups
1409 param = getParameter("showfeaturegroups");
1412 setFeatureGroupState(separatorListToArray(param, separator),
1414 // setFeatureGroupStateOn(newAlignFrame, param, true);
1416 // and now load features
1417 param = getParameter("features");
1422 if (!parseFeaturesFile(param, alf))
1424 param = getParameter("showFeatureSettings");
1425 if (param != null && param.equalsIgnoreCase("true"))
1427 alf.showFeatureSettingsUI();
1433 * Load in a Jnetfile if specified by parameter. Returns true if loaded, else
1439 private boolean initJnetFile(AlignFrame alf)
1442 String param = getParameter("jnetfile");
1445 // jnet became jpred around 2016
1446 param = getParameter("jpredfile");
1453 DataSourceType protocol = resolveFileProtocol(ret);
1454 JPredFile predictions = new JPredFile(ret[0], protocol);
1455 JnetAnnotationMaker.add_annotation(predictions,
1456 alf.getViewport().getAlignment(), 0, false);
1457 // false == do not add sequence profile from concise output
1458 alf.getViewport().getAlignment().setupJPredAlignment();
1459 updateForAnnotations();
1460 } catch (Exception ex)
1462 ex.printStackTrace();
1470 * Load PDBFiles if any specified by parameter(s). Returns true if loaded,
1473 * @param loaderFrame
1476 private boolean initPdbFiles(AlignFrame alf)
1480 * <param name="alignpdbfiles" value="false/true"/> Undocumented for 2.6 -
1481 * related to JAL-434
1484 // not supported (as for JalviewLite)
1485 // boolean doAlign = false;//"true".equalsIgnoreCase("" +
1486 // getAppletParameter("alignpdbfiles", false));
1487 // setAlignPdbStructures(doAlign);
1489 * <param name="PDBfile" value="1gaq.txt PDB|1GAQ|1GAQ|A PDB|1GAQ|1GAQ|B
1492 * <param name="PDBfile2" value="1gaq.txt A=SEQA B=SEQB C=SEQB">
1494 * <param name="PDBfile3" value="1q0o Q45135_9MICO">
1497 // Accumulate pdbs here if they are heading for the same view (if
1498 // alignPdbStructures is true)
1499 // ArrayList<Object[]> pdbs = new ArrayList<>();
1500 // init a lazy matcher if we're asked to
1501 boolean relaxed = "true"
1502 .equalsIgnoreCase(getParameter("relaxedidmatch"));
1503 jalview.analysis.SequenceIdMatcher matcher = relaxed
1504 ? new jalview.analysis.SequenceIdMatcher(
1505 alf.getViewport().getAlignment().getSequencesArray())
1508 String param = getParameter("PDBFILE");
1509 int plast = (param == null ? 9 : 1);
1510 if (param == null && (param = getParameter("PDBFILE1")) == null)
1514 for (int p = 1; p <= plast; p++)
1518 param = getParameter("PDBFILE" + p);
1522 PDBEntry pdb = new PDBEntry();
1525 SequenceI[] seqs = null;
1526 String[] chains = null;
1528 StringTokenizer st = new StringTokenizer(param, " ");
1530 if (st.countTokens() < 2)
1532 String sequence = getParameter("PDBSEQ");
1533 if (sequence != null)
1535 seqs = new SequenceI[] { matcher == null
1536 ? (Sequence) alf.getViewport().getAlignment()
1538 : matcher.findIdMatch(sequence) };
1544 param = st.nextToken();
1545 List<SequenceI> tmp = new ArrayList<>();
1546 List<String> tmp2 = new ArrayList<>();
1548 while (st.hasMoreTokens())
1550 seqstring = st.nextToken();
1551 StringTokenizer st2 = new StringTokenizer(seqstring, "=");
1552 if (st2.countTokens() > 1)
1554 // This is the chain
1555 tmp2.add(st2.nextToken());
1556 seqstring = st2.nextToken();
1558 tmp.add(matcher == null
1559 ? (Sequence) alf.getViewport().getAlignment()
1560 .findName(seqstring)
1561 : matcher.findIdMatch(seqstring));
1564 seqs = tmp.toArray(new SequenceI[tmp.size()]);
1565 if (tmp2.size() == tmp.size())
1567 chains = tmp2.toArray(new String[tmp2.size()]);
1572 DataSourceType protocol = resolveFileProtocol(ret);
1573 // TODO check JAL-357 for files in a jar (CLASSLOADER)
1574 pdb.setFile(ret[0]);
1578 for (int i = 0; i < seqs.length; i++)
1580 if (seqs[i] != null)
1582 ((Sequence) seqs[i]).addPDBId(pdb);
1583 StructureSelectionManager
1584 .getStructureSelectionManager(
1585 (StructureSelectionManagerProvider) this)
1586 .registerPDBEntry(pdb);
1592 // pdbs.add(new Object[] { pdb, seqs, chains, protocol });
1596 StructureViewer.launchStructureViewer(
1597 (alf == null ? getCurrentAlignFrame() : alf).alignPanel,
1603 // if (doAlign && pdbs.size() > 0)
1605 // SequenceI[][] seqs = new SequenceI[pdbs.size()][];
1606 // PDBEntry[] pdb = new PDBEntry[pdbs.size()];
1607 // String[][] chains = new String[pdbs.size()][];
1608 // String[] protocols = new String[pdbs.size()];
1609 // for (int pdbsi = 0, pdbsiSize = pdbs
1610 // .size(); pdbsi < pdbsiSize; pdbsi++)
1612 // Object[] o = pdbs.get(pdbsi);
1613 // pdb[pdbsi] = (PDBEntry) o[0];
1614 // seqs[pdbsi] = (SequenceI[]) o[1];
1615 // chains[pdbsi] = (String[]) o[2];
1616 // protocols[pdbsi] = (String) o[3];
1618 //// alignedStructureView(pdb, seqs, chains, protocols);
1625 * Load a score file if specified by parameter. Returns true if file was
1626 * loaded, else false.
1628 * @param loaderFrame
1630 private boolean initScoreFile(AlignFrame alf)
1633 String sScoreFile = getParameter("scoreFile");
1634 if (sScoreFile != null && !"".equals(sScoreFile))
1638 if (loadScoreFile(sScoreFile, alf))
1643 "Failed to parse T-COFFEE parameter as a valid score file ('"
1644 + sScoreFile + "')");
1645 } catch (Exception e)
1647 System.err.printf("Cannot read score file: '%s'. Cause: %s \n",
1648 sScoreFile, e.getMessage());
1655 * Load a tree for the alignment if specified by parameter. Returns true if a
1656 * tree was loaded, else false.
1660 private boolean initTree(AlignFrame alf)
1663 if ((treeFile = getParameter("tree")) == null
1664 && (treeFile = getParameter("treefile")) == null)
1667 alf = getCurrentAlignFrame();
1671 NewickFile nf = new NewickFile(treeFile, resolveFileProtocol(ret));
1673 if (nf.getTree() != null)
1677 .setCurrentTree(alf.showNewickTree(nf, treeFile).getTree());
1680 } catch (Exception ex)
1682 ex.printStackTrace();
1687 private void updateForAnnotations()
1689 getCurrentAlignFrame().updateForAnnotations();