Clover icon

jalviewX

  1. Project Clover database Wed Oct 31 2018 15:13:58 GMT
  2. Package jalview.bin

File JalviewLite.java

 

Coverage histogram

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

Code metrics

422
859
113
3
3,043
2,145
383
0.45
7.6
37.67
3.39

Classes

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