Clover icon

Coverage Report

  1. Project Clover database Wed Dec 3 2025 17:03:17 GMT
  2. Package jalview.bin

File JalviewLite.java

 

Coverage histogram

../../img/srcFileCovDistChart1.png
57% of files have more coverage

Code metrics

422
859
113
3
3,061
2,164
383
0.45
7.6
37.67
3.39

Classes

Class Line # Actions
JalviewLite 89 612 293
0.0237388722.4%
JalviewLite.LoadJmolThread 1793 16 9
0.00%
JalviewLite.LoadingThread 1842 231 81
0.00%
 

Contributing tests

This file is covered by 1 test. .

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ The Jalview Authors
4    *
5    * This file is part of Jalview.
6    *
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.
11    *
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.
16    *
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.
20    */
21    package jalview.bin;
22   
23    import java.applet.Applet;
24    import java.awt.Button;
25    import java.awt.Color;
26    import java.awt.Component;
27    import java.awt.EventQueue;
28    import java.awt.Font;
29    import java.awt.Frame;
30    import java.awt.Graphics;
31    import java.awt.event.ActionEvent;
32    import java.awt.event.WindowAdapter;
33    import java.awt.event.WindowEvent;
34    import java.io.BufferedReader;
35    import java.io.IOException;
36    import java.io.InputStreamReader;
37    import java.net.URL;
38    import java.util.ArrayList;
39    import java.util.Hashtable;
40    import java.util.List;
41    import java.util.Locale;
42    import java.util.StringTokenizer;
43    import java.util.Vector;
44   
45    import jalview.analysis.AlignmentUtils;
46    import jalview.api.StructureSelectionManagerProvider;
47    import jalview.appletgui.AlignFrame;
48    import jalview.appletgui.AlignViewport;
49    import jalview.appletgui.EmbmenuFrame;
50    import jalview.appletgui.FeatureSettings;
51    import jalview.appletgui.SplitFrame;
52    import jalview.datamodel.Alignment;
53    import jalview.datamodel.AlignmentI;
54    import jalview.datamodel.AlignmentOrder;
55    import jalview.datamodel.ColumnSelection;
56    import jalview.datamodel.PDBEntry;
57    import jalview.datamodel.Sequence;
58    import jalview.datamodel.SequenceGroup;
59    import jalview.datamodel.SequenceI;
60    import jalview.io.AnnotationFile;
61    import jalview.io.AppletFormatAdapter;
62    import jalview.io.DataSourceType;
63    import jalview.io.FileFormatI;
64    import jalview.io.FileFormats;
65    import jalview.io.FileParse;
66    import jalview.io.IdentifyFile;
67    import jalview.io.JPredFile;
68    import jalview.io.JnetAnnotationMaker;
69    import jalview.io.NewickFile;
70    import jalview.appletgui.js.JSFunctionExec;
71    import jalview.appletgui.js.JalviewLiteJsApi;
72    import jalview.appletgui.js.JsCallBack;
73    import jalview.appletgui.js.JsSelectionSender;
74    import jalview.appletgui.js.MouseOverListener;
75    import jalview.appletgui.js.MouseOverStructureListener;
76    import jalview.structure.SelectionListener;
77    import jalview.structure.StructureSelectionManager;
78    import jalview.util.ColorUtils;
79    import jalview.util.HttpUtils;
80    import jalview.util.MessageManager;
81    import netscape.javascript.JSObject;
82   
83    /**
84    * Jalview Applet. Runs in Java 1.18 runtime
85    *
86    * @author $author$
87    * @version $Revision: 1.92 $
88    */
 
