Clover icon

Coverage Report

  1. Project Clover database Wed Nov 13 2024 16:21:17 GMT
  2. Package jalview.bin

File JalviewLite.java

 

Coverage histogram

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

Code metrics

422
859
113
3
3,059
2,162
383
0.45
7.6
37.67
3.39

Classes

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