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