89    public class JalviewLite extends Applet
90    implements StructureSelectionManagerProvider, JalviewLiteJsApi
91    {
92   
93    private static final String TRUE = "true";
94   
95    private static final String FALSE = "false";
96   
 
97  0 toggle public StructureSelectionManager getStructureSelectionManager()
98    {
99  0 return StructureSelectionManager.getStructureSelectionManager(this);
100    }
101   
102    // /////////////////////////////////////////
103    // The following public methods may be called
104    // externally, eg via javascript in HTML page
105    /*
106    * (non-Javadoc)
107    *
108    * @see jalview.bin.JalviewLiteJsApi#getSelectedSequences()
109    */
 
110  0 toggle @Override
111    public String getSelectedSequences()
112    {
113  0 return getSelectedSequencesFrom(getDefaultTargetFrame());
114    }
115   
116    /*
117    * (non-Javadoc)
118    *
119    * @see jalview.bin.JalviewLiteJsApi#getSelectedSequences(java.lang.String)
120    */
 
121  0 toggle @Override
122    public String getSelectedSequences(String sep)
123    {
124  0 return getSelectedSequencesFrom(getDefaultTargetFrame(), sep);
125    }
126   
127    /*
128    * (non-Javadoc)
129    *
130    * @see
131    * jalview.bin.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
132    * .AlignFrame)
133    */
 
134  0 toggle @Override
135    public String getSelectedSequencesFrom(AlignFrame alf)
136    {
137  0 return getSelectedSequencesFrom(alf, separator); // ""+0x00AC);
138    }
139   
140    /*
141    * (non-Javadoc)
142    *
143    * @see
144    * jalview.bin.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
145    * .AlignFrame, java.lang.String)
146    */
 
147  0 toggle @Override
148    public String getSelectedSequencesFrom(AlignFrame alf, String sep)
149    {
150  0 StringBuffer result = new StringBuffer("");
151  0 if (sep == null || sep.length() == 0)
152    {
153  0 sep = separator; // "+0x00AC;
154    }
155  0 if (alf.viewport.getSelectionGroup() != null)
156    {
157  0 SequenceI[] seqs = alf.viewport.getSelectionGroup()
158    .getSequencesInOrder(alf.viewport.getAlignment());
159   
160  0 for (int i = 0; i < seqs.length; i++)
161    {
162  0 result.append(seqs[i].getName());
163  0 result.append(sep);
164    }
165    }
166   
167  0 return result.toString();
168    }
169   
170    /*
171    * (non-Javadoc)
172    *
173    * @see jalview.bin.JalviewLiteJsApi#highlight(java.lang.String,
174    * java.lang.String, java.lang.String)
175    */
 
176  0 toggle @Override
177    public void highlight(String sequenceId, String position,
178    String alignedPosition)
179    {
180  0 highlightIn(getDefaultTargetFrame(), sequenceId, position,
181    alignedPosition);
182    }
183   
184    /*
185    * (non-Javadoc)
186    *
187    * @see jalview.bin.JalviewLiteJsApi#highlightIn(jalview.appletgui.AlignFrame,
188    * java.lang.String, java.lang.String, java.lang.String)
189    */
 
190  0 toggle @Override
191    public void highlightIn(final AlignFrame alf, final String sequenceId,
192    final String position, final String alignedPosition)
193    {
194    // TODO: could try to highlight in all alignments if alf==null
195  0 jalview.analysis.SequenceIdMatcher matcher = new jalview.analysis.SequenceIdMatcher(
196    alf.viewport.getAlignment().getSequencesArray());
197  0 final SequenceI sq = matcher.findIdMatch(sequenceId);
198  0 if (sq != null)
199    {
200  0 int apos = -1;
201  0 try
202    {
203  0 apos = Integer.valueOf(position).intValue();
204  0 apos--;
205    } catch (NumberFormatException ex)
206    {
207  0 return;
208    }
209  0 final StructureSelectionManagerProvider me = this;
210  0 final int pos = apos;
211    // use vamsas listener to broadcast to all listeners in scope
212  0 if (alignedPosition != null
213    && (alignedPosition.trim().length() == 0 || alignedPosition
214    .toLowerCase(Locale.ROOT).indexOf("false") > -1))
215    {
216  0 java.awt.EventQueue.invokeLater(new Runnable()
217    {
 
218  0 toggle @Override
219    public void run()
220    {
221  0 StructureSelectionManager.getStructureSelectionManager(me)
222    .mouseOverVamsasSequence(sq, sq.findIndex(pos), null);
223    }
224    });
225    }
226    else
227    {
228  0 java.awt.EventQueue.invokeLater(new Runnable()
229    {
 
230  0 toggle @Override
231    public void run()
232    {
233  0 StructureSelectionManager.getStructureSelectionManager(me)
234    .mouseOverVamsasSequence(sq, pos, null);
235    }
236    });
237    }
238    }
239    }
240   
241    /*
242    * (non-Javadoc)
243    *
244    * @see jalview.bin.JalviewLiteJsApi#select(java.lang.String,
245    * java.lang.String)
246    */
 
247  0 toggle @Override
248    public void select(String sequenceIds, String columns)
249    {
250  0 selectIn(getDefaultTargetFrame(), sequenceIds, columns, separator);
251    }
252   
253    /*
254    * (non-Javadoc)
255    *
256    * @see jalview.bin.JalviewLiteJsApi#select(java.lang.String,
257    * java.lang.String, java.lang.String)
258    */
 
259  0 toggle @Override
260    public void select(String sequenceIds, String columns, String sep)
261    {
262  0 selectIn(getDefaultTargetFrame(), sequenceIds, columns, sep);
263    }
264   
265    /*
266    * (non-Javadoc)
267    *
268    * @see jalview.bin.JalviewLiteJsApi#selectIn(jalview.appletgui.AlignFrame,
269    * java.lang.String, java.lang.String)
270    */
 
271  0 toggle @Override
272    public void selectIn(AlignFrame alf, String sequenceIds, String columns)
273    {
274  0 selectIn(alf, sequenceIds, columns, separator);
275    }
276   
277    /*
278    * (non-Javadoc)
279    *
280    * @see jalview.bin.JalviewLiteJsApi#selectIn(jalview.appletgui.AlignFrame,
281    * java.lang.String, java.lang.String, java.lang.String)
282    */
 
283  0 toggle @Override
284    public void selectIn(final AlignFrame alf, String sequenceIds,
285    String columns, String sep)
286    {
287  0 if (sep == null || sep.length() == 0)
288    {
289  0 sep = separator;
290    }
291    else
292    {
293  0 if (debug)
294    {
295  0 jalview.bin.Console
296    .errPrintln("Selecting region using separator string '"
297    + separator + "'");
298    }
299    }
300    // deparse fields
301  0 String[] ids = separatorListToArray(sequenceIds, sep);
302  0 String[] cols = separatorListToArray(columns, sep);
303  0 final SequenceGroup sel = new SequenceGroup();
304  0 final ColumnSelection csel = new ColumnSelection();
305  0 AlignmentI al = alf.viewport.getAlignment();
306  0 jalview.analysis.SequenceIdMatcher matcher = new jalview.analysis.SequenceIdMatcher(
307    alf.viewport.getAlignment().getSequencesArray());
308  0 int start = 0, end = al.getWidth(), alw = al.getWidth();
309  0 boolean seqsfound = true;
310  0 if (ids != null && ids.length > 0)
311    {
312  0 seqsfound = false;
313  0 for (int i = 0; i < ids.length; i++)
314    {
315  0 if (ids[i].trim().length() == 0)
316    {
317  0 continue;
318    }
319  0 SequenceI sq = matcher.findIdMatch(ids[i]);
320  0 if (sq != null)
321    {
322  0 seqsfound = true;
323  0 sel.addSequence(sq, false);
324    }
325    }
326    }
327  0 boolean inseqpos = false;
328  0 if (cols != null && cols.length > 0)
329    {
330  0 boolean seset = false;
331  0 for (int i = 0; i < cols.length; i++)
332    {
333  0 String cl = cols[i].trim();
334  0 if (cl.length() == 0)
335    {
336  0 continue;
337    }
338  0 int p;
339  0 if ((p = cl.indexOf("-")) > -1)
340    {
341  0 int from = -1, to = -1;
342  0 try
343    {
344  0 from = Integer.valueOf(cl.substring(0, p)).intValue();
345  0 from--;
346    } catch (NumberFormatException ex)
347    {
348  0 jalview.bin.Console.errPrintln(
349    "ERROR: Couldn't parse first integer in range element column selection string '"
350    + cl + "' - format is 'from-to'");
351  0 return;
352    }
353  0 try
354    {
355  0 to = Integer.valueOf(cl.substring(p + 1)).intValue();
356  0 to--;
357    } catch (NumberFormatException ex)
358    {
359  0 jalview.bin.Console.errPrintln(
360    "ERROR: Couldn't parse second integer in range element column selection string '"
361    + cl + "' - format is 'from-to'");
362  0 return;
363    }
364  0 if (from >= 0 && to >= 0)
365    {
366    // valid range
367  0 if (from < to)
368    {
369  0 int t = to;
370  0 to = from;
371  0 to = t;
372    }
373  0 if (!seset)
374    {
375  0 start = from;
376  0 end = to;
377  0 seset = true;
378    }
379    else
380    {
381    // comment to prevent range extension
382  0 if (start > from)
383    {
384  0 start = from;
385    }
386  0 if (end < to)
387    {
388  0 end = to;
389    }
390    }
391  0 for (int r = from; r <= to; r++)
392    {
393  0 if (r >= 0 && r < alw)
394    {
395  0 csel.addElement(r);
396    }
397    }
398  0 if (debug)
399    {
400  0 jalview.bin.Console.errPrintln("Range '" + cl
401    + "' deparsed as [" + from + "," + to + "]");
402    }
403    }
404    else
405    {
406  0 jalview.bin.Console.errPrintln("ERROR: Invalid Range '" + cl
407    + "' deparsed as [" + from + "," + to + "]");
408    }
409    }
410    else
411    {
412  0 int r = -1;
413  0 try
414    {
415  0 r = Integer.valueOf(cl).intValue();
416  0 r--;
417    } catch (NumberFormatException ex)
418    {
419  0 if (cl.toLowerCase(Locale.ROOT).equals("sequence"))
420    {
421    // we are in the dataset sequence's coordinate frame.
422  0 inseqpos = true;
423    }
424    else
425    {
426  0 jalview.bin.Console.errPrintln(
427    "ERROR: Couldn't parse integer from point selection element of column selection string '"
428    + cl + "'");
429  0 return;
430    }
431    }
432  0 if (r >= 0 && r <= alw)
433    {
434  0 if (!seset)
435    {
436  0 start = r;
437  0 end = r;
438  0 seset = true;
439    }
440    else
441    {
442    // comment to prevent range extension
443  0 if (start > r)
444    {
445  0 start = r;
446    }
447  0 if (end < r)
448    {
449  0 end = r;
450    }
451    }
452  0 csel.addElement(r);
453  0 if (debug)
454    {
455  0 jalview.bin.Console.errPrintln("Point selection '" + cl
456    + "' deparsed as [" + r + "]");
457    }
458    }
459    else
460    {
461  0 jalview.bin.Console
462    .errPrintln("ERROR: Invalid Point selection '" + cl
463    + "' deparsed as [" + r + "]");
464    }
465    }
466    }
467    }
468  0 if (seqsfound)
469    {
470    // we only propagate the selection when it was the null selection, or the
471    // given sequences were found in the alignment.
472  0 if (inseqpos && sel.getSize() > 0)
473    {
474    // assume first sequence provides reference frame ?
475  0 SequenceI rs = sel.getSequenceAt(0);
476  0 start = rs.findIndex(start);
477  0 end = rs.findIndex(end);
478  0 List<Integer> cs = new ArrayList<>(csel.getSelected());
479  0 csel.clear();
480  0 for (Integer selectedCol : cs)
481    {
482  0 csel.addElement(rs.findIndex(selectedCol));
483    }
484    }
485  0 sel.setStartRes(start);
486  0 sel.setEndRes(end);
487  0 EventQueue.invokeLater(new Runnable()
488    {
 
489  0 toggle @Override
490    public void run()
491    {
492  0 alf.select(sel, csel,
493    alf.getAlignViewport().getAlignment().getHiddenColumns());
494    }
495    });
496    }
497    }
498   
499    /*
500    * (non-Javadoc)
501    *
502    * @see
503    * jalview.bin.JalviewLiteJsApi#getSelectedSequencesAsAlignment(java.lang.
504    * String, java.lang.String)
505    */
 
506  0 toggle @Override
507    public String getSelectedSequencesAsAlignment(String format,
508    String suffix)
509    {
510  0 return getSelectedSequencesAsAlignmentFrom(getDefaultTargetFrame(),
511    format, suffix);
512    }
513   
514    /*
515    * (non-Javadoc)
516    *
517    * @see
518    * jalview.bin.JalviewLiteJsApi#getSelectedSequencesAsAlignmentFrom(jalview
519    * .appletgui.AlignFrame, java.lang.String, java.lang.String)
520    */
 
521  0 toggle @Override
522    public String getSelectedSequencesAsAlignmentFrom(AlignFrame alf,
523    String format, String suffix)
524    {
525  0 try
526    {
527  0 FileFormatI theFormat = FileFormats.getInstance().forName(format);
528  0 boolean seqlimits = suffix.equalsIgnoreCase(TRUE);
529  0 if (alf.viewport.getSelectionGroup() != null)
530    {
531    // JBPNote: getSelectionAsNewSequence behaviour has changed - this
532    // method now returns a full copy of sequence data
533    // TODO consider using getSequenceSelection instead here
534  0 String reply = new AppletFormatAdapter().formatSequences(theFormat,
535    new Alignment(alf.viewport.getSelectionAsNewSequence()),
536    seqlimits);
537  0 return reply;
538    }
539    } catch (IllegalArgumentException ex)
540    {
541  0 ex.printStackTrace();
542  0 return "Error retrieving alignment, possibly invalid format specifier: "
543    + format;
544    }
545  0 return "";
546    }
547   
548    /*
549    * (non-Javadoc)
550    *
551    * @see jalview.bin.JalviewLiteJsApi#getAlignmentOrder()
552    */
 
553  0 toggle @Override
554    public String getAlignmentOrder()
555    {
556  0 return getAlignmentOrderFrom(getDefaultTargetFrame());
557    }
558   
559    /*
560    * (non-Javadoc)
561    *
562    * @see
563    * jalview.bin.JalviewLiteJsApi#getAlignmentOrderFrom(jalview.appletgui.AlignFrame
564    * )
565    */
 
566  0 toggle @Override
567    public String getAlignmentOrderFrom(AlignFrame alf)
568    {
569  0 return getAlignmentOrderFrom(alf, separator);
570    }
571   
572    /*
573    * (non-Javadoc)
574    *
575    * @see
576    * jalview.bin.JalviewLiteJsApi#getAlignmentOrderFrom(jalview.appletgui.AlignFrame
577    * , java.lang.String)
578    */
 
579  0 toggle @Override
580    public String getAlignmentOrderFrom(AlignFrame alf, String sep)
581    {
582  0 AlignmentI alorder = alf.getAlignViewport().getAlignment();
583  0 String[] order = new String[alorder.getHeight()];
584  0 for (int i = 0; i < order.length; i++)
585    {
586  0 order[i] = alorder.getSequenceAt(i).getName();
587    }
588  0 return arrayToSeparatorList(order);
589    }
590   
591    /*
592    * (non-Javadoc)
593    *
594    * @see jalview.bin.JalviewLiteJsApi#orderBy(java.lang.String,
595    * java.lang.String)
596    */
 
597  0 toggle @Override
598    public String orderBy(String order, String undoName)
599    {
600  0 return orderBy(order, undoName, separator);
601    }
602   
603    /*
604    * (non-Javadoc)
605    *
606    * @see jalview.bin.JalviewLiteJsApi#orderBy(java.lang.String,
607    * java.lang.String, java.lang.String)
608    */
 
609  0 toggle @Override
610    public String orderBy(String order, String undoName, String sep)
611    {
612  0 return orderAlignmentBy(getDefaultTargetFrame(), order, undoName, sep);
613    }
614   
615    /*
616    * (non-Javadoc)
617    *
618    * @see
619    * jalview.bin.JalviewLiteJsApi#orderAlignmentBy(jalview.appletgui.AlignFrame,
620    * java.lang.String, java.lang.String, java.lang.String)
621    */
 
622  0 toggle @Override
623    public String orderAlignmentBy(AlignFrame alf, String order,
624    String undoName, String sep)
625    {
626  0 String[] ids = separatorListToArray(order, sep);
627  0 SequenceI[] sqs = null;
628  0 if (ids != null && ids.length > 0)
629    {
630  0 jalview.analysis.SequenceIdMatcher matcher = new jalview.analysis.SequenceIdMatcher(
631    alf.viewport.getAlignment().getSequencesArray());
632  0 int s = 0;
633  0 sqs = new SequenceI[ids.length];
634  0 for (int i = 0; i < ids.length; i++)
635    {
636  0 if (ids[i].trim().length() == 0)
637    {
638  0 continue;
639    }
640  0 SequenceI sq = matcher.findIdMatch(ids[i]);
641  0 if (sq != null)
642    {
643  0 sqs[s++] = sq;
644    }
645    }
646  0 if (s > 0)
647    {
648  0 SequenceI[] sqq = new SequenceI[s];
649  0 System.arraycopy(sqs, 0, sqq, 0, s);
650  0 sqs = sqq;
651    }
652    else
653    {
654  0 sqs = null;
655    }
656    }
657  0 if (sqs == null)
658    {
659  0 return "";
660    }
661  0 ;
662  0 final AlignmentOrder aorder = new AlignmentOrder(sqs);
663   
664  0 if (undoName != null && undoName.trim().length() == 0)
665    {
666  0 undoName = null;
667    }
668  0 final String _undoName = undoName;
669    // TODO: deal with synchronization here: cannot raise any events until after
670    // this has returned.
671  0 return alf.sortBy(aorder, _undoName) ? TRUE : "";
672    }
673   
674    /*
675    * (non-Javadoc)
676    *
677    * @see jalview.bin.JalviewLiteJsApi#getAlignment(java.lang.String)
678    */
 
679  0 toggle @Override
680    public String getAlignment(String format)
681    {
682  0 return getAlignmentFrom(getDefaultTargetFrame(), format, TRUE);
683    }
684   
685    /*
686    * (non-Javadoc)
687    *
688    * @see
689    * jalview.bin.JalviewLiteJsApi#getAlignmentFrom(jalview.appletgui.AlignFrame,
690    * java.lang.String)
691    */
 
692  0 toggle @Override
693    public String getAlignmentFrom(AlignFrame alf, String format)
694    {
695  0 return getAlignmentFrom(alf, format, TRUE);
696    }
697   
698    /*
699    * (non-Javadoc)
700    *
701    * @see jalview.bin.JalviewLiteJsApi#getAlignment(java.lang.String,
702    * java.lang.String)
703    */
 
704  0 toggle @Override
705    public String getAlignment(String format, String suffix)
706    {
707  0 return getAlignmentFrom(getDefaultTargetFrame(), format, suffix);
708    }
709   
710    /*
711    * (non-Javadoc)
712    *
713    * @see
714    * jalview.bin.JalviewLiteJsApi#getAlignmentFrom(jalview.appletgui.AlignFrame,
715    * java.lang.String, java.lang.String)
716    */
 
717  0 toggle @Override
718    public String getAlignmentFrom(AlignFrame alf, String format,
719    String suffix)
720    {
721  0 try
722    {
723  0 boolean seqlimits = suffix.equalsIgnoreCase(TRUE);
724   
725  0 FileFormatI theFormat = FileFormats.getInstance().forName(format);
726  0 String reply = new AppletFormatAdapter().formatSequences(theFormat,
727    alf.viewport.getAlignment(), seqlimits);
728  0 return reply;
729    } catch (IllegalArgumentException ex)
730    {
731  0 ex.printStackTrace();
732  0 return "Error retrieving alignment, possibly invalid format specifier: "
733    + format;
734    }
735    }
736   
737    /*
738    * (non-Javadoc)
739    *
740    * @see jalview.bin.JalviewLiteJsApi#loadAnnotation(java.lang.String)
741    */
 
742  0 toggle @Override
743    public void loadAnnotation(String annotation)
744    {
745  0 loadAnnotationFrom(getDefaultTargetFrame(), annotation);
746    }
747   
748    /*
749    * (non-Javadoc)
750    *
751    * @see
752    * jalview.bin.JalviewLiteJsApi#loadAnnotationFrom(jalview.appletgui.AlignFrame
753    * , java.lang.String)
754    */
 
755  0 toggle @Override
756    public void loadAnnotationFrom(AlignFrame alf, String annotation)
757    {
758  0 if (new AnnotationFile().annotateAlignmentView(alf.getAlignViewport(),
759    annotation, DataSourceType.PASTE))
760    {
761  0 alf.alignPanel.fontChanged();
762  0 alf.alignPanel.setScrollValues(0, 0);
763    }
764    else
765    {
766  0 alf.parseFeaturesFile(annotation, DataSourceType.PASTE);
767    }
768    }
769   
770    /*
771    * (non-Javadoc)
772    *
773    * @see jalview.bin.JalviewLiteJsApi#loadAnnotation(java.lang.String)
774    */
 
775  0 toggle @Override
776    public void loadFeatures(String features, boolean autoenabledisplay)
777    {
778  0 loadFeaturesFrom(getDefaultTargetFrame(), features, autoenabledisplay);
779    }
780   
781    /*
782    * (non-Javadoc)
783    *
784    * @see
785    * jalview.bin.JalviewLiteJsApi#loadAnnotationFrom(jalview.appletgui.AlignFrame
786    * , java.lang.String)
787    */
 
788  0 toggle @Override
789    public boolean loadFeaturesFrom(AlignFrame alf, String features,
790    boolean autoenabledisplay)
791    {
792  0 return alf.parseFeaturesFile(features, DataSourceType.PASTE,
793    autoenabledisplay);
794    }
795   
796    /*
797    * (non-Javadoc)
798    *
799    * @see jalview.bin.JalviewLiteJsApi#getFeatures(java.lang.String)
800    */
 
801  0 toggle @Override
802    public String getFeatures(String format)
803    {
804  0 return getFeaturesFrom(getDefaultTargetFrame(), format);
805    }
806   
807    /*
808    * (non-Javadoc)
809    *
810    * @see
811    * jalview.bin.JalviewLiteJsApi#getFeaturesFrom(jalview.appletgui.AlignFrame,
812    * java.lang.String)
813    */
 
814  0 toggle @Override
815    public String getFeaturesFrom(AlignFrame alf, String format)
816    {
817  0 return alf.outputFeatures(false, format);
818    }
819   
820    /*
821    * (non-Javadoc)
822    *
823    * @see jalview.bin.JalviewLiteJsApi#getAnnotation()
824    */
 
825  0 toggle @Override
826    public String getAnnotation()
827    {
828  0 return getAnnotationFrom(getDefaultTargetFrame());
829    }
830   
831    /*
832    * (non-Javadoc)
833    *
834    * @see
835    * jalview.bin.JalviewLiteJsApi#getAnnotationFrom(jalview.appletgui.AlignFrame
836    * )
837    */
 
838  0 toggle @Override
839    public String getAnnotationFrom(AlignFrame alf)
840    {
841  0 return alf.outputAnnotations(false);
842    }
843   
844    /*
845    * (non-Javadoc)
846    *
847    * @see jalview.bin.JalviewLiteJsApi#newView()
848    */
 
849  0 toggle @Override
850    public AlignFrame newView()
851    {
852  0 return newViewFrom(getDefaultTargetFrame());
853    }
854   
855    /*
856    * (non-Javadoc)
857    *
858    * @see jalview.bin.JalviewLiteJsApi#newView(java.lang.String)
859    */
 
860  0 toggle @Override
861    public AlignFrame newView(String name)
862    {
863  0 return newViewFrom(getDefaultTargetFrame(), name);
864    }
865   
866    /*
867    * (non-Javadoc)
868    *
869    * @see jalview.bin.JalviewLiteJsApi#newViewFrom(jalview.appletgui.AlignFrame)
870    */
 
871  0 toggle @Override
872    public AlignFrame newViewFrom(AlignFrame alf)
873    {
874  0 return alf.newView(null);
875    }
876   
877    /*
878    * (non-Javadoc)
879    *
880    * @see jalview.bin.JalviewLiteJsApi#newViewFrom(jalview.appletgui.AlignFrame,
881    * java.lang.String)
882    */
 
883  0 toggle @Override
884    public AlignFrame newViewFrom(AlignFrame alf, String name)
885    {
886  0 return alf.newView(name);
887    }
888   
889    /*
890    * (non-Javadoc)
891    *
892    * @see jalview.bin.JalviewLiteJsApi#loadAlignment(java.lang.String,
893    * java.lang.String)
894    */
 
895  0 toggle @Override
896    public AlignFrame loadAlignment(String text, String title)
897    {
898  0 AlignmentI al = null;
899   
900  0 try
901    {
902  0 FileFormatI format = new IdentifyFile().identify(text,
903    DataSourceType.PASTE);
904  0 al = new AppletFormatAdapter().readFile(text, DataSourceType.PASTE,
905    format);
906  0 if (al.getHeight() > 0)
907    {
908  0 return new AlignFrame(al, this, title, false);
909    }
910    } catch (IOException ex)
911    {
912  0 ex.printStackTrace();
913    }
914  0 return null;
915    }
916   
917    /*
918    * (non-Javadoc)
919    *
920    * @see jalview.bin.JalviewLiteJsApi#setMouseoverListener(java.lang.String)
921    */
 
922  0 toggle @Override
923    public void setMouseoverListener(String listener)
924    {
925  0 setMouseoverListener(currentAlignFrame, listener);
926    }
927   
928    private Vector<JSFunctionExec> javascriptListeners = new Vector<>();
929   
930    /*
931    * (non-Javadoc)
932    *
933    * @see
934    * jalview.bin.JalviewLiteJsApi#setMouseoverListener(jalview.appletgui.AlignFrame
935    * , java.lang.String)
936    */
 
937  0 toggle @Override
938    public void setMouseoverListener(AlignFrame af, String listener)
939    {
940  0 if (listener != null)
941    {
942  0 listener = listener.trim();
943  0 if (listener.length() == 0)
944    {
945  0 jalview.bin.Console.errPrintln(
946    "jalview Javascript error: Ignoring empty function for mouseover listener.");
947  0 return;
948    }
949    }
950  0 MouseOverListener mol = new MouseOverListener(
951    this, af, listener);
952  0 javascriptListeners.addElement(mol);
953  0 StructureSelectionManager.getStructureSelectionManager(this)
954    .addStructureViewerListener(mol);
955  0 if (debug)
956    {
957  0 jalview.bin.Console.errPrintln("Added a mouseover listener for "
958  0 + ((af == null) ? "All frames"
959    : "Just views for "
960    + af.getAlignViewport().getSequenceSetId()));
961  0 jalview.bin.Console.errPrintln("There are now "
962    + javascriptListeners.size() + " listeners in total.");
963    }
964    }
965   
966    /*
967    * (non-Javadoc)
968    *
969    * @see jalview.bin.JalviewLiteJsApi#setSelectionListener(java.lang.String)
970    */
 
971  0 toggle @Override
972    public void setSelectionListener(String listener)
973    {
974  0 setSelectionListener(null, listener);
975    }
976   
977    /*
978    * (non-Javadoc)
979    *
980    * @see
981    * jalview.bin.JalviewLiteJsApi#setSelectionListener(jalview.appletgui.AlignFrame
982    * , java.lang.String)
983    */
 
984  0 toggle @Override
985    public void setSelectionListener(AlignFrame af, String listener)
986    {
987  0 if (listener != null)
988    {
989  0 listener = listener.trim();
990  0 if (listener.length() == 0)
991    {
992  0 jalview.bin.Console.errPrintln(
993    "jalview Javascript error: Ignoring empty function for selection listener.");
994  0 return;
995    }
996    }
997  0 JsSelectionSender mol = new JsSelectionSender(
998    this, af, listener);
999  0 javascriptListeners.addElement(mol);
1000  0 StructureSelectionManager.getStructureSelectionManager(this)
1001    .addSelectionListener(mol);
1002  0 if (debug)
1003    {
1004  0 jalview.bin.Console.errPrintln("Added a selection listener for "
1005  0 + ((af == null) ? "All frames"
1006    : "Just views for "
1007    + af.getAlignViewport().getSequenceSetId()));
1008  0 jalview.bin.Console.errPrintln("There are now "
1009    + javascriptListeners.size() + " listeners in total.");
1010    }
1011    }
1012   
1013    /**
1014    * Callable from javascript to register a javascript function to pass events
1015    * to a structure viewer.
1016    *
1017    * @param listener
1018    * the name of a javascript function
1019    * @param modelSet
1020    * a token separated list of PDB file names listened for
1021    * @see jalview.bin.JalviewLiteJsApi#setStructureListener(java.lang.String,
1022    * java.lang.String)
1023    */
 
1024  0 toggle @Override
1025    public void setStructureListener(String listener, String modelSet)
1026    {
1027  0 if (listener != null)
1028    {
1029  0 listener = listener.trim();
1030  0 if (listener.length() == 0)
1031    {
1032  0 jalview.bin.Console.errPrintln(
1033    "jalview Javascript error: Ignoring empty function for selection listener.");
1034  0 return;
1035    }
1036    }
1037  0 MouseOverStructureListener mol = new MouseOverStructureListener(this,
1038    listener, separatorListToArray(modelSet));
1039  0 javascriptListeners.addElement(mol);
1040  0 StructureSelectionManager.getStructureSelectionManager(this)
1041    .addStructureViewerListener(mol);
1042  0 if (debug)
1043    {
1044  0 jalview.bin.Console
1045    .errPrintln("Added a javascript structure viewer listener '"
1046    + listener + "'");
1047  0 jalview.bin.Console.errPrintln("There are now "
1048    + javascriptListeners.size() + " listeners in total.");
1049    }
1050    }
1051   
1052    /*
1053    * (non-Javadoc)
1054    *
1055    * @see
1056    * jalview.bin.JalviewLiteJsApi#removeJavascriptListener(jalview.appletgui
1057    * .AlignFrame, java.lang.String)
1058    */
 
1059  0 toggle @Override
1060    public void removeJavascriptListener(AlignFrame af, String listener)
1061    {
1062  0 if (listener != null)
1063    {
1064  0 listener = listener.trim();
1065  0 if (listener.length() == 0)
1066    {
1067  0 listener = null;
1068    }
1069    }
1070  0 boolean rprt = false;
1071  0 for (int ms = 0, msSize = javascriptListeners.size(); ms < msSize;)
1072    {
1073  0 Object lstn = javascriptListeners.elementAt(ms);
1074  0 JsCallBack lstner = (JsCallBack) lstn;
1075  0 if ((af == null || lstner.getAlignFrame() == af) && (listener == null
1076    || lstner.getListenerFunction().equals(listener)))
1077    {
1078  0 javascriptListeners.removeElement(lstner);
1079  0 msSize--;
1080  0 if (lstner instanceof SelectionListener)
1081    {
1082  0 StructureSelectionManager.getStructureSelectionManager(this)
1083    .removeSelectionListener((SelectionListener) lstner);
1084    }
1085    else
1086    {
1087  0 StructureSelectionManager.getStructureSelectionManager(this)
1088    .removeStructureViewerListener(lstner, null);
1089    }
1090  0 rprt = debug;
1091  0 if (debug)
1092    {
1093  0 jalview.bin.Console
1094    .errPrintln("Removed listener '" + listener + "'");
1095    }
1096    }
1097    else
1098    {
1099  0 ms++;
1100    }
1101    }
1102  0 if (rprt)
1103    {
1104  0 jalview.bin.Console.errPrintln("There are now "
1105    + javascriptListeners.size() + " listeners in total.");
1106    }
1107    }
1108   
 
1109  0 toggle @Override
1110    public void stop()
1111    {
1112  0 jalview.bin.Console.errPrintln("Applet " + getName() + " stop().");
1113  0 tidyUp();
1114    }
1115   
 
1116  0 toggle @Override
1117    public void destroy()
1118    {
1119  0 jalview.bin.Console.errPrintln("Applet " + getName() + " destroy().");
1120  0 tidyUp();
1121    }
1122   
 
1123  0 toggle private void tidyUp()
1124    {
1125  0 removeAll();
1126  0 if (currentAlignFrame != null && currentAlignFrame.viewport != null
1127    && currentAlignFrame.viewport.applet != null)
1128    {
1129  0 AlignViewport av = currentAlignFrame.viewport;
1130  0 currentAlignFrame.closeMenuItem_actionPerformed();
1131  0 av.applet = null;
1132  0 currentAlignFrame = null;
1133    }
1134  0 if (javascriptListeners != null)
1135    {
1136  0 while (javascriptListeners.size() > 0)
1137    {
1138  0 JSFunctionExec mol = javascriptListeners
1139    .elementAt(0);
1140  0 javascriptListeners.removeElement(mol);
1141  0 if (mol instanceof SelectionListener)
1142    {
1143  0 StructureSelectionManager.getStructureSelectionManager(this)
1144    .removeSelectionListener((SelectionListener) mol);
1145    }
1146    else
1147    {
1148  0 StructureSelectionManager.getStructureSelectionManager(this)
1149    .removeStructureViewerListener(mol, null);
1150    }
1151  0 mol.jvlite = null;
1152    }
1153    }
1154  0 if (jsFunctionExec != null)
1155    {
1156  0 jsFunctionExec.stopQueue();
1157  0 jsFunctionExec.jvlite = null;
1158    }
1159  0 initialAlignFrame = null;
1160  0 jsFunctionExec = null;
1161  0 javascriptListeners = null;
1162  0 StructureSelectionManager.release(this);
1163    }
1164   
1165    private JSFunctionExec jsFunctionExec;
1166   
1167    /*
1168    * (non-Javadoc)
1169    *
1170    * @see jalview.bin.JalviewLiteJsApi#mouseOverStructure(java.lang.String,
1171    * java.lang.String, java.lang.String)
1172    */
 
1173  0 toggle @Override
1174    public void mouseOverStructure(final String pdbResNum, final String chain,
1175    final String pdbfile)
1176    {
1177  0 final StructureSelectionManagerProvider me = this;
1178  0 java.awt.EventQueue.invokeLater(new Runnable()
1179    {
 
1180  0 toggle @Override
1181    public void run()
1182    {
1183  0 try
1184    {
1185  0 StructureSelectionManager.getStructureSelectionManager(me)
1186    .mouseOverStructure(Integer.valueOf(pdbResNum).intValue(),
1187    chain, pdbfile);
1188  0 if (debug)
1189    {
1190  0 System.err
1191    .println("mouseOver for '" + pdbResNum + "' in chain '"
1192    + chain + "' in structure '" + pdbfile + "'");
1193    }
1194    } catch (NumberFormatException e)
1195    {
1196  0 jalview.bin.Console
1197    .errPrintln("Ignoring invalid residue number string '"
1198    + pdbResNum + "'");
1199    }
1200   
1201    }
1202    });
1203    }
1204   
1205    /*
1206    * (non-Javadoc)
1207    *
1208    * @see
1209    * jalview.bin.JalviewLiteJsApi#scrollViewToIn(jalview.appletgui.AlignFrame,
1210    * java.lang.String, java.lang.String)
1211    */
 
1212  0 toggle @Override
1213    public void scrollViewToIn(final AlignFrame alf, final String topRow,
1214    final String leftHandColumn)
1215    {
1216  0 java.awt.EventQueue.invokeLater(new Runnable()
1217    {
 
1218  0 toggle @Override
1219    public void run()
1220    {
1221  0 try
1222    {
1223  0 alf.scrollTo(Integer.valueOf(topRow).intValue(),
1224    Integer.valueOf(leftHandColumn).intValue());
1225   
1226    } catch (Exception ex)
1227    {
1228  0 jalview.bin.Console
1229    .errPrintln("Couldn't parse integer arguments (topRow='"
1230    + topRow + "' and leftHandColumn='"
1231    + leftHandColumn + "')");
1232  0 ex.printStackTrace();
1233    }
1234    }
1235    });
1236    }
1237   
1238    /*
1239    * (non-Javadoc)
1240    *
1241    * @see
1242    * JalviewLiteJsApi#scrollViewToRowIn(jalview.appletgui
1243    * .AlignFrame, java.lang.String)
1244    */
 
1245  0 toggle @Override
1246    public void scrollViewToRowIn(final AlignFrame alf, final String topRow)
1247    {
1248   
1249  0 java.awt.EventQueue.invokeLater(new Runnable()
1250    {
 
1251  0 toggle @Override
1252    public void run()
1253    {
1254  0 try
1255    {
1256  0 alf.scrollToRow(Integer.valueOf(topRow).intValue());
1257   
1258    } catch (Exception ex)
1259    {
1260  0 jalview.bin.Console
1261    .errPrintln("Couldn't parse integer arguments (topRow='"
1262    + topRow + "')");
1263  0 ex.printStackTrace();
1264    }
1265   
1266    }
1267    });
1268    }
1269   
1270    /*
1271    * (non-Javadoc)
1272    *
1273    * @see
1274    * JalviewLiteJsApi#scrollViewToColumnIn(jalview.appletgui
1275    * .AlignFrame, java.lang.String)
1276    */
 
1277  0 toggle @Override
1278    public void scrollViewToColumnIn(final AlignFrame alf,
1279    final String leftHandColumn)
1280    {
1281  0 java.awt.EventQueue.invokeLater(new Runnable()
1282    {
1283   
 
1284  0 toggle @Override
1285    public void run()
1286    {
1287  0 try
1288    {
1289  0 alf.scrollToColumn(Integer.valueOf(leftHandColumn).intValue());
1290   
1291    } catch (Exception ex)
1292    {
1293  0 jalview.bin.Console.errPrintln(
1294    "Couldn't parse integer arguments (leftHandColumn='"
1295    + leftHandColumn + "')");
1296  0 ex.printStackTrace();
1297    }
1298    }
1299    });
1300   
1301    }
1302   
1303    // //////////////////////////////////////////////
1304    // //////////////////////////////////////////////
1305   
1306    public static int lastFrameX = 200;
1307   
1308    public static int lastFrameY = 200;
1309   
1310    boolean fileFound = true;
1311   
1312    String file = "No file";
1313   
1314    String file2 = null;
1315   
1316    Button launcher = new Button(
1317    MessageManager.getString("label.start_jalview"));
1318   
1319    /**
1320    * The currentAlignFrame is static, it will change if and when the user
1321    * selects a new window. Note that it will *never* point back to the embedded
1322    * AlignFrame if the applet is started as embedded on the page and then
1323    * afterwards a new view is created.
1324    */
1325    public AlignFrame currentAlignFrame = null;
1326   
1327    /**
1328    * This is the first frame to be displayed, and does not change. API calls
1329    * will default to this instance if currentAlignFrame is null.
1330    */
1331    AlignFrame initialAlignFrame = null;
1332   
1333    boolean embedded = false;
1334   
1335    private boolean checkForJmol = true;
1336   
1337    private boolean checkedForJmol = false; // ensure we don't check for jmol
1338   
1339    // every time the app is re-inited
1340   
1341    public boolean jmolAvailable = false;
1342   
1343    private boolean alignPdbStructures = false;
1344   
1345    /**
1346    * use an external structure viewer exclusively (no jmols or mc_views will be
1347    * opened by JalviewLite itself)
1348    */
1349    public boolean useXtrnalSviewer = false;
1350   
1351    public static boolean debug = false;
1352   
1353    static String builddate = null, version = null, installation = null;
1354   
 
1355  0 toggle private static void initBuildDetails()
1356    {
1357  0 if (builddate == null)
1358    {
1359  0 builddate = "unknown";
1360  0 version = "test";
1361  0 installation = "applet";
1362  0 java.net.URL url = JalviewLite.class
1363    .getResource("/.build_properties");
1364  0 if (url != null)
1365    {
1366  0 try
1367    {
1368  0 BufferedReader reader = new BufferedReader(
1369    new InputStreamReader(HttpUtils.openStream(url)));
1370  0 String line;
1371  0 while ((line = reader.readLine()) != null)
1372    {
1373  0 if (line.indexOf("VERSION") > -1)
1374    {
1375  0 version = line.substring(line.indexOf("=") + 1);
1376    }
1377  0 if (line.indexOf("BUILD_DATE") > -1)
1378    {
1379  0 builddate = line.substring(line.indexOf("=") + 1);
1380    }
1381  0 if (line.indexOf("INSTALLATION") > -1)
1382    {
1383  0 installation = line.substring(line.indexOf("=") + 1);
1384    }
1385    }
1386    } catch (Exception ex)
1387    {
1388  0 ex.printStackTrace();
1389    }
1390    }
1391    }
1392    }
1393   
 
1394  0 toggle public static String getBuildDate()
1395    {
1396  0 initBuildDetails();
1397  0 return builddate;
1398    }
1399   
 
1400  0 toggle public static String getInstallation()
1401    {
1402  0 initBuildDetails();
1403  0 return installation;
1404    }
1405   
 
1406  0 toggle public static String getVersion()
1407    {
1408  0 initBuildDetails();
1409  0 return version;
1410    }
1411   
1412    // public JSObject scriptObject = null;
1413   
1414    /**
1415    * init method for Jalview Applet
1416    */
 
1417  0 toggle @Override
1418    public void init()
1419    {
1420  0 debug = TRUE.equalsIgnoreCase(getParameter("debug"));
1421  0 try
1422    {
1423  0 if (debug)
1424    {
1425  0 jalview.bin.Console.errPrintln("Applet context is '"
1426    + getAppletContext().getClass().toString() + "'");
1427    }
1428  0 JSObject scriptObject = JSObject.getWindow(this);
1429  0 if (debug && scriptObject != null)
1430    {
1431  0 jalview.bin.Console
1432    .errPrintln("Applet has Javascript callback support.");
1433    }
1434   
1435    } catch (Exception ex)
1436    {
1437  0 jalview.bin.Console.errPrintln(
1438    "Warning: No JalviewLite javascript callbacks available.");
1439  0 if (debug)
1440    {
1441  0 ex.printStackTrace();
1442    }
1443    }
1444   
1445  0 if (debug)
1446    {
1447  0 jalview.bin.Console.errPrintln("JalviewLite Version " + getVersion());
1448  0 jalview.bin.Console.errPrintln("Build Date : " + getBuildDate());
1449  0 jalview.bin.Console.errPrintln("Installation : " + getInstallation());
1450    }
1451  0 String externalsviewer = getParameter("externalstructureviewer");
1452  0 if (externalsviewer != null)
1453    {
1454  0 useXtrnalSviewer = externalsviewer.trim().toLowerCase(Locale.ROOT)
1455    .equals(TRUE);
1456    }
1457    /**
1458    * if true disable the check for jmol
1459    */
1460  0 String chkforJmol = getParameter("nojmol");
1461  0 if (chkforJmol != null)
1462    {
1463  0 checkForJmol = !chkforJmol.equals(TRUE);
1464    }
1465    /**
1466    * get the separator parameter if present
1467    */
1468  0 String sep = getParameter("separator");
1469  0 if (sep != null)
1470    {
1471  0 if (sep.length() > 0)
1472    {
1473  0 separator = sep;
1474  0 if (debug)
1475    {
1476  0 jalview.bin.Console
1477    .errPrintln("Separator set to '" + separator + "'");
1478    }
1479    }
1480    else
1481    {
1482  0 throw new Error(MessageManager
1483    .getString("error.invalid_separator_parameter"));
1484    }
1485    }
1486  0 int r = 255;
1487  0 int g = 255;
1488  0 int b = 255;
1489  0 String param = getParameter("RGB");
1490   
1491  0 if (param != null)
1492    {
1493  0 try
1494    {
1495  0 r = Integer.parseInt(param.substring(0, 2), 16);
1496  0 g = Integer.parseInt(param.substring(2, 4), 16);
1497  0 b = Integer.parseInt(param.substring(4, 6), 16);
1498    } catch (Exception ex)
1499    {
1500  0 r = 255;
1501  0 g = 255;
1502  0 b = 255;
1503    }
1504    }
1505  0 param = getParameter("label");
1506  0 if (param != null)
1507    {
1508  0 launcher.setLabel(param);
1509    }
1510   
1511  0 setBackground(new Color(r, g, b));
1512   
1513  0 file = getParameter("file");
1514   
1515  0 if (file == null)
1516    {
1517    // Maybe the sequences are added as parameters
1518  0 StringBuffer data = new StringBuffer("PASTE");
1519  0 int i = 1;
1520  0 while ((file = getParameter("sequence" + i)) != null)
1521    {
1522  0 data.append(file.toString() + "\n");
1523  0 i++;
1524    }
1525  0 if (data.length() > 5)
1526    {
1527  0 file = data.toString();
1528    }
1529    }
1530  0 if (getDefaultParameter("enableSplitFrame", true))
1531    {
1532  0 file2 = getParameter("file2");
1533    }
1534   
1535  0 embedded = TRUE.equalsIgnoreCase(getParameter("embedded"));
1536  0 if (embedded)
1537    {
1538  0 LoadingThread loader = new LoadingThread(file, file2, this);
1539  0 loader.start();
1540    }
1541  0 else if (file != null)
1542    {
1543    /*
1544    * Start the applet immediately or show a button to start it
1545    */
1546  0 if (FALSE.equalsIgnoreCase(getParameter("showbutton")))
1547    {
1548  0 LoadingThread loader = new LoadingThread(file, file2, this);
1549  0 loader.start();
1550    }
1551    else
1552    {
1553  0 add(launcher);
1554  0 launcher.addActionListener(new java.awt.event.ActionListener()
1555    {
 
1556  0 toggle @Override
1557    public void actionPerformed(ActionEvent e)
1558    {
1559  0 LoadingThread loader = new LoadingThread(file, file2,
1560    JalviewLite.this);
1561  0 loader.start();
1562    }
1563    });
1564    }
1565    }
1566    else
1567    {
1568    // jalview initialisation with no alignment. loadAlignment() method can
1569    // still be called to open new alignments.
1570  0 file = "NO FILE";
1571  0 fileFound = false;
1572  0 callInitCallback();
1573    }
1574    }
1575   
 
1576  0 toggle private void initLiveConnect()
1577    {
1578    // try really hard to get the liveConnect thing working
1579  0 boolean notFailed = false;
1580  0 int tries = 0;
1581  0 while (!notFailed && tries < 10)
1582    {
1583  0 if (tries > 0)
1584    {
1585  0 jalview.bin.Console
1586    .errPrintln("LiveConnect request thread going to sleep.");
1587    }
1588  0 try
1589    {
1590  0 Thread.sleep(700 * (1 + tries));
1591    } catch (InterruptedException q)
1592    {
1593    }
1594  0 ;
1595  0 if (tries++ > 0)
1596    {
1597  0 jalview.bin.Console
1598    .errPrintln("LiveConnect request thread woken up.");
1599    }
1600  0 try
1601    {
1602  0 JSObject scriptObject = JSObject.getWindow(this);
1603  0 if (scriptObject.eval("navigator") != null)
1604    {
1605  0 notFailed = true;
1606    }
1607    } catch (Exception jsex)
1608    {
1609  0 jalview.bin.Console.errPrintln("Attempt " + tries
1610    + " to access LiveConnect javascript failed.");
1611    }
1612    }
1613    }
1614   
 
1615  0 toggle private void callInitCallback()
1616    {
1617  0 String initjscallback = getParameter("oninit");
1618  0 if (initjscallback == null)
1619    {
1620  0 return;
1621    }
1622  0 initjscallback = initjscallback.trim();
1623  0 if (initjscallback.length() > 0)
1624    {
1625  0 JSObject scriptObject = null;
1626  0 try
1627    {
1628  0 scriptObject = JSObject.getWindow(this);
1629    } catch (Exception ex)
1630    {
1631    }
1632  0 ;
1633    // try really hard to let the browser plugin know we want liveconnect
1634  0 initLiveConnect();
1635   
1636  0 if (scriptObject != null)
1637    {
1638  0 try
1639    {
1640    // do onInit with the JS executor thread
1641  0 new JSFunctionExec(this).executeJavascriptFunction(true,
1642    initjscallback, null,
1643    "Calling oninit callback '" + initjscallback + "'.");
1644    } catch (Exception e)
1645    {
1646  0 jalview.bin.Console
1647    .errPrintln("Exception when executing _oninit callback '"
1648    + initjscallback + "'.");
1649  0 e.printStackTrace();
1650    }
1651    }
1652    else
1653    {
1654  0 jalview.bin.Console.errPrintln("Not executing _oninit callback '"
1655    + initjscallback + "' - no scripting allowed.");
1656    }
1657    }
1658    }
1659   
1660    /**
1661    * Initialises and displays a new java.awt.Frame
1662    *
1663    * @param frame
1664    * java.awt.Frame to be displayed
1665    * @param title
1666    * title of new frame
1667    * @param width
1668    * width if new frame
1669    * @param height
1670    * height of new frame
1671    */
 
1672  0 toggle public static void addFrame(final Frame frame, String title, int width,
1673    int height)
1674    {
1675  0 frame.setLocation(lastFrameX, lastFrameY);
1676  0 lastFrameX += 40;
1677  0 lastFrameY += 40;
1678  0 frame.setSize(width, height);
1679  0 frame.setTitle(title);
1680  0 frame.addWindowListener(new WindowAdapter()
1681    {
 
1682  0 toggle @Override
1683    public void windowClosing(WindowEvent e)
1684    {
1685  0 if (frame instanceof AlignFrame)
1686    {
1687  0 AlignViewport vp = ((AlignFrame) frame).viewport;
1688  0 ((AlignFrame) frame).closeMenuItem_actionPerformed();
1689  0 if (vp.applet.currentAlignFrame == frame)
1690    {
1691  0 vp.applet.currentAlignFrame = null;
1692    }
1693  0 vp.applet = null;
1694  0 vp = null;
1695   
1696    }
1697  0 lastFrameX -= 40;
1698  0 lastFrameY -= 40;
1699  0 if (frame instanceof EmbmenuFrame)
1700    {
1701  0 ((EmbmenuFrame) frame).destroyMenus();
1702    }
1703  0 frame.setMenuBar(null);
1704  0 frame.dispose();
1705    }
1706   
 
1707  0 toggle @Override
1708    public void windowActivated(WindowEvent e)
1709    {
1710  0 if (frame instanceof AlignFrame)
1711    {
1712  0 ((AlignFrame) frame).viewport.applet.currentAlignFrame = (AlignFrame) frame;
1713  0 if (debug)
1714    {
1715  0 jalview.bin.Console.errPrintln("Activated window " + frame);
1716    }
1717    }
1718    // be good.
1719  0 super.windowActivated(e);
1720    }
1721    /*
1722    * Probably not necessary to do this - see TODO above. (non-Javadoc)
1723    *
1724    * @see
1725    * java.awt.event.WindowAdapter#windowDeactivated(java.awt.event.WindowEvent
1726    * )
1727    *
1728    * public void windowDeactivated(WindowEvent e) { if (currentAlignFrame ==
1729    * frame) { currentAlignFrame = null; if (debug) {
1730    * jalview.bin.Console.errPrintln("Deactivated window "+frame); } }
1731    * super.windowDeactivated(e); }
1732    */
1733    });
1734  0 frame.setVisible(true);
1735    }
1736   
1737    /**
1738    * This paints the background surrounding the "Launch Jalview button" <br>
1739    * <br>
1740    * If file given in parameter not found, displays error message
1741    *
1742    * @param g
1743    * graphics context
1744    */
 
1745  0 toggle @Override
1746    public void paint(Graphics g)
1747    {
1748  0 if (!fileFound)
1749    {
1750  0 g.setColor(new Color(200, 200, 200));
1751  0 g.setColor(Color.cyan);
1752  0 g.fillRect(0, 0, getSize().width, getSize().height);
1753  0 g.setColor(Color.red);
1754  0 g.drawString(
1755    MessageManager.getString("label.jalview_cannot_open_file"), 5,
1756    15);
1757  0 g.drawString("\"" + file + "\"", 5, 30);
1758    }
1759  0 else if (embedded)
1760    {
1761  0 g.setColor(Color.black);
1762  0 g.setFont(new Font("Arial", Font.BOLD, 24));
1763  0 g.drawString(MessageManager.getString("label.jalview_applet"), 50,
1764    getSize().height / 2 - 30);
1765  0 g.drawString(MessageManager.getString("label.loading_data") + "...",
1766    50, getSize().height / 2);
1767    }
1768    }
1769   
1770    /**
1771    * get all components associated with the applet of the given type
1772    *
1773    * @param class1
1774    * @return
1775    */
 
1776  0 toggle public Vector getAppletWindow(Class class1)
1777    {
1778  0 Vector wnds = new Vector();
1779  0 Component[] cmp = getComponents();
1780  0 if (cmp != null)
1781    {
1782  0 for (int i = 0; i < cmp.length; i++)
1783    {
1784  0 if (class1.isAssignableFrom(cmp[i].getClass()))
1785    {
1786  0 wnds.addElement(cmp);
1787    }
1788    }
1789    }
1790  0 return wnds;
1791    }
1792   
 
1793    class LoadJmolThread extends Thread
1794    {
1795    private boolean running = false;
1796   
 
1797  0 toggle @Override
1798    public void run()
1799    {
1800  0 if (running || checkedForJmol)
1801    {
1802  0 return;
1803    }
1804  0 running = true;
1805  0 if (checkForJmol)
1806    {
1807  0 try
1808    {
1809  0 if (!System.getProperty("java.version").startsWith("1.1"))
1810    {
1811  0 Class.forName("org.jmol.adapter.smarter.SmarterJmolAdapter");
1812  0 jmolAvailable = true;
1813    }
1814  0 if (!jmolAvailable)
1815    {
1816  0 jalview.bin.Console.outPrintln(
1817    "Jmol not available - Using mc_view for structures");
1818    }
1819    } catch (java.lang.ClassNotFoundException ex)
1820    {
1821    }
1822    }
1823    else
1824    {
1825  0 jmolAvailable = false;
1826  0 if (debug)
1827    {
1828  0 jalview.bin.Console.errPrintln(
1829    "Skipping Jmol check. Will use mc_view (probably)");
1830    }
1831    }
1832  0 checkedForJmol = true;
1833  0 running = false;
1834    }
1835   
 
1836  0 toggle public boolean notFinished()
1837    {
1838  0 return running || !checkedForJmol;
1839    }
1840    }
1841   
 
1842    class LoadingThread extends Thread
1843    {
1844    /**
1845    * State variable: protocol for access to file source
1846    */
1847    DataSourceType protocol;
1848   
1849    String _file; // alignment file or URL spec
1850   
1851    String _file2; // second alignment file or URL spec
1852   
1853    JalviewLite applet;
1854   
 
1855  0 toggle private void dbgMsg(String msg)
1856    {
1857  0 if (JalviewLite.debug)
1858    {
1859  0 jalview.bin.Console.errPrintln(msg);
1860    }
1861    }
1862   
1863    /**
1864    * update the protocol state variable for accessing the datasource located
1865    * by file.
1866    *
1867    * @param path
1868    * @return possibly updated datasource string
1869    */
 
1870  0 toggle public String resolveFileProtocol(String path)
1871    {
1872    /*
1873    * is it paste data?
1874    */
1875  0 if (path.startsWith("PASTE"))
1876    {
1877  0 protocol = DataSourceType.PASTE;
1878  0 return path.substring(5);
1879    }
1880   
1881    /*
1882    * is it a URL?
1883    */
1884  0 if (path.indexOf("://") != -1)
1885    {
1886  0 protocol = DataSourceType.URL;
1887  0 return path;
1888    }
1889   
1890    /*
1891    * try relative to document root
1892    */
1893  0 URL documentBase = getDocumentBase();
1894  0 String withDocBase = resolveUrlForLocalOrAbsolute(path, documentBase);
1895  0 if (HttpUtils.isValidUrl(withDocBase))
1896    {
1897  0 if (debug)
1898    {
1899  0 jalview.bin.Console.errPrintln("Prepended document base '"
1900    + documentBase + "' to make: '" + withDocBase + "'");
1901    }
1902  0 protocol = DataSourceType.URL;
1903  0 return withDocBase;
1904    }
1905   
1906    /*
1907    * try relative to codebase (if different to document base)
1908    */
1909  0 URL codeBase = getCodeBase();
1910  0 String withCodeBase = applet.resolveUrlForLocalOrAbsolute(path,
1911    codeBase);
1912  0 if (!withCodeBase.equals(withDocBase)
1913    && HttpUtils.isValidUrl(withCodeBase))
1914    {
1915  0 protocol = DataSourceType.URL;
1916  0 if (debug)
1917    {
1918  0 jalview.bin.Console.errPrintln("Prepended codebase '" + codeBase
1919    + "' to make: '" + withCodeBase + "'");
1920    }
1921  0 return withCodeBase;
1922    }
1923   
1924    /*
1925    * try locating by classloader; try this last so files in the directory
1926    * are resolved using document base
1927    */
1928  0 if (inArchive(path))
1929    {
1930  0 protocol = DataSourceType.CLASSLOADER;
1931    }
1932  0 return path;
1933    }
1934   
 
1935  0 toggle public LoadingThread(String file, String file2, JalviewLite _applet)
1936    {
1937  0 this._file = file;
1938  0 this._file2 = file2;
1939  0 applet = _applet;
1940    }
1941   
 
1942  0 toggle @Override
1943    public void run()
1944    {
1945  0 LoadJmolThread jmolchecker = new LoadJmolThread();
1946  0 jmolchecker.start();
1947  0 while (jmolchecker.notFinished())
1948    {
1949    // wait around until the Jmol check is complete.
1950  0 try
1951    {
1952  0 Thread.sleep(2);
1953    } catch (Exception e)
1954    {
1955    }
1956    }
1957  0 startLoading();
1958    // applet.callInitCallback();
1959    }
1960   
1961    /**
1962    * Load the alignment and any related files as specified by applet
1963    * parameters
1964    */
 
1965  0 toggle private void startLoading()
1966    {
1967  0 dbgMsg("Loading thread started with:\n>>file\n" + _file
1968    + ">>endfile");
1969   
1970  0 dbgMsg("Loading started.");
1971   
1972  0 AlignFrame newAlignFrame = readAlignment(_file);
1973  0 AlignFrame newAlignFrame2 = readAlignment(_file2);
1974  0 if (newAlignFrame != null)
1975    {
1976  0 addToDisplay(newAlignFrame, newAlignFrame2);
1977  0 loadTree(newAlignFrame);
1978   
1979  0 loadScoreFile(newAlignFrame);
1980   
1981  0 loadFeatures(newAlignFrame);
1982   
1983  0 loadAnnotations(newAlignFrame);
1984   
1985  0 loadJnetFile(newAlignFrame);
1986   
1987  0 loadPdbFiles(newAlignFrame);
1988    }
1989    else
1990    {
1991  0 fileFound = false;
1992  0 applet.remove(launcher);
1993  0 applet.repaint();
1994    }
1995  0 callInitCallback();
1996    }
1997   
1998    /**
1999    * Add an AlignFrame to the display; or if two are provided, a SplitFrame.
2000    *
2001    * @param af
2002    * @param af2
2003    */
 
2004  0 toggle public void addToDisplay(AlignFrame af, AlignFrame af2)
2005    {
2006  0 if (af2 != null)
2007    {
2008  0 AlignmentI al1 = af.viewport.getAlignment();
2009  0 AlignmentI al2 = af2.viewport.getAlignment();
2010  0 AlignmentI cdna = al1.isNucleotide() ? al1 : al2;
2011  0 AlignmentI prot = al1.isNucleotide() ? al2 : al1;
2012  0 if (AlignmentUtils.mapProteinAlignmentToCdna(prot, cdna))
2013    {
2014  0 al2.alignAs(al1);
2015  0 SplitFrame sf = new SplitFrame(af, af2);
2016  0 sf.addToDisplay(embedded, JalviewLite.this);
2017  0 return;
2018    }
2019    else
2020    {
2021  0 String msg = "Could not map any sequence in " + af2.getTitle()
2022    + " as "
2023  0 + (al1.isNucleotide() ? "protein product" : "cDNA")
2024    + " for " + af.getTitle();
2025  0 jalview.bin.Console.errPrintln(msg);
2026    }
2027    }
2028   
2029  0 af.addToDisplay(embedded);
2030    }
2031   
2032    /**
2033    * Read the alignment file (from URL, text 'paste', or archive by
2034    * classloader).
2035    *
2036    * @return
2037    */
 
2038  0 toggle protected AlignFrame readAlignment(String fileParam)
2039    {
2040  0 if (fileParam == null)
2041    {
2042  0 return null;
2043    }
2044  0 String resolvedFile = resolveFileProtocol(fileParam);
2045  0 AlignmentI al = null;
2046  0 try
2047    {
2048  0 FileFormatI format = new IdentifyFile().identify(resolvedFile,
2049    protocol);
2050  0 dbgMsg("File identified as '" + format + "'");
2051  0 al = new AppletFormatAdapter().readFile(resolvedFile, protocol,
2052    format);
2053  0 if ((al != null) && (al.getHeight() > 0))
2054    {
2055  0 dbgMsg("Successfully loaded file.");
2056  0 al.setDataset(null);
2057  0 AlignFrame newAlignFrame = new AlignFrame(al, applet,
2058    resolvedFile, embedded, false);
2059  0 newAlignFrame.setTitle(resolvedFile);
2060  0 if (initialAlignFrame == null)
2061    {
2062  0 initialAlignFrame = newAlignFrame;
2063    }
2064    // update the focus.
2065  0 currentAlignFrame = newAlignFrame;
2066   
2067  0 if (protocol == DataSourceType.PASTE)
2068    {
2069  0 newAlignFrame.setTitle(MessageManager
2070    .formatMessage("label.sequences_from", new Object[]
2071    { applet.getDocumentBase().toString() }));
2072    }
2073   
2074  0 newAlignFrame.statusBar.setText(MessageManager.formatMessage(
2075    "label.successfully_loaded_file", new Object[]
2076    { resolvedFile }));
2077   
2078  0 return newAlignFrame;
2079    }
2080    } catch (java.io.IOException ex)
2081    {
2082  0 dbgMsg("File load exception.");
2083  0 ex.printStackTrace();
2084  0 if (debug)
2085    {
2086  0 try
2087    {
2088  0 FileParse fp = new FileParse(resolvedFile, protocol);
2089  0 String ln = null;
2090  0 dbgMsg(">>>Dumping contents of '" + resolvedFile + "' " + "("
2091    + protocol + ")");
2092  0 while ((ln = fp.nextLine()) != null)
2093    {
2094  0 dbgMsg(ln);
2095    }
2096  0 dbgMsg(">>>Dump finished.");
2097    } catch (Exception e)
2098    {
2099  0 jalview.bin.Console.errPrintln(
2100    "Exception when trying to dump the content of the file parameter.");
2101  0 e.printStackTrace();
2102    }
2103    }
2104    }
2105  0 return null;
2106    }
2107   
2108    /**
2109    * Load PDBFiles if any specified by parameter(s). Returns true if loaded,
2110    * else false.
2111    *
2112    * @param alignFrame
2113    * @return
2114    */
 
2115  0 toggle protected boolean loadPdbFiles(AlignFrame alignFrame)
2116    {
2117  0 boolean result = false;
2118    /*
2119    * <param name="alignpdbfiles" value="false/true"/> Undocumented for 2.6 -
2120    * related to JAL-434
2121    */
2122   
2123  0 applet.setAlignPdbStructures(
2124    getDefaultParameter("alignpdbfiles", false));
2125    /*
2126    * <param name="PDBfile" value="1gaq.txt PDB|1GAQ|1GAQ|A PDB|1GAQ|1GAQ|B
2127    * PDB|1GAQ|1GAQ|C">
2128    *
2129    * <param name="PDBfile2" value="1gaq.txt A=SEQA B=SEQB C=SEQB">
2130    *
2131    * <param name="PDBfile3" value="1q0o Q45135_9MICO">
2132    */
2133   
2134  0 int pdbFileCount = 0;
2135    // Accumulate pdbs here if they are heading for the same view (if
2136    // alignPdbStructures is true)
2137  0 Vector pdbs = new Vector();
2138    // create a lazy matcher if we're asked to
2139  0 jalview.analysis.SequenceIdMatcher matcher = (applet
2140    .getDefaultParameter("relaxedidmatch", false))
2141    ? new jalview.analysis.SequenceIdMatcher(
2142    alignFrame.getAlignViewport().getAlignment()
2143    .getSequencesArray())
2144    : null;
2145   
2146  0 String param;
2147  0 do
2148    {
2149  0 if (pdbFileCount > 0)
2150    {
2151  0 param = applet.getParameter("PDBFILE" + pdbFileCount);
2152    }
2153    else
2154    {
2155  0 param = applet.getParameter("PDBFILE");
2156    }
2157   
2158  0 if (param != null)
2159    {
2160  0 PDBEntry pdb = new PDBEntry();
2161   
2162  0 String seqstring;
2163  0 SequenceI[] seqs = null;
2164  0 String[] chains = null;
2165   
2166  0 StringTokenizer st = new StringTokenizer(param, " ");
2167   
2168  0 if (st.countTokens() < 2)
2169    {
2170  0 String sequence = applet.getParameter("PDBSEQ");
2171  0 if (sequence != null)
2172    {
2173  0 seqs = new SequenceI[] { matcher == null
2174    ? (Sequence) alignFrame.getAlignViewport()
2175    .getAlignment().findName(sequence)
2176    : matcher.findIdMatch(sequence) };
2177    }
2178   
2179    }
2180    else
2181    {
2182  0 param = st.nextToken();
2183  0 List<SequenceI> tmp = new ArrayList<>();
2184  0 List<String> tmp2 = new ArrayList<>();
2185   
2186  0 while (st.hasMoreTokens())
2187    {
2188  0 seqstring = st.nextToken();
2189  0 StringTokenizer st2 = new StringTokenizer(seqstring, "=");
2190  0 if (st2.countTokens() > 1)
2191    {
2192    // This is the chain
2193  0 tmp2.add(st2.nextToken());
2194  0 seqstring = st2.nextToken();
2195    }
2196  0 tmp.add(matcher == null
2197    ? (Sequence) alignFrame.getAlignViewport()
2198    .getAlignment().findName(seqstring)
2199    : matcher.findIdMatch(seqstring));
2200    }
2201   
2202  0 seqs = tmp.toArray(new SequenceI[tmp.size()]);
2203  0 if (tmp2.size() == tmp.size())
2204    {
2205  0 chains = tmp2.toArray(new String[tmp2.size()]);
2206    }
2207    }
2208  0 param = resolveFileProtocol(param);
2209    // TODO check JAL-357 for files in a jar (CLASSLOADER)
2210  0 pdb.setFile(param);
2211   
2212  0 if (seqs != null)
2213    {
2214  0 for (int i = 0; i < seqs.length; i++)
2215    {
2216  0 if (seqs[i] != null)
2217    {
2218  0 ((Sequence) seqs[i]).addPDBId(pdb);
2219  0 StructureSelectionManager
2220    .getStructureSelectionManager(applet)
2221    .registerPDBEntry(pdb);
2222    }
2223    else
2224    {
2225  0 if (JalviewLite.debug)
2226    {
2227    // this may not really be a problem but we give a warning
2228    // anyway
2229  0 jalview.bin.Console.errPrintln(
2230    "Warning: Possible input parsing error: Null sequence for attachment of PDB (sequence "
2231    + i + ")");
2232    }
2233    }
2234    }
2235   
2236  0 if (!alignPdbStructures)
2237    {
2238  0 alignFrame.newStructureView(applet, pdb, seqs, chains,
2239    protocol);
2240    }
2241    else
2242    {
2243  0 pdbs.addElement(new Object[] { pdb, seqs, chains, protocol });
2244    }
2245    }
2246    }
2247   
2248  0 pdbFileCount++;
2249  0 } while (param != null || pdbFileCount < 10);
2250  0 if (pdbs.size() > 0)
2251    {
2252  0 SequenceI[][] seqs = new SequenceI[pdbs.size()][];
2253  0 PDBEntry[] pdb = new PDBEntry[pdbs.size()];
2254  0 String[][] chains = new String[pdbs.size()][];
2255  0 String[] protocols = new String[pdbs.size()];
2256  0 for (int pdbsi = 0, pdbsiSize = pdbs
2257  0 .size(); pdbsi < pdbsiSize; pdbsi++)
2258    {
2259  0 Object[] o = (Object[]) pdbs.elementAt(pdbsi);
2260  0 pdb[pdbsi] = (PDBEntry) o[0];
2261  0 seqs[pdbsi] = (SequenceI[]) o[1];
2262  0 chains[pdbsi] = (String[]) o[2];
2263  0 protocols[pdbsi] = (String) o[3];
2264    }
2265  0 alignFrame.alignedStructureView(applet, pdb, seqs, chains,
2266    protocols);
2267  0 result = true;
2268    }
2269  0 return result;
2270    }
2271   
2272    /**
2273    * Load in a Jnetfile if specified by parameter. Returns true if loaded,
2274    * else false.
2275    *
2276    * @param alignFrame
2277    * @return
2278    */
 
2279  0 toggle protected boolean loadJnetFile(AlignFrame alignFrame)
2280    {
2281  0 boolean result = false;
2282  0 String param = applet.getParameter("jnetfile");
2283  0 if (param == null)
2284    {
2285    // jnet became jpred around 2016
2286  0 param = applet.getParameter("jpredfile");
2287    }
2288  0 if (param != null)
2289    {
2290  0 try
2291    {
2292  0 param = resolveFileProtocol(param);
2293  0 JPredFile predictions = new JPredFile(param, protocol);
2294  0 JnetAnnotationMaker.add_annotation(predictions,
2295    alignFrame.viewport.getAlignment(), 0, false);
2296    // false == do not add sequence profile from concise output
2297   
2298  0 alignFrame.viewport.getAlignment().setupJPredAlignment();
2299   
2300  0 alignFrame.alignPanel.fontChanged();
2301  0 alignFrame.alignPanel.setScrollValues(0, 0);
2302  0 result = true;
2303    } catch (Exception ex)
2304    {
2305  0 ex.printStackTrace();
2306    }
2307    }
2308  0 return result;
2309    }
2310   
2311    /**
2312    * Load annotations if specified by parameter. Returns true if loaded, else
2313    * false.
2314    *
2315    * @param alignFrame
2316    * @return
2317    */
 
2318  0 toggle protected boolean loadAnnotations(AlignFrame alignFrame)
2319    {
2320  0 boolean result = false;
2321  0 String param = applet.getParameter("annotations");
2322  0 if (param != null)
2323    {
2324  0 param = resolveFileProtocol(param);
2325   
2326  0 if (new AnnotationFile().annotateAlignmentView(alignFrame.viewport,
2327    param, protocol))
2328    {
2329  0 alignFrame.alignPanel.fontChanged();
2330  0 alignFrame.alignPanel.setScrollValues(0, 0);
2331  0 result = true;
2332    }
2333    else
2334    {
2335  0 jalview.bin.Console.errPrintln(
2336    "Annotations were not added from annotation file '"
2337    + param + "'");
2338    }
2339    }
2340  0 return result;
2341    }
2342   
2343    /**
2344    * Load features file and view settings as specified by parameters. Returns
2345    * true if features were loaded, else false.
2346    *
2347    * @param alignFrame
2348    * @return
2349    */
 
2350  0 toggle protected boolean loadFeatures(AlignFrame alignFrame)
2351    {
2352  0 boolean result = false;
2353    // ///////////////////////////
2354    // modify display of features
2355    // we do this before any features have been loaded, ensuring any hidden
2356    // groups are hidden when features first displayed
2357    //
2358    // hide specific groups
2359    //
2360  0 String param = applet.getParameter("hidefeaturegroups");
2361  0 if (param != null)
2362    {
2363  0 alignFrame.setFeatureGroupState(separatorListToArray(param), false);
2364    // applet.setFeatureGroupStateOn(newAlignFrame, param, false);
2365    }
2366    // show specific groups
2367  0 param = applet.getParameter("showfeaturegroups");
2368  0 if (param != null)
2369    {
2370  0 alignFrame.setFeatureGroupState(separatorListToArray(param), true);
2371    // applet.setFeatureGroupStateOn(newAlignFrame, param, true);
2372    }
2373    // and now load features
2374  0 param = applet.getParameter("features");
2375  0 if (param != null)
2376    {
2377  0 param = resolveFileProtocol(param);
2378   
2379  0 result = alignFrame.parseFeaturesFile(param, protocol);
2380    }
2381   
2382  0 param = applet.getParameter("showFeatureSettings");
2383  0 if (param != null && param.equalsIgnoreCase(TRUE))
2384    {
2385  0 alignFrame.viewport.setShowSequenceFeatures(true);
2386  0 new FeatureSettings(alignFrame.alignPanel);
2387    }
2388  0 return result;
2389    }
2390   
2391    /**
2392    * Load a score file if specified by parameter. Returns true if file was
2393    * loaded, else false.
2394    *
2395    * @param alignFrame
2396    */
 
2397  0 toggle protected boolean loadScoreFile(AlignFrame alignFrame)
2398    {
2399  0 boolean result = false;
2400  0 String sScoreFile = applet.getParameter("scoreFile");
2401  0 if (sScoreFile != null && !"".equals(sScoreFile))
2402    {
2403  0 try
2404    {
2405  0 if (debug)
2406    {
2407  0 jalview.bin.Console.errPrintln(
2408    "Attempting to load T-COFFEE score file from the scoreFile parameter");
2409    }
2410  0 result = alignFrame.loadScoreFile(sScoreFile);
2411  0 if (!result)
2412    {
2413  0 jalview.bin.Console.errPrintln(
2414    "Failed to parse T-COFFEE parameter as a valid score file ('"
2415    + sScoreFile + "')");
2416    }
2417    } catch (Exception e)
2418    {
2419  0 System.err.printf("Cannot read score file: '%s'. Cause: %s \n",
2420    sScoreFile, e.getMessage());
2421    }
2422    }
2423  0 return result;
2424    }
2425   
2426    /**
2427    * Load a tree for the alignment if specified by parameter. Returns true if
2428    * a tree was loaded, else false.
2429    *
2430    * @param alignFrame
2431    * @return
2432    */
 
2433  0 toggle protected boolean loadTree(AlignFrame alignFrame)
2434    {
2435  0 boolean result = false;
2436  0 String treeFile = applet.getParameter("tree");
2437  0 if (treeFile == null)
2438    {
2439  0 treeFile = applet.getParameter("treeFile");
2440    }
2441   
2442  0 if (treeFile != null)
2443    {
2444  0 try
2445    {
2446  0 treeFile = resolveFileProtocol(treeFile);
2447  0 NewickFile fin = new NewickFile(treeFile, protocol);
2448  0 fin.parse();
2449   
2450  0 if (fin.getTree() != null)
2451    {
2452  0 alignFrame.loadTree(fin, treeFile);
2453  0 result = true;
2454  0 dbgMsg("Successfully imported tree.");
2455    }
2456    else
2457    {
2458  0 dbgMsg("Tree parameter did not resolve to a valid tree.");
2459    }
2460    } catch (Exception ex)
2461    {
2462  0 ex.printStackTrace();
2463    }
2464    }
2465  0 return result;
2466    }
2467   
2468    /**
2469    * Discovers whether the given file is in the Applet Archive
2470    *
2471    * @param f
2472    * String
2473    * @return boolean
2474    */
 
2475  0 toggle boolean inArchive(String f)
2476    {
2477    // This might throw a security exception in certain browsers
2478    // Netscape Communicator for instance.
2479  0 try
2480    {
2481  0 boolean rtn = (getClass().getResourceAsStream("/" + f) != null);
2482  0 if (debug)
2483    {
2484  0 jalview.bin.Console.errPrintln("Resource '" + f + "' was "
2485  0 + (rtn ? "" : "not ") + "located by classloader.");
2486    }
2487  0 return rtn;
2488    } catch (Exception ex)
2489    {
2490  0 jalview.bin.Console.outPrintln(
2491    "Exception checking resources: " + f + " " + ex);
2492  0 return false;
2493    }
2494    }
2495    }
2496   
2497    /**
2498    * @return the default alignFrame acted on by the public applet methods. May
2499    * return null with an error message on System.err indicating the
2500    * fact.
2501    */
 
2502  0 toggle public AlignFrame getDefaultTargetFrame()
2503    {
2504  0 if (currentAlignFrame != null)
2505    {
2506  0 return currentAlignFrame;
2507    }
2508  0 if (initialAlignFrame != null)
2509    {
2510  0 return initialAlignFrame;
2511    }
2512  0 jalview.bin.Console.errPrintln(
2513    "Implementation error: Jalview Applet API cannot work out which AlignFrame to use.");
2514  0 return null;
2515    }
2516   
2517    /**
2518    * separator used for separatorList
2519    */
2520    protected String separator = "" + ((char) 0x00AC); // the default used to be
2521    // '|' but many sequence
2522    // IDS include pipes.
2523   
2524    /**
2525    * set to enable the URL based javascript execution mechanism
2526    */
2527    public boolean jsfallbackEnabled = false;
2528   
2529    /**
2530    * parse the string into a list
2531    *
2532    * @param list
2533    * @return elements separated by separator
2534    */
 
2535  0 toggle public String[] separatorListToArray(String list)
2536    {
2537  0 return separatorListToArray(list, separator);
2538    }
2539   
2540    /**
2541    * parse the string into a list
2542    *
2543    * @param list
2544    * @param separator
2545    * @return elements separated by separator
2546    */
 
2547  7 toggle public static String[] separatorListToArray(String list, String separator)
2548    {
2549    // TODO use StringUtils version (slightly different...)
2550  7 int seplen = separator.length();
2551  7 if (list == null || list.equals("") || list.equals(separator))
2552    {
2553  4 return null;
2554    }
2555  3 java.util.Vector jv = new Vector();
2556  3 int cp = 0, pos;
2557  ? while ((pos = list.indexOf(separator, cp)) > cp)
2558    {
2559  5 jv.addElement(list.substring(cp, pos));
2560  5 cp = pos + seplen;
2561    }
2562  3 if (cp < list.length())
2563    {
2564  0 String c = list.substring(cp);
2565  0 if (!c.equals(separator))
2566    {
2567  0 jv.addElement(c);
2568    }
2569    }
2570  3 if (jv.size() > 0)
2571    {
2572  3 String[] v = new String[jv.size()];
2573  8 for (int i = 0; i < v.length; i++)
2574    {
2575  5 v[i] = (String) jv.elementAt(i);
2576    }
2577  3 jv.removeAllElements();
2578  3 if (debug)
2579    {
2580  0 jalview.bin.Console.errPrintln("Array from '" + separator
2581    + "' separated List:\n" + v.length);
2582  0 for (int i = 0; i < v.length; i++)
2583    {
2584  0 jalview.bin.Console.errPrintln("item " + i + " '" + v[i] + "'");
2585    }
2586    }
2587  3 return v;
2588    }
2589  0 if (debug)
2590    {
2591  0 jalview.bin.Console.errPrintln(
2592    "Empty Array from '" + separator + "' separated List");
2593    }
2594  0 return null;
2595    }
2596   
2597    /**
2598    * concatenate the list with separator
2599    *
2600    * @param list
2601    * @return concatenated string
2602    */
 
2603  0 toggle public String arrayToSeparatorList(String[] list)
2604    {
2605  0 return arrayToSeparatorList(list, separator);
2606    }
2607   
2608    /**
2609    * concatenate the list with separator
2610    *
2611    * @param list
2612    * @param separator
2613    * @return concatenated string
2614    */
 
2615  0 toggle public static String arrayToSeparatorList(String[] list, String separator)
2616    {
2617    // TODO use StringUtils version
2618  0 StringBuffer v = new StringBuffer();
2619  0 if (list != null && list.length > 0)
2620    {
2621  0 for (int i = 0, iSize = list.length; i < iSize; i++)
2622    {
2623  0 if (list[i] != null)
2624    {
2625  0 if (i > 0)
2626    {
2627  0 v.append(separator);
2628    }
2629  0 v.append(list[i]);
2630    }
2631    }
2632  0 if (debug)
2633    {
2634  0 System.err
2635    .println("Returning '" + separator + "' separated List:\n");
2636  0 jalview.bin.Console.errPrintln(v);
2637    }
2638  0 return v.toString();
2639    }
2640  0 if (debug)
2641    {
2642  0 jalview.bin.Console.errPrintln(
2643    "Returning empty '" + separator + "' separated List\n");
2644    }
2645  0 return "" + separator;
2646    }
2647   
2648    /*
2649    * (non-Javadoc)
2650    *
2651    * @see jalview.bin.JalviewLiteJsApi#getFeatureGroups()
2652    */
 
2653  0 toggle @Override
2654    public String getFeatureGroups()
2655    {
2656  0 String lst = arrayToSeparatorList(
2657    getDefaultTargetFrame().getFeatureGroups());
2658  0 return lst;
2659    }
2660   
2661    /*
2662    * (non-Javadoc)
2663    *
2664    * @see
2665    * jalview.bin.JalviewLiteJsApi#getFeatureGroupsOn(jalview.appletgui.AlignFrame
2666    * )
2667    */
 
2668  0 toggle @Override
2669    public String getFeatureGroupsOn(AlignFrame alf)
2670    {
2671  0 String lst = arrayToSeparatorList(alf.getFeatureGroups());
2672  0 return lst;
2673    }
2674   
2675    /*
2676    * (non-Javadoc)
2677    *
2678    * @see jalview.bin.JalviewLiteJsApi#getFeatureGroupsOfState(boolean)
2679    */
 
2680  0 toggle @Override
2681    public String getFeatureGroupsOfState(boolean visible)
2682    {
2683  0 return arrayToSeparatorList(
2684    getDefaultTargetFrame().getFeatureGroupsOfState(visible));
2685    }
2686   
2687    /*
2688    * (non-Javadoc)
2689    *
2690    * @see
2691    * jalview.bin.JalviewLiteJsApi#getFeatureGroupsOfStateOn(jalview.appletgui
2692    * .AlignFrame, boolean)
2693    */
 
2694  0 toggle @Override
2695    public String getFeatureGroupsOfStateOn(AlignFrame alf, boolean visible)
2696    {
2697  0 return arrayToSeparatorList(alf.getFeatureGroupsOfState(visible));
2698    }
2699   
2700    /*
2701    * (non-Javadoc)
2702    *
2703    * @see jalview.bin.JalviewLiteJsApi#setFeatureGroupStateOn(jalview.appletgui.
2704    * AlignFrame, java.lang.String, boolean)
2705    */
 
2706  0 toggle @Override
2707    public void setFeatureGroupStateOn(final AlignFrame alf,
2708    final String groups, boolean state)
2709    {
2710  0 final boolean st = state;// !(state==null || state.equals("") ||
2711    // state.toLowerCase(Locale.ROOT).equals("false"));
2712  0 java.awt.EventQueue.invokeLater(new Runnable()
2713    {
 
2714  0 toggle @Override
2715    public void run()
2716    {
2717  0 alf.setFeatureGroupState(separatorListToArray(groups), st);
2718    }
2719    });
2720    }
2721   
2722    /*
2723    * (non-Javadoc)
2724    *
2725    * @see jalview.bin.JalviewLiteJsApi#setFeatureGroupState(java.lang.String,
2726    * boolean)
2727    */
 
2728  0 toggle @Override
2729    public void setFeatureGroupState(String groups, boolean state)
2730    {
2731  0 setFeatureGroupStateOn(getDefaultTargetFrame(), groups, state);
2732    }
2733   
2734    /*
2735    * (non-Javadoc)
2736    *
2737    * @see jalview.bin.JalviewLiteJsApi#getSeparator()
2738    */
 
2739  0 toggle @Override
2740    public String getSeparator()
2741    {
2742  0 return separator;
2743    }
2744   
2745    /*
2746    * (non-Javadoc)
2747    *
2748    * @see jalview.bin.JalviewLiteJsApi#setSeparator(java.lang.String)
2749    */
 
2750  0 toggle @Override
2751    public void setSeparator(String separator)
2752    {
2753  0 if (separator == null || separator.length() < 1)
2754    {
2755    // reset to default
2756  0 separator = "" + ((char) 0x00AC);
2757    }
2758  0 this.separator = separator;
2759  0 if (debug)
2760    {
2761  0 jalview.bin.Console
2762    .errPrintln("Default Separator now: '" + separator + "'");
2763    }
2764    }
2765   
2766    /**
2767    * get boolean value of applet parameter 'name' and return default if
2768    * parameter is not set
2769    *
2770    * @param name
2771    * name of paremeter
2772    * @param def
2773    * the value to return otherwise
2774    * @return true or false
2775    */
 
2776  0 toggle public boolean getDefaultParameter(String name, boolean def)
2777    {
2778  0 String stn;
2779  0 if ((stn = getParameter(name)) == null)
2780    {
2781  0 return def;
2782    }
2783  0 if (TRUE.equalsIgnoreCase(stn))
2784    {
2785  0 return true;
2786    }
2787  0 return false;
2788    }
2789   
2790    /*
2791    * (non-Javadoc)
2792    *
2793    * @see jalview.bin.JalviewLiteJsApi#addPdbFile(jalview.appletgui.AlignFrame,
2794    * java.lang.String, java.lang.String, java.lang.String)
2795    */
 
2796  0 toggle @Override
2797    public boolean addPdbFile(AlignFrame alFrame, String sequenceId,
2798    String pdbEntryString, String pdbFile)
2799    {
2800  0 return alFrame.addPdbFile(sequenceId, pdbEntryString, pdbFile);
2801    }
2802   
 
2803  0 toggle protected void setAlignPdbStructures(boolean alignPdbStructures)
2804    {
2805  0 this.alignPdbStructures = alignPdbStructures;
2806    }
2807   
 
2808  0 toggle public boolean isAlignPdbStructures()
2809    {
2810  0 return alignPdbStructures;
2811    }
2812   
 
2813  0 toggle @Override
2814    public void start()
2815    {
2816    // callInitCallback();
2817    }
2818   
2819    private Hashtable<String, long[]> jshashes = new Hashtable<>();
2820   
2821    private Hashtable<String, Hashtable<String, String[]>> jsmessages = new Hashtable<>();
2822   
 
2823  0 toggle public void setJsMessageSet(String messageclass, String viewId,
2824    String[] colcommands)
2825    {
2826  0 Hashtable<String, String[]> msgset = jsmessages.get(messageclass);
2827  0 if (msgset == null)
2828    {
2829  0 msgset = new Hashtable<>();
2830  0 jsmessages.put(messageclass, msgset);
2831    }
2832  0 msgset.put(viewId, colcommands);
2833  0 long[] l = new long[colcommands.length];
2834  0 for (int i = 0; i < colcommands.length; i++)
2835    {
2836  0 l[i] = colcommands[i].hashCode();
2837    }
2838  0 jshashes.put(messageclass + "|" + viewId, l);
2839    }
2840   
2841    /*
2842    * (non-Javadoc)
2843    *
2844    * @see jalview.bin.JalviewLiteJsApi#getJsMessage(java.lang.String,
2845    * java.lang.String)
2846    */
 
2847  0 toggle @Override
2848    public String getJsMessage(String messageclass, String viewId)
2849    {
2850  0 Hashtable<String, String[]> msgset = jsmessages.get(messageclass);
2851  0 if (msgset != null)
2852    {
2853  0 String[] msgs = msgset.get(viewId);
2854  0 if (msgs != null)
2855    {
2856  0 for (int i = 0; i < msgs.length; i++)
2857    {
2858  0 if (msgs[i] != null)
2859    {
2860  0 String m = msgs[i];
2861  0 msgs[i] = null;
2862  0 return m;
2863    }
2864    }
2865    }
2866    }
2867  0 return "";
2868    }
2869   
 
2870  0 toggle public boolean isJsMessageSetChanged(String string, String string2,
2871    String[] colcommands)
2872    {
2873  0 long[] l = jshashes.get(string + "|" + string2);
2874  0 if (l == null && colcommands != null)
2875    {
2876  0 return true;
2877    }
2878  0 for (int i = 0; i < colcommands.length; i++)
2879    {
2880  0 if (l[i] != colcommands[i].hashCode())
2881    {
2882  0 return true;
2883    }
2884    }
2885  0 return false;
2886    }
2887   
2888    private Vector jsExecQueue = new Vector();
2889   
 
2890  0 toggle public Vector getJsExecQueue()
2891    {
2892  0 return jsExecQueue;
2893    }
2894   
 
2895  0 toggle public void setExecutor(JSFunctionExec jsFunctionExec2)
2896    {
2897  0 jsFunctionExec = jsFunctionExec2;
2898    }
2899   
2900    /**
2901    * return the given colour value parameter or the given default if parameter
2902    * not given
2903    *
2904    * @param colparam
2905    * @param defcolour
2906    * @return
2907    */
 
2908  0 toggle public Color getDefaultColourParameter(String colparam, Color defcolour)
2909    {
2910  0 String colprop = getParameter(colparam);
2911  0 if (colprop == null || colprop.trim().length() == 0)
2912    {
2913  0 return defcolour;
2914    }
2915  0 Color col = ColorUtils.parseColourString(colprop);
2916  0 if (col == null)
2917    {
2918  0 jalview.bin.Console.errPrintln("Couldn't parse '" + colprop
2919    + "' as a colour for " + colparam);
2920    }
2921  0 return (col == null) ? defcolour : col;
2922    }
2923   
 
2924  0 toggle public void openJalviewHelpUrl()
2925    {
2926  0 String helpUrl = getParameter("jalviewhelpurl");
2927  0 if (helpUrl == null || helpUrl.trim().length() < 5)
2928    {
2929  0 helpUrl = "http://www.jalview.org/help.html";
2930    }
2931  0 showURL(helpUrl, "HELP");
2932    }
2933   
2934    /**
2935    * form a complete URL given a path to a resource and a reference location on
2936    * the same server
2937    *
2938    * @param targetPath
2939    * - an absolute path on the same server as localref or a document
2940    * located relative to localref
2941    * @param localref
2942    * - a URL on the same server as url
2943    * @return a complete URL for the resource located by url
2944    */
 
2945  0 toggle private String resolveUrlForLocalOrAbsolute(String targetPath,
2946    URL localref)
2947    {
2948  0 String resolvedPath = "";
2949  0 if (targetPath.startsWith("/"))
2950    {
2951  0 String codebase = localref.toString();
2952  0 String localfile = localref.getFile();
2953  0 resolvedPath = codebase.substring(0,
2954    codebase.length() - localfile.length()) + targetPath;
2955  0 return resolvedPath;
2956    }
2957   
2958    /*
2959    * get URL path and strip off any trailing file e.g.
2960    * www.jalview.org/examples/index.html#applets?a=b is trimmed to
2961    * www.jalview.org/examples/
2962    */
2963  0 String urlPath = localref.toString();
2964  0 String directoryPath = urlPath;
2965  0 int lastSeparator = directoryPath.lastIndexOf("/");
2966  0 if (lastSeparator > 0)
2967    {
2968  0 directoryPath = directoryPath.substring(0, lastSeparator + 1);
2969    }
2970   
2971  0 if (targetPath.startsWith("/"))
2972    {
2973    /*
2974    * construct absolute URL to a file on the server - this is not allowed?
2975    */
2976    // String localfile = localref.getFile();
2977    // resolvedPath = urlPath.substring(0,
2978    // urlPath.length() - localfile.length())
2979    // + targetPath;
2980  0 resolvedPath = directoryPath + targetPath.substring(1);
2981    }
2982    else
2983    {
2984  0 resolvedPath = directoryPath + targetPath;
2985    }
2986  0 if (debug)
2987    {
2988  0 jalview.bin.Console.errPrintln(
2989    "resolveUrlForLocalOrAbsolute returning " + resolvedPath);
2990    }
2991  0 return resolvedPath;
2992    }
2993   
2994    /**
2995    * open a URL in the browser - resolving it according to relative refs and
2996    * coping with javascript: protocol if necessary.
2997    *
2998    * @param url
2999    * @param target
3000    */
 
3001  0 toggle public void showURL(String url, String target)
3002    {
3003  0 try
3004    {
3005  0 if (url.indexOf(":") == -1)
3006    {
3007    // TODO: verify (Bas Vroling bug) prepend codebase or server URL to
3008    // form valid URL
3009    // Should really use docbase, not codebase.
3010  0 URL prepend;
3011  0 url = resolveUrlForLocalOrAbsolute(url,
3012  0 prepend = getDefaultParameter("resolvetocodebase", false)
3013    ? getCodeBase()
3014    : getDocumentBase());
3015  0 if (debug)
3016    {
3017  0 jalview.bin.Console.errPrintln("Show url (prepended " + prepend
3018    + " - toggle resolvetocodebase if code/docbase resolution is wrong): "
3019    + url);
3020    }
3021    }
3022    else
3023    {
3024  0 if (debug)
3025    {
3026  0 jalview.bin.Console.errPrintln("Show url: " + url);
3027    }
3028    }
3029  0 if (url.indexOf("javascript:") == 0)
3030    {
3031    // no target for the javascript context
3032  0 getAppletContext().showDocument(new java.net.URL(url));
3033    }
3034    else
3035    {
3036  0 getAppletContext().showDocument(new java.net.URL(url), target);
3037    }
3038    } catch (Exception ex)
3039    {
3040  0 ex.printStackTrace();
3041    }
3042    }
3043   
3044    /**
3045    * bind structures in a viewer to any matching sequences in an alignFrame (use
3046    * sequenceIds to limit scope of search to specific sequences)
3047    *
3048    * @param alFrame
3049    * @param viewer
3050    * @param sequenceIds
3051    * @return TODO: consider making an exception structure for indicating when
3052    * binding fails public SequenceStructureBinding
3053    * addStructureViewInstance( AlignFrame alFrame, Object viewer, String
3054    * sequenceIds) {
3055    *
3056    * if (sequenceIds != null && sequenceIds.length() > 0) { return
3057    * alFrame.addStructureViewInstance(viewer,
3058    * separatorListToArray(sequenceIds)); } else { return
3059    * alFrame.addStructureViewInstance(viewer, null); } // return null; }
3060    */
3061    }