Clover icon

Coverage Report

  1. Project Clover database Mon Nov 11 2024 17:27:16 GMT
  2. Package jalview.gui

File SequenceFetcher.java

 

Coverage histogram

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

Code metrics

106
315
40
2
998
746
114
0.36
7.88
20
2.85

Classes

Class Line # Actions
SequenceFetcher 69 308 108
0.0133928571.3%
SequenceFetcher.StringPair 71 7 6
0.00%
 

Contributing tests

This file is covered by 192 tests. .

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.gui;
22   
23    import java.awt.BorderLayout;
24    import java.awt.Font;
25    import java.awt.event.ActionEvent;
26    import java.awt.event.ActionListener;
27    import java.awt.event.KeyAdapter;
28    import java.awt.event.KeyEvent;
29    import java.util.ArrayList;
30    import java.util.Arrays;
31    import java.util.HashSet;
32    import java.util.Iterator;
33    import java.util.List;
34   
35    import javax.swing.JButton;
36    import javax.swing.JCheckBox;
37    import javax.swing.JComboBox;
38    import javax.swing.JInternalFrame;
39    import javax.swing.JLabel;
40    import javax.swing.JPanel;
41    import javax.swing.JScrollPane;
42    import javax.swing.JTextArea;
43    import javax.swing.SwingConstants;
44   
45    import jalview.api.FeatureSettingsModelI;
46    import jalview.bin.Cache;
47    import jalview.bin.Console;
48    import jalview.datamodel.AlignmentI;
49    import jalview.datamodel.DBRefEntry;
50    import jalview.datamodel.SequenceI;
51    import jalview.fts.core.GFTSPanel;
52    import jalview.fts.service.pdb.PDBFTSPanel;
53    import jalview.fts.service.threedbeacons.TDBeaconsFTSPanel;
54    import jalview.fts.service.uniprot.UniprotFTSPanel;
55    import jalview.io.FileFormatI;
56    import jalview.io.gff.SequenceOntologyI;
57    import jalview.util.DBRefUtils;
58    import jalview.util.MessageManager;
59    import jalview.util.Platform;
60    import jalview.ws.seqfetcher.DbSourceProxy;
61   
62    /**
63    * A panel where the use may choose a database source, and enter one or more
64    * accessions, to retrieve entries from the database.
65    * <p>
66    * If the selected source is Uniprot or PDB, a free text search panel is opened
67    * instead to perform the search and selection.
68    */
 
