JAL-1665 refactored Sequence.getSequenceFeatures
[jalview.git] / src / jalview / gui / SequenceFetcher.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
3  * Copyright (C) 2014 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.gui;
22
23 import jalview.datamodel.Alignment;
24 import jalview.datamodel.AlignmentI;
25 import jalview.datamodel.DBRefEntry;
26 import jalview.datamodel.DBRefSource;
27 import jalview.datamodel.SequenceFeature;
28 import jalview.datamodel.SequenceI;
29 import jalview.io.FormatAdapter;
30 import jalview.io.IdentifyFile;
31 import jalview.util.DBRefUtils;
32 import jalview.util.MessageManager;
33 import jalview.ws.dbsources.das.api.DasSourceRegistryI;
34 import jalview.ws.seqfetcher.DbSourceProxy;
35
36 import java.awt.BorderLayout;
37 import java.awt.Font;
38 import java.awt.event.ActionEvent;
39 import java.awt.event.ActionListener;
40 import java.awt.event.KeyAdapter;
41 import java.awt.event.KeyEvent;
42 import java.util.ArrayList;
43 import java.util.Arrays;
44 import java.util.Iterator;
45 import java.util.List;
46
47 import javax.swing.JButton;
48 import javax.swing.JCheckBox;
49 import javax.swing.JInternalFrame;
50 import javax.swing.JLabel;
51 import javax.swing.JOptionPane;
52 import javax.swing.JPanel;
53 import javax.swing.JScrollPane;
54 import javax.swing.JTextArea;
55 import javax.swing.SwingConstants;
56 import javax.swing.tree.DefaultMutableTreeNode;
57
58 import com.stevesoft.pat.Regex;
59
60 public class SequenceFetcher extends JPanel implements Runnable
61 {
62   // ASequenceFetcher sfetch;
63   JInternalFrame frame;
64
65   IProgressIndicator guiWindow;
66
67   AlignFrame alignFrame;
68
69   StringBuffer result;
70
71   final String noDbSelected = "-- Select Database --";
72
73   private static jalview.ws.SequenceFetcher sfetch = null;
74
75   private static long lastDasSourceRegistry = -3;
76
77   private static DasSourceRegistryI dasRegistry = null;
78
79   private static boolean _initingFetcher = false;
80
81   private static Thread initingThread = null;
82
83   /**
84    * Blocking method that initialises and returns the shared instance of the
85    * SequenceFetcher client
86    * 
87    * @param guiWindow
88    *          - where the initialisation delay message should be shown
89    * @return the singleton instance of the sequence fetcher client
90    */
91   public static jalview.ws.SequenceFetcher getSequenceFetcherSingleton(
92           final IProgressIndicator guiWindow)
93   {
94     if (_initingFetcher && initingThread != null && initingThread.isAlive())
95     {
96       if (guiWindow != null)
97       {
98         guiWindow.setProgressBar(
99                 MessageManager.getString("status.waiting_sequence_database_fetchers_init"),
100                 Thread.currentThread().hashCode());
101       }
102       // initting happening on another thread - so wait around to see if it
103       // finishes.
104       while (_initingFetcher && initingThread != null
105               && initingThread.isAlive())
106       {
107         try
108         {
109           Thread.sleep(10);
110         } catch (Exception e)
111         {
112         }
113         ;
114       }
115       if (guiWindow != null)
116       {
117         guiWindow.setProgressBar(
118                         MessageManager.getString("status.waiting_sequence_database_fetchers_init"),
119                 Thread.currentThread().hashCode());
120       }
121     }
122     if (sfetch == null
123             || dasRegistry != jalview.bin.Cache.getDasSourceRegistry()
124             || lastDasSourceRegistry != (jalview.bin.Cache
125                     .getDasSourceRegistry().getDasRegistryURL() + jalview.bin.Cache
126                     .getDasSourceRegistry().getLocalSourceString())
127                     .hashCode())
128     {
129       _initingFetcher = true;
130       initingThread = Thread.currentThread();
131       /**
132        * give a visual indication that sequence fetcher construction is occuring
133        */
134       if (guiWindow != null)
135       {
136         guiWindow.setProgressBar(MessageManager.getString("status.init_sequence_database_fetchers"),
137                 Thread.currentThread().hashCode());
138       }
139       dasRegistry = jalview.bin.Cache.getDasSourceRegistry();
140       dasRegistry.refreshSources();
141
142       jalview.ws.SequenceFetcher sf = new jalview.ws.SequenceFetcher();
143       if (guiWindow != null)
144       {
145         guiWindow.setProgressBar(MessageManager.getString("status.init_sequence_database_fetchers"),
146                 Thread.currentThread().hashCode());
147       }
148       lastDasSourceRegistry = (dasRegistry.getDasRegistryURL() + dasRegistry
149               .getLocalSourceString()).hashCode();
150       sfetch = sf;
151       _initingFetcher = false;
152       initingThread = null;
153     }
154     return sfetch;
155   }
156
157   public SequenceFetcher(IProgressIndicator guiIndic)
158   {
159     final IProgressIndicator guiWindow = guiIndic;
160     final SequenceFetcher us = this;
161     // launch initialiser thread
162     Thread sf = new Thread(new Runnable()
163     {
164
165       @Override
166       public void run()
167       {
168         if (getSequenceFetcherSingleton(guiWindow) != null)
169         {
170           us.initGui(guiWindow);
171         }
172         else
173         {
174           javax.swing.SwingUtilities.invokeLater(new Runnable()
175           {
176             @Override
177             public void run()
178             {
179               JOptionPane
180                       .showInternalMessageDialog(
181                               Desktop.desktop,
182                               MessageManager.getString("warn.couldnt_create_sequence_fetcher_client"),
183                               MessageManager.getString("label.couldnt_create_sequence_fetcher"),
184                               JOptionPane.ERROR_MESSAGE);
185             }
186           });
187
188           // raise warning dialog
189         }
190       }
191     });
192     sf.start();
193   }
194
195   private class DatabaseAuthority extends DefaultMutableTreeNode
196   {
197
198   };
199
200   private class DatabaseSource extends DefaultMutableTreeNode
201   {
202
203   };
204
205   /**
206    * called by thread spawned by constructor
207    * 
208    * @param guiWindow
209    */
210   private void initGui(IProgressIndicator guiWindow)
211   {
212     this.guiWindow = guiWindow;
213     if (guiWindow instanceof AlignFrame)
214     {
215       alignFrame = (AlignFrame) guiWindow;
216     }
217     database = new JDatabaseTree(sfetch);
218     try
219     {
220       jbInit();
221     } catch (Exception ex)
222     {
223       ex.printStackTrace();
224     }
225
226     frame = new JInternalFrame();
227     frame.setContentPane(this);
228     if (new jalview.util.Platform().isAMac())
229     {
230       Desktop.addInternalFrame(frame, getFrameTitle(), 400, 240);
231     }
232     else
233     {
234       Desktop.addInternalFrame(frame, getFrameTitle(), 400, 180);
235     }
236   }
237
238   private String getFrameTitle()
239   {
240     return ((alignFrame == null) ? MessageManager.getString("label.new_sequence_fetcher") : MessageManager.getString("label.additional_sequence_fetcher"));
241   }
242
243   private void jbInit() throws Exception
244   {
245     this.setLayout(borderLayout2);
246
247     database.setFont(JvSwingUtils.getLabelFont());
248     dbeg.setFont(new java.awt.Font("Verdana", Font.BOLD, 11));
249     jLabel1.setFont(new java.awt.Font("Verdana", Font.ITALIC, 11));
250     jLabel1.setHorizontalAlignment(SwingConstants.CENTER);
251     jLabel1.setText(MessageManager
252             .getString("label.separate_multiple_accession_ids"));
253
254     replacePunctuation.setHorizontalAlignment(SwingConstants.CENTER);
255     replacePunctuation
256             .setFont(new java.awt.Font("Verdana", Font.ITALIC, 11));
257     replacePunctuation.setText(MessageManager
258             .getString("label.replace_commas_semicolons"));
259     ok.setText(MessageManager.getString("action.ok"));
260     ok.addActionListener(new ActionListener()
261     {
262       @Override
263       public void actionPerformed(ActionEvent e)
264       {
265         ok_actionPerformed();
266       }
267     });
268     clear.setText(MessageManager.getString("action.clear"));
269     clear.addActionListener(new ActionListener()
270     {
271       @Override
272       public void actionPerformed(ActionEvent e)
273       {
274         clear_actionPerformed();
275       }
276     });
277
278     example.setText(MessageManager.getString("label.example"));
279     example.addActionListener(new ActionListener()
280     {
281       @Override
282       public void actionPerformed(ActionEvent e)
283       {
284         example_actionPerformed();
285       }
286     });
287     close.setText(MessageManager.getString("action.close"));
288     close.addActionListener(new ActionListener()
289     {
290       @Override
291       public void actionPerformed(ActionEvent e)
292       {
293         close_actionPerformed(e);
294       }
295     });
296     textArea.setFont(JvSwingUtils.getLabelFont());
297     textArea.setLineWrap(true);
298     textArea.addKeyListener(new KeyAdapter()
299     {
300       @Override
301       public void keyPressed(KeyEvent e)
302       {
303         if (e.getKeyCode() == KeyEvent.VK_ENTER)
304         {
305           ok_actionPerformed();
306         }
307       }
308     });
309     jPanel3.setLayout(borderLayout1);
310     borderLayout1.setVgap(5);
311     jPanel1.add(ok);
312     jPanel1.add(example);
313     jPanel1.add(clear);
314     jPanel1.add(close);
315     jPanel3.add(jPanel2, java.awt.BorderLayout.CENTER);
316     jPanel2.setLayout(borderLayout3);
317     databaseButt = database.getDatabaseSelectorButton();
318     databaseButt.setFont(JvSwingUtils.getLabelFont());
319     database.addActionListener(new ActionListener()
320     {
321
322       @Override
323       public void actionPerformed(ActionEvent e)
324       {
325         try
326         {
327           databaseButt.setText(database.getSelectedItem()
328                   + (database.getSelectedSources().size() > 1 ? " (and "
329                           + database.getSelectedSources().size()
330                           + " others)" : ""));
331           String eq = database.getExampleQueries();
332           dbeg.setText(MessageManager.formatMessage(
333                   "label.example_query_param", new String[]
334                   { eq }));
335           boolean enablePunct = !(eq != null && eq.indexOf(",") > -1);
336           for (DbSourceProxy dbs : database.getSelectedSources())
337           {
338             if (dbs instanceof jalview.ws.dbsources.das.datamodel.DasSequenceSource)
339             {
340               enablePunct = false;
341               break;
342             }
343           }
344           replacePunctuation.setEnabled(enablePunct);
345
346         } catch (Exception ex)
347         {
348           dbeg.setText("");
349           replacePunctuation.setEnabled(true);
350         }
351         jPanel2.repaint();
352       }
353     });
354     dbeg.setText("");
355     jPanel2.add(databaseButt, java.awt.BorderLayout.NORTH);
356     jPanel2.add(dbeg, java.awt.BorderLayout.CENTER);
357     JPanel jPanel2a = new JPanel(new BorderLayout());
358     jPanel2a.add(jLabel1, java.awt.BorderLayout.NORTH);
359     jPanel2a.add(replacePunctuation, java.awt.BorderLayout.SOUTH);
360     jPanel2.add(jPanel2a, java.awt.BorderLayout.SOUTH);
361     // jPanel2.setPreferredSize(new Dimension())
362     jPanel3.add(jScrollPane1, java.awt.BorderLayout.CENTER);
363     this.add(jPanel1, java.awt.BorderLayout.SOUTH);
364     this.add(jPanel3, java.awt.BorderLayout.CENTER);
365     this.add(jPanel2, java.awt.BorderLayout.NORTH);
366     jScrollPane1.getViewport().add(textArea);
367
368   }
369
370   protected void example_actionPerformed()
371   {
372     DbSourceProxy db = null;
373     try
374     {
375       textArea.setText(database.getExampleQueries());
376     } catch (Exception ex)
377     {
378     }
379     jPanel3.repaint();
380   }
381
382   protected void clear_actionPerformed()
383   {
384     textArea.setText("");
385     jPanel3.repaint();
386   }
387
388   JLabel dbeg = new JLabel();
389
390   JDatabaseTree database;
391
392   JButton databaseButt;
393
394   JLabel jLabel1 = new JLabel();
395
396   JCheckBox replacePunctuation = new JCheckBox();
397
398   JButton ok = new JButton();
399
400   JButton clear = new JButton();
401
402   JButton example = new JButton();
403
404   JButton close = new JButton();
405
406   JPanel jPanel1 = new JPanel();
407
408   JTextArea textArea = new JTextArea();
409
410   JScrollPane jScrollPane1 = new JScrollPane();
411
412   JPanel jPanel2 = new JPanel();
413
414   JPanel jPanel3 = new JPanel();
415
416   JPanel jPanel4 = new JPanel();
417
418   BorderLayout borderLayout1 = new BorderLayout();
419
420   BorderLayout borderLayout2 = new BorderLayout();
421
422   BorderLayout borderLayout3 = new BorderLayout();
423
424   public void close_actionPerformed(ActionEvent e)
425   {
426     try
427     {
428       frame.setClosed(true);
429     } catch (Exception ex)
430     {
431     }
432   }
433
434   public void ok_actionPerformed()
435   {
436     databaseButt.setEnabled(false);
437     example.setEnabled(false);
438     textArea.setEnabled(false);
439     ok.setEnabled(false);
440     close.setEnabled(false);
441
442     Thread worker = new Thread(this);
443     worker.start();
444   }
445
446   private void resetDialog()
447   {
448     databaseButt.setEnabled(true);
449     example.setEnabled(true);
450     textArea.setEnabled(true);
451     ok.setEnabled(true);
452     close.setEnabled(true);
453   }
454
455   @Override
456   public void run()
457   {
458     String error = "";
459     if (!database.hasSelection())
460     {
461       error += "Please select the source database\n";
462     }
463     // TODO: make this transformation more configurable
464     com.stevesoft.pat.Regex empty;
465     if (replacePunctuation.isEnabled() && replacePunctuation.isSelected())
466     {
467       empty = new com.stevesoft.pat.Regex(
468       // replace commas and spaces with a semicolon
469               "(\\s|[,; ])+", ";");
470     }
471     else
472     {
473       // just turn spaces and semicolons into single semicolons
474       empty = new com.stevesoft.pat.Regex("(\\s|[; ])+", ";");
475     }
476     textArea.setText(empty.replaceAll(textArea.getText()));
477     // see if there's anthing to search with
478     if (!new com.stevesoft.pat.Regex("[A-Za-z0-9_.]").search(textArea
479             .getText()))
480     {
481       error += "Please enter a (semi-colon separated list of) database id(s)";
482     }
483     if (error.length() > 0)
484     {
485       showErrorMessage(error);
486       resetDialog();
487       return;
488     }
489     // indicate if successive sources should be merged into one alignment.
490     boolean addToLast = false;
491     ArrayList<String> aresultq = new ArrayList<String>(), presultTitle = new ArrayList<String>();
492     ArrayList<AlignmentI> presult = new ArrayList<AlignmentI>(), aresult = new ArrayList<AlignmentI>();
493     Iterator<DbSourceProxy> proxies = database.getSelectedSources()
494             .iterator();
495     String[] qries;
496     List<String> nextfetch = Arrays.asList(qries = textArea.getText()
497             .split(";"));
498     Iterator<String> en = Arrays.asList(new String[0]).iterator();
499     int nqueries = qries.length;
500     while (proxies.hasNext() && (en.hasNext() || nextfetch.size() > 0))
501     {
502       if (!en.hasNext() && nextfetch.size() > 0)
503       {
504         en = nextfetch.iterator();
505         nqueries = nextfetch.size();
506         // save the remaining queries in the original array
507         qries = nextfetch.toArray(new String[nqueries]);
508         nextfetch = new ArrayList<String>();
509       }
510
511       DbSourceProxy proxy = proxies.next();
512       boolean isAliSource = false;
513       try
514       {
515         // update status
516         guiWindow.setProgressBar(MessageManager.formatMessage("status.fetching_sequence_queries_from", new String[]{Integer.valueOf(nqueries).toString(),proxy.getDbName()}), Thread
517                 .currentThread().hashCode());
518         isAliSource = proxy.isA(DBRefSource.ALIGNMENTDB);
519         if (proxy.getAccessionSeparator() == null)
520         {
521           while (en.hasNext())
522           {
523             String item = en.next();
524             try
525             {
526               if (aresult != null)
527               {
528                 try
529                 {
530                   // give the server a chance to breathe
531                   Thread.sleep(5);
532                 } catch (Exception e)
533                 {
534                   //
535                 }
536
537               }
538
539               AlignmentI indres = null;
540               try
541               {
542                 indres = proxy.getSequenceRecords(item);
543               } catch (OutOfMemoryError oome)
544               {
545                 new OOMWarning("fetching " + item + " from "
546                         + proxy.getDbName(), oome, this);
547               }
548               if (indres != null)
549               {
550                 aresultq.add(item);
551                 aresult.add(indres);
552               }
553               else
554               {
555                 nextfetch.add(item);
556               }
557             } catch (Exception e)
558             {
559               jalview.bin.Cache.log.info("Error retrieving " + item
560                       + " from " + proxy.getDbName(), e);
561               nextfetch.add(item);
562             }
563           }
564         }
565         else
566         {
567           StringBuffer multiacc = new StringBuffer();
568           ArrayList<String> tosend = new ArrayList<String>();
569           while (en.hasNext())
570           {
571             String nel = en.next();
572             tosend.add(nel);
573             multiacc.append(nel);
574             if (en.hasNext())
575             {
576               multiacc.append(proxy.getAccessionSeparator());
577             }
578           }
579           try
580           {
581             AlignmentI rslt;
582             SequenceI[] rs;
583             List<String> nores = new ArrayList<String>();
584             rslt = proxy.getSequenceRecords(multiacc.toString());
585             if (rslt == null || rslt.getHeight() == 0)
586             {
587               // no results - pass on all queries to next source
588               nextfetch.addAll(tosend);
589             }
590             else
591             {
592               aresultq.add(multiacc.toString());
593               aresult.add(rslt);
594
595               rs = rslt.getSequencesArray();
596               // search for each query in the dbrefs associated with each
597               // sequence
598               // returned.
599               // ones we do not find will be used to query next source (if any)
600               for (String q : tosend)
601               {
602                 DBRefEntry dbr = new DBRefEntry(), found[] = null;
603                 dbr.setSource(proxy.getDbSource());
604                 dbr.setVersion(null);
605                 if (proxy.getAccessionValidator() != null)
606                 {
607                   Regex vgr = proxy.getAccessionValidator();
608                   vgr.search(q);
609                   if (vgr.numSubs() > 0)
610                   {
611                     dbr.setAccessionId(vgr.stringMatched(1));
612                   }
613                   else
614                   {
615                     dbr.setAccessionId(vgr.stringMatched());
616                   }
617                 }
618                 else
619                 {
620                   dbr.setAccessionId(q);
621                 }
622                 boolean rfound = false;
623                 for (int r = 0; r < rs.length; r++)
624                 {
625                   if (rs[r] != null
626                           && (found = DBRefUtils.searchRefs(
627                                   rs[r].getDBRef(), dbr)) != null
628                           && found.length > 0)
629                   {
630                     rfound = true;
631                     rs[r] = null;
632                     continue;
633                   }
634                 }
635                 if (!rfound)
636                 {
637                   nextfetch.add(q);
638                 }
639               }
640             }
641           } catch (OutOfMemoryError oome)
642           {
643             new OOMWarning("fetching " + multiacc + " from "
644                     + database.getSelectedItem(), oome, this);
645           }
646         }
647
648       } catch (Exception e)
649       {
650         showErrorMessage("Error retrieving " + textArea.getText()
651                 + " from " + database.getSelectedItem());
652         // error
653         // +="Couldn't retrieve sequences from "+database.getSelectedItem();
654         System.err.println("Retrieval failed for source ='"
655                 + database.getSelectedItem() + "' and query\n'"
656                 + textArea.getText() + "'\n");
657         e.printStackTrace();
658       } catch (OutOfMemoryError e)
659       {
660         // resets dialog box - so we don't use OOMwarning here.
661         showErrorMessage("Out of Memory when retrieving "
662                 + textArea.getText()
663                 + " from "
664                 + database.getSelectedItem()
665                 + "\nPlease see the Jalview FAQ for instructions for increasing the memory available to Jalview.\n");
666         e.printStackTrace();
667       } catch (Error e)
668       {
669         showErrorMessage("Serious Error retrieving " + textArea.getText()
670                 + " from " + database.getSelectedItem());
671         e.printStackTrace();
672       }
673       // Stack results ready for opening in alignment windows
674       if (aresult != null && aresult.size() > 0)
675       {
676         AlignmentI ar = null;
677         if (isAliSource)
678         {
679           addToLast = false;
680           // new window for each result
681           while (aresult.size() > 0)
682           {
683             presult.add(aresult.remove(0));
684             presultTitle.add(aresultq.remove(0) + " "
685                     + getDefaultRetrievalTitle());
686           }
687         }
688         else
689         {
690           String titl = null;
691           if (addToLast && presult.size() > 0)
692           {
693             ar = presult.remove(presult.size() - 1);
694             titl = presultTitle.remove(presultTitle.size() - 1);
695           }
696           // concatenate all results in one window
697           while (aresult.size() > 0)
698           {
699             if (ar == null)
700             {
701               ar = aresult.remove(0);
702             }
703             else
704             {
705               ar.append(aresult.remove(0));
706             }
707             ;
708           }
709           addToLast = true;
710           presult.add(ar);
711           presultTitle.add(titl);
712         }
713       }
714       guiWindow.setProgressBar(MessageManager.getString("status.finshed_querying"), Thread.currentThread()
715               .hashCode());
716     }
717     guiWindow.setProgressBar((presult.size() > 0) ? MessageManager.getString("status.parsing_results")
718             : MessageManager.getString("status.processing"), Thread.currentThread().hashCode());
719     // process results
720     while (presult.size() > 0)
721     {
722       parseResult(presult.remove(0), presultTitle.remove(0), null);
723     }
724     // only remove visual delay after we finished parsing.
725     guiWindow.setProgressBar(null, Thread.currentThread().hashCode());
726     if (nextfetch.size() > 0)
727     {
728       StringBuffer sb = new StringBuffer();
729       sb.append("Didn't retrieve the following "
730               + (nextfetch.size() == 1 ? "query" : nextfetch.size()
731                       + " queries") + ": \n");
732       int l = sb.length(), lr = 0;
733       for (String s : nextfetch)
734       {
735         if (l != sb.length())
736         {
737           sb.append("; ");
738         }
739         if (lr - sb.length() > 40)
740         {
741           sb.append("\n");
742         }
743         sb.append(s);
744       }
745       showErrorMessage(sb.toString());
746     }
747     resetDialog();
748   }
749
750   AlignmentI parseResult(String result, String title)
751   {
752     String format = new IdentifyFile().Identify(result, "Paste");
753     Alignment sequences = null;
754     if (FormatAdapter.isValidFormat(format))
755     {
756       sequences = null;
757       try
758       {
759         sequences = new FormatAdapter().readFile(result.toString(),
760                 "Paste", format);
761       } catch (Exception ex)
762       {
763       }
764
765       if (sequences != null)
766       {
767         return parseResult(sequences, title, format);
768       }
769     }
770     else
771     {
772       showErrorMessage("Error retrieving " + textArea.getText() + " from "
773               + database.getSelectedItem());
774     }
775
776     return null;
777   }
778
779   /**
780    * 
781    * @return a standard title for any results retrieved using the currently
782    *         selected source and settings
783    */
784   public String getDefaultRetrievalTitle()
785   {
786     return "Retrieved from " + database.getSelectedItem();
787   }
788
789   AlignmentI parseResult(AlignmentI al, String title,
790           String currentFileFormat)
791   {
792
793     if (al != null && al.getHeight() > 0)
794     {
795       if (alignFrame == null)
796       {
797         AlignFrame af = new AlignFrame(al, AlignFrame.DEFAULT_WIDTH,
798                 AlignFrame.DEFAULT_HEIGHT);
799         if (currentFileFormat != null)
800         {
801           af.currentFileFormat = currentFileFormat; // WHAT IS THE DEFAULT
802           // FORMAT FOR
803           // NON-FormatAdapter Sourced
804           // Alignments?
805         }
806
807         if (title == null)
808         {
809           title = getDefaultRetrievalTitle();
810         }
811         SequenceFeature[] sfs = null;
812         List<SequenceI> alsqs;
813         synchronized (alsqs = al.getSequences())
814         {
815           for (SequenceI sq : alsqs)
816           {
817             if ((sfs = sq.getSequenceFeatures()) != null)
818             {
819               if (sfs.length > 0)
820               {
821                 af.setShowSeqFeatures(true);
822                 break;
823               }
824             }
825
826           }
827         }
828         Desktop.addInternalFrame(af, title, AlignFrame.DEFAULT_WIDTH,
829                 AlignFrame.DEFAULT_HEIGHT);
830
831         af.statusBar.setText(MessageManager
832                 .getString("label.successfully_pasted_alignment_file"));
833
834         try
835         {
836           af.setMaximum(jalview.bin.Cache.getDefault("SHOW_FULLSCREEN",
837                   false));
838         } catch (Exception ex)
839         {
840         }
841       }
842       else
843       {
844         for (int i = 0; i < al.getHeight(); i++)
845         {
846           alignFrame.viewport.getAlignment().addSequence(
847                   al.getSequenceAt(i)); // this
848           // also
849           // creates
850           // dataset
851           // sequence
852           // entries
853         }
854         alignFrame.viewport.setEndSeq(alignFrame.viewport.getAlignment()
855                 .getHeight());
856         alignFrame.viewport.getAlignment().getWidth();
857         alignFrame.viewport.firePropertyChange("alignment", null,
858                 alignFrame.viewport.getAlignment().getSequences());
859       }
860     }
861     return al;
862   }
863
864   void showErrorMessage(final String error)
865   {
866     resetDialog();
867     javax.swing.SwingUtilities.invokeLater(new Runnable()
868     {
869       @Override
870       public void run()
871       {
872         JOptionPane.showInternalMessageDialog(Desktop.desktop, error,
873                 MessageManager.getString("label.error_retrieving_data"),
874                 JOptionPane.WARNING_MESSAGE);
875       }
876     });
877   }
878 }