69    public class SequenceFetcher extends JPanel implements Runnable
70    {
 
71    private class StringPair
72    {
73    private String key;
74   
75    private String display;
76   
 
77  0 toggle public StringPair(String s1, String s2)
78    {
79  0 key = s1;
80  0 display = s2;
81    }
82   
 
83  0 toggle public StringPair(String s)
84    {
85  0 this(s, s);
86    }
87   
 
88  0 toggle public String getKey()
89    {
90  0 return key;
91    }
92   
 
93  0 toggle public String getDisplay()
94    {
95  0 return display;
96    }
97   
 
98  0 toggle @Override
99    public String toString()
100    {
101  0 return display;
102    }
103   
 
104  0 toggle public boolean equals(StringPair other)
105    {
106  0 return other.key == this.key;
107    }
108    }
109   
110    private static jalview.ws.SequenceFetcher sfetch = null;
111   
112    JLabel exampleAccession;
113   
114    JComboBox<StringPair> database;
115   
116    JCheckBox replacePunctuation;
117   
118    JButton okBtn;
119   
120    JButton exampleBtn;
121   
122    JButton closeBtn;
123   
124    JButton backBtn;
125   
126    JTextArea textArea;
127   
128    JInternalFrame frame;
129   
130    IProgressIndicator guiWindow;
131   
132    AlignFrame alignFrame;
133   
134    GFTSPanel parentSearchPanel;
135   
136    IProgressIndicator progressIndicator;
137   
138    volatile boolean _isConstructing = false;
139   
140    /**
141    * Returns the shared instance of the SequenceFetcher client
142    *
143    * @return
144    */
 
145  3366 toggle public static jalview.ws.SequenceFetcher getSequenceFetcherSingleton()
146    {
147  3366 if (sfetch == null)
148    {
149  6 sfetch = new jalview.ws.SequenceFetcher();
150    }
151  3366 return sfetch;
152    }
153   
154    /**
155    * Constructor given a client to receive any status or progress messages
156    * (currently either the Desktop, or an AlignFrame panel)
157    *
158    * @param guiIndic
159    */
 
160  0 toggle public SequenceFetcher(IProgressIndicator guiIndic)
161    {
162  0 this(guiIndic, null, null);
163    }
164   
165    /**
166    * Constructor with specified database and accession(s) to retrieve
167    *
168    * @param guiIndic
169    * @param selectedDb
170    * @param queryString
171    */
 
172  0 toggle public SequenceFetcher(IProgressIndicator guiIndic,
173    final String selectedDb, final String queryString)
174    {
175  0 this.progressIndicator = guiIndic;
176  0 getSequenceFetcherSingleton();
177  0 this.guiWindow = progressIndicator;
178   
179  0 if (progressIndicator instanceof AlignFrame)
180    {
181  0 alignFrame = (AlignFrame) progressIndicator;
182    }
183   
184  0 jbInit(selectedDb);
185  0 textArea.setText(queryString);
186   
187  0 frame = new JInternalFrame();
188  0 frame.setContentPane(this);
189  0 frame.setFrameIcon(null);
190  0 Desktop.addInternalFrame(frame, getFrameTitle(), true, 400,
191  0 Platform.isAMacAndNotJS() ? 240 : 180);
192    }
193   
 
194  0 toggle private String getFrameTitle()
195    {
196  0 return ((alignFrame == null)
197    ? MessageManager.getString("label.new_sequence_fetcher")
198    : MessageManager
199    .getString("label.additional_sequence_fetcher"));
200    }
201   
 
202  0 toggle private void jbInit(String selectedDb)
203    {
204  0 this.setLayout(new BorderLayout());
205   
206  0 database = new JComboBox<>();
207  0 database.setFont(JvSwingUtils.getLabelFont());
208  0 StringPair instructionItem = new StringPair(
209    MessageManager.getString("action.select_ddbb"));
210  0 database.setPrototypeDisplayValue(instructionItem);
211  0 String[] sources = new jalview.ws.SequenceFetcher().getSupportedDb();
212  0 Arrays.sort(sources, String.CASE_INSENSITIVE_ORDER);
213  0 database.addItem(instructionItem);
214  0 for (String source : sources)
215    {
216  0 List<DbSourceProxy> slist = sfetch.getSourceProxy(source);
217  0 if (slist.size() == 1 && slist.get(0) != null)
218    {
219  0 database.addItem(new StringPair(source, slist.get(0).getDbName()));
220    }
221    else
222    {
223  0 database.addItem(new StringPair(source));
224    }
225    }
226  0 setDatabaseSelectedItem(selectedDb);
227  0 if (database.getSelectedIndex() == -1)
228    {
229  0 database.setSelectedIndex(0);
230    }
231  0 database.setMaximumRowCount(database.getItemCount());
232  0 database.addActionListener(new ActionListener()
233    {
 
234  0 toggle @Override
235    public void actionPerformed(ActionEvent e)
236    {
237  0 String currentSelection = ((StringPair) database.getSelectedItem())
238    .getKey();
239  0 updateExampleQuery(currentSelection);
240   
241  0 if ("pdb".equalsIgnoreCase(currentSelection))
242    {
243  0 frame.dispose();
244  0 new PDBFTSPanel(SequenceFetcher.this);
245    }
246  0 else if ("uniprot".equalsIgnoreCase(currentSelection))
247    {
248  0 frame.dispose();
249  0 new UniprotFTSPanel(SequenceFetcher.this);
250    }
251  0 else if ("3d-beacons".equalsIgnoreCase(currentSelection))
252    {
253  0 frame.dispose();
254  0 new TDBeaconsFTSPanel(SequenceFetcher.this);
255    }
256    else
257    {
258  0 otherSourceAction();
259    }
260    }
261    });
262   
263  0 exampleAccession = new JLabel("");
264  0 exampleAccession.setFont(new Font("Verdana", Font.BOLD, 11));
265  0 JLabel jLabel1 = new JLabel(MessageManager
266    .getString("label.separate_multiple_accession_ids"));
267  0 jLabel1.setFont(new Font("Verdana", Font.ITALIC, 11));
268  0 jLabel1.setHorizontalAlignment(SwingConstants.LEFT);
269   
270  0 replacePunctuation = new JCheckBox(
271    MessageManager.getString("label.replace_commas_semicolons"));
272  0 replacePunctuation.setHorizontalAlignment(SwingConstants.LEFT);
273  0 replacePunctuation.setFont(new Font("Verdana", Font.ITALIC, 11));
274  0 okBtn = new JButton(MessageManager.getString("action.ok"));
275  0 okBtn.addActionListener(new ActionListener()
276    {
 
277  0 toggle @Override
278    public void actionPerformed(ActionEvent e)
279    {
280  0 ok_actionPerformed();
281    }
282    });
283  0 JButton clear = new JButton(MessageManager.getString("action.clear"));
284  0 clear.addActionListener(new ActionListener()
285    {
 
286  0 toggle @Override
287    public void actionPerformed(ActionEvent e)
288    {
289  0 clear_actionPerformed();
290    }
291    });
292   
293  0 exampleBtn = new JButton(MessageManager.getString("label.example"));
294  0 exampleBtn.addActionListener(new ActionListener()
295    {
 
296  0 toggle @Override
297    public void actionPerformed(ActionEvent e)
298    {
299  0 example_actionPerformed();
300    }
301    });
302  0 closeBtn = new JButton(MessageManager.getString("action.cancel"));
303  0 closeBtn.addActionListener(new ActionListener()
304    {
 
305  0 toggle @Override
306    public void actionPerformed(ActionEvent e)
307    {
308  0 close_actionPerformed(e);
309    }
310    });
311  0 backBtn = new JButton(MessageManager.getString("action.back"));
312  0 backBtn.addActionListener(new ActionListener()
313    {
 
314  0 toggle @Override
315    public void actionPerformed(ActionEvent e)
316    {
317  0 parentSearchPanel.btn_back_ActionPerformed();
318    }
319    });
320    // back not visible unless embedded
321  0 backBtn.setVisible(false);
322   
323  0 textArea = new JTextArea();
324  0 textArea.setFont(JvSwingUtils.getLabelFont());
325  0 textArea.setLineWrap(true);
326  0 textArea.addKeyListener(new KeyAdapter()
327    {
 
328  0 toggle @Override
329    public void keyPressed(KeyEvent e)
330    {
331  0 if (e.getKeyCode() == KeyEvent.VK_ENTER)
332    {
333  0 ok_actionPerformed();
334    }
335    }
336    });
337   
338  0 JPanel actionPanel = new JPanel();
339  0 actionPanel.add(backBtn);
340  0 actionPanel.add(exampleBtn);
341  0 actionPanel.add(clear);
342  0 actionPanel.add(okBtn);
343  0 actionPanel.add(closeBtn);
344   
345  0 JPanel databasePanel = new JPanel();
346  0 databasePanel.setLayout(new BorderLayout());
347  0 databasePanel.add(database, BorderLayout.NORTH);
348  0 databasePanel.add(exampleAccession, BorderLayout.CENTER);
349  0 JPanel jPanel2a = new JPanel(new BorderLayout());
350  0 jPanel2a.add(jLabel1, BorderLayout.NORTH);
351  0 jPanel2a.add(replacePunctuation, BorderLayout.SOUTH);
352  0 databasePanel.add(jPanel2a, BorderLayout.SOUTH);
353   
354  0 JPanel idsPanel = new JPanel();
355  0 idsPanel.setLayout(new BorderLayout(0, 5));
356  0 JScrollPane jScrollPane1 = new JScrollPane();
357  0 jScrollPane1.getViewport().add(textArea);
358  0 idsPanel.add(jScrollPane1, BorderLayout.CENTER);
359   
360  0 this.add(actionPanel, BorderLayout.SOUTH);
361  0 this.add(idsPanel, BorderLayout.CENTER);
362  0 this.add(databasePanel, BorderLayout.NORTH);
363    }
364   
 
365  0 toggle private void setDatabaseSelectedItem(String db)
366    {
367  0 for (int i = 0; i < database.getItemCount(); i++)
368    {
369  0 StringPair sp = database.getItemAt(i);
370  0 if (sp != null && db != null && db.equals(sp.getKey()))
371    {
372  0 database.setSelectedIndex(i);
373  0 return;
374    }
375    }
376    }
377   
378    /**
379    * Answers a semi-colon-delimited string with the example query or queries for
380    * the selected database
381    *
382    * @param db
383    * @return
384    */
 
385  0 toggle protected String getExampleQueries(String db)
386    {
387  0 StringBuilder sb = new StringBuilder();
388  0 HashSet<String> hs = new HashSet<>();
389  0 for (DbSourceProxy dbs : sfetch.getSourceProxy(db))
390    {
391  0 String tq = dbs.getTestQuery();
392  0 if (hs.add(tq)) // not a duplicate source
393    {
394  0 if (sb.length() > 0)
395    {
396  0 sb.append(";");
397    }
398  0 sb.append(tq);
399    }
400    }
401  0 return sb.toString();
402    }
403   
404    /**
405    * Action on selecting a database other than Uniprot or PDB is to enable or
406    * disable 'Replace commas', and await input in the query field
407    */
 
408  0 toggle protected void otherSourceAction()
409    {
410  0 try
411    {
412  0 String eq = exampleAccession.getText();
413    // TODO this should be a property of the SequenceFetcher whether commas
414    // are allowed in the IDs...
415   
416  0 boolean enablePunct = !(eq != null && eq.indexOf(",") > -1);
417  0 replacePunctuation.setEnabled(enablePunct);
418   
419    } catch (Exception ex)
420    {
421  0 exampleAccession.setText("");
422  0 replacePunctuation.setEnabled(true);
423    }
424  0 repaint();
425    }
426   
427    /**
428    * Sets the text of the example query to incorporate the example accession
429    * provided by the selected database source
430    *
431    * @param selectedDatabase
432    * @return
433    */
 
434  0 toggle protected String updateExampleQuery(String selectedDatabase)
435    {
436  0 String eq = getExampleQueries(selectedDatabase);
437  0 exampleAccession.setText(MessageManager
438    .formatMessage("label.example_query_param", new String[]
439    { eq }));
440  0 return eq;
441    }
442   
443    /**
444    * Action on clicking the 'Example' button is to write the example accession
445    * as the query text field value
446    */
 
447  0 toggle protected void example_actionPerformed()
448    {
449  0 String eq = getExampleQueries(
450    ((StringPair) database.getSelectedItem()).getKey());
451  0 textArea.setText(eq);
452  0 repaint();
453    }
454   
455    /**
456    * Clears the query input field
457    */
 
458  0 toggle protected void clear_actionPerformed()
459    {
460  0 textArea.setText("");
461  0 repaint();
462    }
463   
464    /**
465    * Action on Close button is to close this frame, and also (if it is embedded
466    * in a search panel) to close the search panel
467    *
468    * @param e
469    */
 
470  0 toggle protected void close_actionPerformed(ActionEvent e)
471    {
472  0 try
473    {
474  0 frame.setClosed(true);
475  0 if (parentSearchPanel != null)
476    {
477  0 parentSearchPanel.btn_cancel_ActionPerformed();
478    }
479    } catch (Exception ex)
480    {
481    }
482    }
483   
484    /**
485    * Action on OK is to start the fetch for entered accession(s)
486    */
 
487  0 toggle public void ok_actionPerformed()
488    {
489    /*
490    * tidy inputs and check there is something to search for
491    */
492  0 String t0 = textArea.getText();
493  0 String text = t0.trim();
494  0 if (replacePunctuation.isEnabled() && replacePunctuation.isSelected())
495    {
496  0 text = text.replace(",", ";");
497    }
498  0 text = text.replaceAll("(\\s|[; ])+", ";");
499  0 if (!t0.equals(text))
500    {
501  0 textArea.setText(text);
502    }
503  0 if (text.isEmpty())
504    {
505    // todo i18n
506  0 showErrorMessage(
507    "Please enter a (semi-colon separated list of) database id(s)");
508  0 resetDialog();
509  0 return;
510    }
511  0 if (database.getSelectedIndex() == 0)
512    {
513    // todo i18n
514  0 showErrorMessage("Please choose a database");
515  0 resetDialog();
516  0 return;
517    }
518   
519  0 exampleBtn.setEnabled(false);
520  0 textArea.setEnabled(false);
521  0 okBtn.setEnabled(false);
522  0 closeBtn.setEnabled(false);
523  0 backBtn.setEnabled(false);
524   
525  0 Thread worker = new Thread(this);
526  0 worker.start();
527    }
528   
 
529  0 toggle private void resetDialog()
530    {
531  0 exampleBtn.setEnabled(true);
532  0 textArea.setEnabled(true);
533  0 okBtn.setEnabled(true);
534  0 closeBtn.setEnabled(true);
535  0 backBtn.setEnabled(parentSearchPanel != null);
536    }
537   
 
538  0 toggle @Override
539    public void run()
540    {
541  0 boolean addToLast = false;
542  0 List<String> aresultq = new ArrayList<>();
543  0 List<String> presultTitle = new ArrayList<>();
544  0 List<AlignmentI> presult = new ArrayList<>();
545  0 List<AlignmentI> aresult = new ArrayList<>();
546  0 List<DbSourceProxy> sources = sfetch.getSourceProxy(
547    ((StringPair) database.getSelectedItem()).getKey());
548  0 Iterator<DbSourceProxy> proxies = sources.iterator();
549  0 String[] qries = textArea.getText().trim().split(";");
550  0 List<String> nextFetch = Arrays.asList(qries);
551  0 Iterator<String> en = Arrays.asList(new String[0]).iterator();
552  0 int nqueries = qries.length;
553   
554  0 FeatureSettingsModelI preferredFeatureColours = null;
555  0 while (proxies.hasNext() && (en.hasNext() || nextFetch.size() > 0))
556    {
557  0 if (!en.hasNext() && nextFetch.size() > 0)
558    {
559  0 en = nextFetch.iterator();
560  0 nqueries = nextFetch.size();
561    // save the remaining queries in the original array
562  0 qries = nextFetch.toArray(new String[nqueries]);
563  0 nextFetch = new ArrayList<>();
564    }
565   
566  0 DbSourceProxy proxy = proxies.next();
567  0 try
568    {
569    // update status
570  0 guiWindow.setProgressBar(MessageManager.formatMessage(
571    "status.fetching_sequence_queries_from", new String[]
572    { Integer.valueOf(nqueries).toString(),
573    proxy.getDbName() }),
574    Thread.currentThread().hashCode());
575  0 if (proxy.getMaximumQueryCount() == 1)
576    {
577    /*
578    * proxy only handles one accession id at a time
579    */
580  0 while (en.hasNext())
581    {
582  0 String acc = en.next();
583  0 if (!fetchSingleAccession(proxy, acc, aresultq, aresult))
584    {
585  0 nextFetch.add(acc);
586    }
587    }
588    }
589    else
590    {
591    /*
592    * proxy can fetch multiple accessions at one time
593    */
594  0 fetchMultipleAccessions(proxy, en, aresultq, aresult, nextFetch);
595    }
596    } catch (Exception e)
597    {
598  0 showErrorMessage("Error retrieving " + textArea.getText() + " from "
599    + ((StringPair) database.getSelectedItem()).getDisplay());
600    // error
601    // +="Couldn't retrieve sequences from "+database.getSelectedItem();
602  0 jalview.bin.Console.errPrintln("Retrieval failed for source ='"
603    + ((StringPair) database.getSelectedItem()).getDisplay()
604    + "' and query\n'" + textArea.getText() + "'\n");
605  0 e.printStackTrace();
606    } catch (OutOfMemoryError e)
607    {
608  0 showErrorMessage("Out of Memory when retrieving "
609    + textArea.getText() + " from "
610    + ((StringPair) database.getSelectedItem()).getDisplay()
611    + "\nPlease see the Jalview FAQ for instructions for increasing the memory available to Jalview.\n");
612  0 e.printStackTrace();
613    } catch (Error e)
614    {
615  0 showErrorMessage("Serious Error retrieving " + textArea.getText()
616    + " from "
617    + ((StringPair) database.getSelectedItem()).getDisplay());
618  0 e.printStackTrace();
619    }
620   
621    // Stack results ready for opening in alignment windows
622  0 if (aresult != null && aresult.size() > 0)
623    {
624  0 FeatureSettingsModelI proxyColourScheme = proxy
625    .getFeatureColourScheme();
626  0 if (proxyColourScheme != null)
627    {
628  0 preferredFeatureColours = proxyColourScheme;
629    }
630   
631  0 AlignmentI ar = null;
632  0 if (proxy.isAlignmentSource())
633    {
634  0 addToLast = false;
635    // new window for each result
636  0 while (aresult.size() > 0)
637    {
638  0 presult.add(aresult.remove(0));
639  0 presultTitle.add(
640    aresultq.remove(0) + " " + getDefaultRetrievalTitle());
641    }
642    }
643    else
644    {
645  0 String titl = null;
646  0 if (addToLast && presult.size() > 0)
647    {
648  0 ar = presult.remove(presult.size() - 1);
649  0 titl = presultTitle.remove(presultTitle.size() - 1);
650    }
651    // concatenate all results in one window
652  0 while (aresult.size() > 0)
653    {
654  0 if (ar == null)
655    {
656  0 ar = aresult.remove(0);
657    }
658    else
659    {
660  0 ar.append(aresult.remove(0));
661    }
662    }
663  0 addToLast = true;
664  0 presult.add(ar);
665  0 presultTitle.add(titl);
666    }
667    }
668  0 guiWindow.setProgressBar(
669    MessageManager.getString("status.finshed_querying"),
670    Thread.currentThread().hashCode());
671    }
672  0 guiWindow
673    .setProgressBar(
674  0 (presult.size() > 0)
675    ? MessageManager
676    .getString("status.parsing_results")
677    : MessageManager.getString("status.processing"),
678    Thread.currentThread().hashCode());
679    // process results
680  0 while (presult.size() > 0)
681    {
682  0 parseResult(presult.remove(0), presultTitle.remove(0), null,
683    preferredFeatureColours);
684    }
685    // only remove visual delay after we finished parsing.
686  0 guiWindow.setProgressBar(null, Thread.currentThread().hashCode());
687  0 if (nextFetch.size() > 0)
688    {
689  0 StringBuffer sb = new StringBuffer();
690  0 sb.append("Didn't retrieve the following "
691  0 + (nextFetch.size() == 1 ? "query"
692    : nextFetch.size() + " queries")
693    + ": \n");
694  0 int l = sb.length(), lr = 0;
695  0 for (String s : nextFetch)
696    {
697  0 if (l != sb.length())
698    {
699  0 sb.append("; ");
700    }
701  0 if (lr - sb.length() > 40)
702    {
703  0 sb.append("\n");
704    }
705  0 sb.append(s);
706    }
707  0 showErrorMessage(sb.toString());
708    }
709  0 resetDialog();
710    }
711   
712    /**
713    * Tries to fetch one or more accession ids from the database proxy
714    *
715    * @param proxy
716    * @param accessions
717    * the queries to fetch
718    * @param aresultq
719    * a successful queries list to add to
720    * @param aresult
721    * a list of retrieved alignments to add to
722    * @param nextFetch
723    * failed queries are added to this list
724    * @throws Exception
725    */
 
726  0 toggle void fetchMultipleAccessions(DbSourceProxy proxy,
727    Iterator<String> accessions, List<String> aresultq,
728    List<AlignmentI> aresult, List<String> nextFetch) throws Exception
729    {
730  0 StringBuilder multiacc = new StringBuilder();
731  0 List<String> tosend = new ArrayList<>();
732  0 while (accessions.hasNext())
733    {
734  0 String nel = accessions.next();
735  0 tosend.add(nel);
736  0 multiacc.append(nel);
737  0 if (accessions.hasNext())
738    {
739  0 multiacc.append(proxy.getAccessionSeparator());
740    }
741    }
742   
743  0 try
744    {
745  0 String query = multiacc.toString();
746  0 AlignmentI rslt = proxy.getSequenceRecords(query);
747  0 if (rslt == null || rslt.getHeight() == 0)
748    {
749    // no results - pass on all queries to next source
750  0 nextFetch.addAll(tosend);
751    }
752    else
753    {
754  0 aresultq.add(query);
755  0 aresult.add(rslt);
756  0 if (tosend.size() > 1)
757    {
758  0 checkResultForQueries(rslt, tosend, nextFetch, proxy);
759    }
760    }
761    } catch (OutOfMemoryError oome)
762    {
763  0 new OOMWarning("fetching " + multiacc + " from "
764    + ((StringPair) database.getSelectedItem()).getDisplay(),
765    oome, this);
766    }
767    }
768   
769    /**
770    * Query for a single accession id via the database proxy
771    *
772    * @param proxy
773    * @param accession
774    * @param aresultq
775    * a list of successful queries to add to
776    * @param aresult
777    * a list of retrieved alignments to add to
778    * @return true if the fetch was successful, else false
779    */
 
780  0 toggle boolean fetchSingleAccession(DbSourceProxy proxy, String accession,
781    List<String> aresultq, List<AlignmentI> aresult)
782    {
783  0 boolean success = false;
784  0 try
785    {
786  0 if (aresult != null)
787    {
788  0 try
789    {
790    // give the server a chance to breathe
791  0 Thread.sleep(5);
792    } catch (Exception e)
793    {
794    //
795    }
796    }
797   
798  0 AlignmentI indres = null;
799  0 try
800    {
801  0 indres = proxy.getSequenceRecords(accession);
802    } catch (OutOfMemoryError oome)
803    {
804  0 new OOMWarning(
805    "fetching " + accession + " from " + proxy.getDbName(),
806    oome, this);
807    }
808  0 if (indres != null)
809    {
810  0 aresultq.add(accession);
811  0 aresult.add(indres);
812  0 success = true;
813    }
814    } catch (Exception e)
815    {
816  0 Console.info("Error retrieving " + accession + " from "
817    + proxy.getDbName(), e);
818    }
819  0 return success;
820    }
821   
822    /**
823    * Checks which of the queries were successfully retrieved by searching the
824    * DBRefs of the retrieved sequences for a match. Any not found are added to
825    * the 'nextFetch' list.
826    *
827    * @param rslt
828    * @param queries
829    * @param nextFetch
830    * @param proxy
831    */
 
832  0 toggle void checkResultForQueries(AlignmentI rslt, List<String> queries,
833    List<String> nextFetch, DbSourceProxy proxy)
834    {
835  0 SequenceI[] rs = rslt.getSequencesArray();
836   
837  0 for (String q : queries)
838    {
839    // BH 2019.01.25 dbr is never used.
840    // DBRefEntry dbr = new DBRefEntry();
841    // dbr.setSource(proxy.getDbSource());
842    // dbr.setVersion(null);
843  0 String accId = proxy.getAccessionIdFromQuery(q);
844    // dbr.setAccessionId(accId);
845  0 boolean rfound = false;
846  0 for (int r = 0, nr = rs.length; r < nr; r++)
847    {
848  0 if (rs[r] != null)
849    {
850  0 List<DBRefEntry> found = DBRefUtils.searchRefs(rs[r].getDBRefs(),
851    accId);
852  0 if (!found.isEmpty())
853    {
854  0 rfound = true;
855  0 break;
856    }
857    }
858    }
859  0 if (!rfound)
860    {
861  0 nextFetch.add(q);
862    }
863    }
864    }
865   
866    /**
867    *
868    * @return a standard title for any results retrieved using the currently
869    * selected source and settings
870    */
 
871  0 toggle public String getDefaultRetrievalTitle()
872    {
873  0 return "Retrieved from "
874    + ((StringPair) database.getSelectedItem()).getDisplay();
875    }
876   
877    /**
878    * constructs an alignment frame given the data and metadata
879    *
880    * @param al
881    * @param title
882    * @param currentFileFormat
883    * @param preferredFeatureColours
884    * @return the alignment
885    */
 
886  0 toggle public AlignmentI parseResult(AlignmentI al, String title,
887    FileFormatI currentFileFormat,
888    FeatureSettingsModelI preferredFeatureColours)
889    {
890   
891  0 if (al != null && al.getHeight() > 0)
892    {
893  0 if (title == null)
894    {
895  0 title = getDefaultRetrievalTitle();
896    }
897  0 if (alignFrame == null)
898    {
899  0 AlignFrame af = new AlignFrame(al, AlignFrame.DEFAULT_WIDTH,
900    AlignFrame.DEFAULT_HEIGHT);
901  0 if (currentFileFormat != null)
902    {
903  0 af.currentFileFormat = currentFileFormat;
904    }
905   
906  0 List<SequenceI> alsqs = al.getSequences();
907  0 synchronized (alsqs)
908    {
909  0 for (SequenceI sq : alsqs)
910    {
911  0 if (sq.getFeatures().hasFeatures())
912    {
913  0 af.setShowSeqFeatures(true);
914  0 break;
915    }
916    }
917    }
918   
919  0 af.getViewport().applyFeaturesStyle(preferredFeatureColours);
920  0 if (Cache.getDefault("HIDE_INTRONS", true))
921    {
922  0 af.hideFeatureColumns(SequenceOntologyI.EXON, false);
923    }
924  0 Desktop.addInternalFrame(af, title, AlignFrame.DEFAULT_WIDTH,
925    AlignFrame.DEFAULT_HEIGHT);
926   
927  0 af.setStatus(MessageManager
928    .getString("label.successfully_pasted_alignment_file"));
929   
930  0 try
931    {
932  0 af.setMaximum(Cache.getDefault("SHOW_FULLSCREEN", false));
933    } catch (Exception ex)
934    {
935    }
936    }
937    else
938    {
939  0 alignFrame.viewport.addAlignment(al, title);
940    }
941    }
942  0 return al;
943    }
944   
 
945  0 toggle void showErrorMessage(final String error)
946    {
947  0 resetDialog();
948  0 javax.swing.SwingUtilities.invokeLater(new Runnable()
949    {
 
950  0 toggle @Override
951    public void run()
952    {
953  0 JvOptionPane.showInternalMessageDialog(Desktop.desktop, error,
954    MessageManager.getString("label.error_retrieving_data"),
955    JvOptionPane.WARNING_MESSAGE);
956    }
957    });
958    }
959   
 
960  0 toggle public IProgressIndicator getProgressIndicator()
961    {
962  0 return progressIndicator;
963    }
964   
 
965  0 toggle public void setProgressIndicator(IProgressIndicator progressIndicator)
966    {
967  0 this.progressIndicator = progressIndicator;
968    }
969   
970    /**
971    * Hide this panel (on clicking the database button to open the database
972    * chooser)
973    */
 
974  0 toggle void hidePanel()
975    {
976  0 frame.setVisible(false);
977    }
978   
 
979  0 toggle public void setQuery(String ids)
980    {
981  0 textArea.setText(ids);
982    }
983   
984    /**
985    * Called to modify the search panel for embedding as an alternative tab of a
986    * free text search panel. The database choice list is hidden (since the
987    * choice has been made), and a Back button is made visible (which reopens the
988    * Sequence Fetcher panel).
989    *
990    * @param parentPanel
991    */
 
992  0 toggle public void embedIn(GFTSPanel parentPanel)
993    {
994  0 database.setVisible(false);
995  0 backBtn.setVisible(true);
996  0 parentSearchPanel = parentPanel;
997    }
998    }