JAL-3446 from JAL-3253-applet SequenceFetcher as AsyncSwingWorker
authorBobHanson <hansonr@stolaf.edu>
Tue, 2 Jun 2020 19:11:10 +0000 (14:11 -0500)
committerBobHanson <hansonr@stolaf.edu>
Tue, 2 Jun 2020 19:11:10 +0000 (14:11 -0500)
- uses a javajs.async.SwingJSUtils.StateMachine

- implements a subclass of javajs.async.AsyncSwingWorker, which itself
subclasses SwingWorker

- also required some temporary adjustments for not yet having yet
handled ApplicationSingleton
 on this branch

- added one Preferences final static

- integrates several older methods that together were able to cycle
through a list of items to fetch from a list of possible source
"proxies"

- allows either synchronous (testng) or asynchronous operation simply by
setting the StateMachine's mainLoop timer (0 == synchronous).

- allows JavaScript to display a progress monitor

- allows Java to use a simple Java built in ProgressMonitor for a
SwingWorker-like operation. (easily tested, but not implemented here).

- for more details, see javajs.async.AsyncSwingWorker JavaDoc.

src/jalview/fts/core/GFTSPanel.java
src/jalview/fts/service/pdb/PDBFTSPanel.java
src/jalview/fts/service/uniprot/UniprotFTSPanel.java
src/jalview/gui/AlignFrame.java
src/jalview/gui/Desktop.java
src/jalview/gui/Preferences.java
src/jalview/gui/SequenceFetcher.java
src/jalview/ws/DBRefFetcher.java
src/jalview/ws/SequenceFetcher.java
test/jalview/io/CrossRef2xmlTests.java

index 7ff0f75..e9fd33e 100644 (file)
@@ -916,9 +916,7 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI
 
   public void transferToSequenceFetcher(String ids)
   {
-    seqFetcher.setQuery(ids);
-    Thread worker = new Thread(seqFetcher);
-    worker.start();
+    seqFetcher.fetch(ids, true);
   }
 
   @Override
index 2dd0f8c..7a2fe83 100644 (file)
@@ -222,9 +222,7 @@ public class PDBFTSPanel extends GFTSPanel
     }
 
     String ids = selectedIds.toString();
-    seqFetcher.setQuery(ids);
-    Thread worker = new Thread(seqFetcher);
-    worker.start();
+    seqFetcher.fetch(ids, true);
     delayAndEnableActionButtons();
   }
 
index 182e29b..2d7894f 100644 (file)
@@ -221,9 +221,7 @@ public class UniprotFTSPanel extends GFTSPanel
     }
 
     String ids = selectedIds.toString();
-    seqFetcher.setQuery(ids);
-    Thread worker = new Thread(seqFetcher);
-    worker.start();
+    seqFetcher.fetch(ids, true);
     delayAndEnableActionButtons();
   }
 
index 29f6a2e..71fc831 100644 (file)
@@ -5173,13 +5173,12 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       @Override
       public void run()
       {
-        final jalview.ws.SequenceFetcher sf = jalview.gui.SequenceFetcher
-                .getSequenceFetcherSingleton();
         javax.swing.SwingUtilities.invokeLater(new Runnable()
         {
           @Override
           public void run()
           {
+            final jalview.ws.SequenceFetcher sf = jalview.ws.SequenceFetcher.getInstance();
             String[] dbclasses = sf.getNonAlignmentSources();
             List<DbSourceProxy> otherdb;
             JMenu dfetch = new JMenu();
index 1b85dd5..df76433 100644 (file)
@@ -22,6 +22,7 @@ package jalview.gui;
 
 import java.awt.BorderLayout;
 import java.awt.Color;
+import java.awt.Component;
 import java.awt.Dimension;
 import java.awt.FontMetrics;
 import java.awt.Graphics;
@@ -3375,4 +3376,17 @@ public class Desktop extends jalview.jbgui.GDesktop
     return result;
   }
 
+  
+  /**
+   * BH just a placeholder until we get the singletons in place; for SequenceFetcher test
+   * 
+   * @return
+   */
+
+  public static MyDesktopPane getDesktopPane()
+  {
+    Desktop desktop = Desktop.getInstance();
+    // BH SwingJS TODO 
+    return desktop == null ? null : desktop.desktop;
+  }
 }
index 55345e0..7d29e1e 100755 (executable)
@@ -173,10 +173,14 @@ public class Preferences extends GPreferences
 
   public static final String SHOW_DBREFS_TOOLTIP = "SHOW_DBREFS_TOOLTIP";
 
+  public static final String SHOW_FULLSCREEN = "SHOW_FULLSCREEN";
+
   public static final String SHOW_GROUP_CONSENSUS = "SHOW_GROUP_CONSENSUS";
 
   public static final String SHOW_GROUP_CONSERVATION = "SHOW_GROUP_CONSERVATION";
 
+  public static final String SHOW_IDENTITY = "SHOW_IDENTITY";
+
   public static final String SHOW_JVSUFFIX = "SHOW_JVSUFFIX";
 
   public static final String SHOW_NPFEATS_TOOLTIP = "SHOW_NPFEATS_TOOLTIP";
index 8b5d3b7..ded241b 100755 (executable)
@@ -36,6 +36,7 @@ import jalview.util.Platform;
 import jalview.ws.seqfetcher.DbSourceProxy;
 
 import java.awt.BorderLayout;
+import java.awt.Component;
 import java.awt.Font;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
@@ -57,6 +58,8 @@ import javax.swing.JScrollPane;
 import javax.swing.JTextArea;
 import javax.swing.SwingConstants;
 
+import javajs.async.AsyncSwingWorker;
+
 /**
  * A panel where the use may choose a database source, and enter one or more
  * accessions, to retrieve entries from the database.
@@ -64,9 +67,9 @@ import javax.swing.SwingConstants;
  * If the selected source is Uniprot or PDB, a free text search panel is opened
  * instead to perform the search and selection.
  */
-public class SequenceFetcher extends JPanel implements Runnable
+@SuppressWarnings("serial")
+public class SequenceFetcher extends JPanel
 {
-  private static jalview.ws.SequenceFetcher sfetch = null;
 
   JLabel exampleAccession;
 
@@ -97,20 +100,6 @@ public class SequenceFetcher extends JPanel implements Runnable
   volatile boolean _isConstructing = false;
 
   /**
-   * Returns the shared instance of the SequenceFetcher client
-   * 
-   * @return
-   */
-  public static jalview.ws.SequenceFetcher getSequenceFetcherSingleton()
-  {
-    if (sfetch == null)
-    {
-      sfetch = new jalview.ws.SequenceFetcher();
-    }
-    return sfetch;
-  }
-
-  /**
    * Constructor given a client to receive any status or progress messages
    * (currently either the Desktop, or an AlignFrame panel)
    * 
@@ -132,7 +121,7 @@ public class SequenceFetcher extends JPanel implements Runnable
           final String selectedDb, final String queryString)
   {
     this.progressIndicator = guiIndic;
-    getSequenceFetcherSingleton();
+
     this.guiWindow = progressIndicator;
 
     if (progressIndicator instanceof AlignFrame)
@@ -145,8 +134,8 @@ public class SequenceFetcher extends JPanel implements Runnable
 
     frame = new JInternalFrame();
     frame.setContentPane(this);
-    Desktop.addInternalFrame(frame, getFrameTitle(), true, 400, 
-               Platform.isAMacAndNotJS() ? 240 : 180);
+    Desktop.addInternalFrame(frame, getFrameTitle(), true, 400,
+            Platform.isAMacAndNotJS() ? 240 : 180);
   }
 
   private String getFrameTitle()
@@ -164,7 +153,8 @@ public class SequenceFetcher extends JPanel implements Runnable
     database = new JComboBox<>();
     database.setFont(JvSwingUtils.getLabelFont());
     database.setPrototypeDisplayValue("ENSEMBLGENOMES   ");
-    String[] sources = new jalview.ws.SequenceFetcher().getSupportedDb();
+    String[] sources = jalview.ws.SequenceFetcher.getInstance()
+            .getSupportedDb();
     Arrays.sort(sources, String.CASE_INSENSITIVE_ORDER);
     database.addItem(MessageManager.getString("action.select_ddbb"));
     for (String source : sources)
@@ -315,7 +305,8 @@ public class SequenceFetcher extends JPanel implements Runnable
   {
     StringBuilder sb = new StringBuilder();
     HashSet<String> hs = new HashSet<>();
-    for (DbSourceProxy dbs : sfetch.getSourceProxy(db))
+    for (DbSourceProxy dbs : jalview.ws.SequenceFetcher.getInstance()
+            .getSourceProxy(db))
     {
       String tq = dbs.getTestQuery();
       if (hs.add(tq)) // not a duplicate source
@@ -424,9 +415,9 @@ public class SequenceFetcher extends JPanel implements Runnable
       text = text.replace(",", ";");
     }
     text = text.replaceAll("(\\s|[; ])+", ";");
-    if (!t0.equals(text)) 
+    if (!t0.equals(text))
     {
-         textArea.setText(text);
+      textArea.setText(text);
     }
     if (text.isEmpty())
     {
@@ -436,25 +427,34 @@ public class SequenceFetcher extends JPanel implements Runnable
       resetDialog();
       return;
     }
-    if (database.getSelectedIndex() == 0)
-    {
-      // todo i18n
-      showErrorMessage("Please choose a database");
-      resetDialog();
-      return;
-    }
-
     exampleBtn.setEnabled(false);
     textArea.setEnabled(false);
     okBtn.setEnabled(false);
     closeBtn.setEnabled(false);
     backBtn.setEnabled(false);
+    fetch(null, true);
+  }
 
-    Thread worker = new Thread(this);
-    worker.start();
+  public void fetch(String ids, boolean isAsync)
+  {
+    if (ids == null)
+    {
+      ids = textArea.getText();
+    }
+    else
+    {
+      textArea.setText(ids);
+    }
+    Component parent = null; // or this
+    String title = null; // or some title for the progress monitor
+    int min = AsyncFetchTask.STATE_INIT;
+    int max = AsyncFetchTask.STATE_DONE;
+    int msDelay = (isAsync ? 5 : 0);
+    new AsyncFetchTask(ids, parent, title, msDelay, min, max).execute();
   }
 
-  private void resetDialog()
+
+  protected void resetDialog()
   {
     exampleBtn.setEnabled(true);
     textArea.setEnabled(true);
@@ -463,176 +463,364 @@ public class SequenceFetcher extends JPanel implements Runnable
     backBtn.setEnabled(parentSearchPanel != null);
   }
 
-  @Override
-  public void run()
+  /**
+   * This asynchronous class allows for a single-threaded state machine
+   * SwingWorker to process a list of requests from multiple sources.
+   * 
+   * A standard ProcessMonitor could be attached to this task, but it is
+   * currently not.
+   * 
+   * @author hansonr
+   *
+   */
+  private class AsyncFetchTask extends AsyncSwingWorker
   {
-    boolean addToLast = false;
-    List<String> aresultq = new ArrayList<>();
-    List<String> presultTitle = new ArrayList<>();
-    List<AlignmentI> presult = new ArrayList<>();
-    List<AlignmentI> aresult = new ArrayList<>();
-    List<DbSourceProxy> sources = sfetch
-            .getSourceProxy((String) database.getSelectedItem());
-    Iterator<DbSourceProxy> proxies = sources.iterator();
-    String[] qries = textArea.getText().trim().split(";");
-    List<String> nextFetch = Arrays.asList(qries);
-    Iterator<String> en = Arrays.asList(new String[0]).iterator();
-    int nqueries = qries.length;
-
-    FeatureSettingsModelI preferredFeatureColours = null;
-    while (proxies.hasNext() && (en.hasNext() || nextFetch.size() > 0))
-    {
-      if (!en.hasNext() && nextFetch.size() > 0)
-      {
-        en = nextFetch.iterator();
-        nqueries = nextFetch.size();
-        // save the remaining queries in the original array
-        qries = nextFetch.toArray(new String[nqueries]);
-        nextFetch = new ArrayList<>();
-      }
 
-      DbSourceProxy proxy = proxies.next();
-      try
+    protected boolean addToLast = false;
+
+    protected List<String> aresultq = new ArrayList<>();
+
+    protected List<String> presultTitle = new ArrayList<>();
+
+    protected List<AlignmentI> presult = new ArrayList<>();
+
+    protected List<AlignmentI> aresult = new ArrayList<>();
+
+    protected FeatureSettingsModelI preferredFeatureColours = null;
+
+    protected List<DbSourceProxy> sources;
+
+    protected Iterator<DbSourceProxy> sourceIterator;
+
+    protected String[] fetchArray;
+
+    protected List<String> fetchList;
+
+    protected Iterator<String> fetchIterator;
+
+    protected int fetchCount;
+
+    protected DbSourceProxy source;
+
+    protected String ids;
+
+    protected long myID;
+
+    protected boolean isAsync;
+
+    protected Throwable taskError;
+
+    public AsyncFetchTask(String ids, Component owner, String title,
+            int delayMillis,
+            int min, int max)
+    {
+      super(owner, title, delayMillis, min, max);
+      this.ids = ids;
+      isAsync = (delayMillis != 0);
+      myID = Thread.currentThread().getId();
+    }
+
+    @Override
+    public void initAsync()
+    {
+      sources = jalview.ws.SequenceFetcher.getInstance()
+              .getSourceProxy((String) database.getSelectedItem());
+      sourceIterator = sources.iterator();
+      fetchArray = ids.trim().split(";");
+      fetchList = Arrays.asList(fetchArray);
+    }
+
+    private final static int STATE_INIT = 0;
+
+    private final static int STATE_NEXT_SOURCE = 10;
+
+    private final static int STATE_FETCH_SINGLE = 30;
+
+    private final static int STATE_FETCH_MULTIPLE = 40;
+
+    private final static int STATE_PROCESS = 50;
+
+    private final static int STATE_PARSE_RESULTS = 80;
+
+    private final static int STATE_DONE = 100;
+
+    protected static final int STATE_TASK_ERROR = 99;
+
+    @Override
+    public int doInBackgroundAsync(int progress)
+    {
+      System.out.println("SequenceFetcher.AsyncFetchTask " + isAsync + " "
+              + progress + " "
+              + taskError);
+      switch (progress)
       {
-        // update status
-        guiWindow.setProgressBar(MessageManager.formatMessage(
+      case STATE_INIT:
+      case STATE_NEXT_SOURCE:
+        boolean doneFetching = (fetchIterator == null
+                || !fetchIterator.hasNext());
+        boolean havePending = (fetchList.size() > 0);
+        if (!sourceIterator.hasNext() || doneFetching && !havePending)
+        {
+          showProgress((presult.size() > 0)
+                  ? MessageManager.getString("status.parsing_results")
+                  : MessageManager.getString("status.processing"));
+          return STATE_PARSE_RESULTS;
+        }
+        source = sourceIterator.next();
+        if (doneFetching)
+        {
+          // if we are here, we must have some pending still
+          fetchCount = fetchList.size();
+          fetchIterator = fetchList.iterator();
+          // save the remaining queries in the original array
+          fetchArray = fetchList.toArray(new String[fetchCount]);
+          // and clear the
+          fetchList = new ArrayList<>();
+        }
+        showProgress(MessageManager.formatMessage(
                 "status.fetching_sequence_queries_from", new String[]
-                { Integer.valueOf(nqueries).toString(),
-                    proxy.getDbName() }),
-                Thread.currentThread().hashCode());
-        if (proxy.getMaximumQueryCount() == 1)
+                { Integer.valueOf(fetchCount).toString(),
+                    source.getDbName() }));
+        return (source.getMaximumQueryCount() == 1 ? STATE_FETCH_SINGLE
+                : STATE_FETCH_MULTIPLE);
+      case STATE_FETCH_SINGLE:
+        if (fetchIterator.hasNext())
         {
-          /*
-           * proxy only handles one accession id at a time
-           */
-          while (en.hasNext())
+          return runSubtask(new Runnable()
           {
-            String acc = en.next();
-            if (!fetchSingleAccession(proxy, acc, aresultq, aresult))
+
+            @Override
+            public void run()
             {
-              nextFetch.add(acc);
+              // source only handles one accession id at a time
+              try
+              {
+                if (!isAsync)
+                {
+                  // for CrossRef2xmlTest only; to "allow the server to breathe"
+                  // (but we are doing that already when isAsync is true)
+                  Thread.sleep(5);
+                }
+                String notFound = fetchSingleAccession(source,
+                        fetchIterator.next(), aresultq, aresult);
+                if (notFound != null)
+                {
+                  fetchList.add(notFound);
+                }
+              } catch (Throwable e)
+              {
+                taskError = e;
+              }
             }
-          }
+          });
         }
-        else
+        return STATE_PROCESS;
+      case STATE_FETCH_MULTIPLE:
+        // proxy can fetch multiple accessions at one time
+        setProgressAsync(STATE_PROCESS);
+        return runSubtask(new Runnable()
         {
-          /*
-           * proxy can fetch multiple accessions at one time
-           */
-          fetchMultipleAccessions(proxy, en, aresultq, aresult, nextFetch);
-        }
-      } catch (Exception e)
-      {
-        showErrorMessage("Error retrieving " + textArea.getText() + " from "
-                + database.getSelectedItem());
-        // error
-        // +="Couldn't retrieve sequences from "+database.getSelectedItem();
-        System.err.println("Retrieval failed for source ='"
-                + database.getSelectedItem() + "' and query\n'"
-                + textArea.getText() + "'\n");
-        e.printStackTrace();
-      } catch (OutOfMemoryError e)
-      {
-        showErrorMessage("Out of Memory when retrieving "
-                + textArea.getText() + " from " + database.getSelectedItem()
-                + "\nPlease see the Jalview FAQ for instructions for increasing the memory available to Jalview.\n");
-        e.printStackTrace();
-      } catch (Error e)
-      {
-        showErrorMessage("Serious Error retrieving " + textArea.getText()
-                + " from " + database.getSelectedItem());
-        e.printStackTrace();
-      }
 
-      // Stack results ready for opening in alignment windows
-      if (aresult != null && aresult.size() > 0)
-      {
-        FeatureSettingsModelI proxyColourScheme = proxy
-                .getFeatureColourScheme();
-        if (proxyColourScheme != null)
-        {
-          preferredFeatureColours = proxyColourScheme;
-        }
+          @Override
+          public void run()
+          {
+            try
+            {
+              fetchMultipleAccessions(source, fetchIterator, aresultq,
+                      aresult, fetchList);
+            } catch (Throwable e)
+            {
+              taskError = e;
+            }
+          }
 
-        AlignmentI ar = null;
-        if (proxy.isAlignmentSource())
+        });
+      case STATE_PROCESS:
+        // Stack results ready for opening in alignment windows
+        if (aresult != null && aresult.size() > 0)
         {
-          addToLast = false;
-          // new window for each result
-          while (aresult.size() > 0)
+          FeatureSettingsModelI proxyColourScheme = source
+                  .getFeatureColourScheme();
+          if (proxyColourScheme != null)
           {
-            presult.add(aresult.remove(0));
-            presultTitle.add(
-                    aresultq.remove(0) + " " + getDefaultRetrievalTitle());
+            preferredFeatureColours = proxyColourScheme;
           }
-        }
-        else
-        {
-          String titl = null;
-          if (addToLast && presult.size() > 0)
+
+          AlignmentI ar = null;
+          if (source.isAlignmentSource())
           {
-            ar = presult.remove(presult.size() - 1);
-            titl = presultTitle.remove(presultTitle.size() - 1);
+            addToLast = false;
+            // new window for each result
+            while (aresult.size() > 0)
+            {
+              presult.add(aresult.remove(0));
+              presultTitle.add(aresultq.remove(0) + " "
+                      + getDefaultRetrievalTitle());
+            }
           }
-          // concatenate all results in one window
-          while (aresult.size() > 0)
+          else
           {
-            if (ar == null)
+            String titl = null;
+            if (addToLast && presult.size() > 0)
             {
-              ar = aresult.remove(0);
+              ar = presult.remove(presult.size() - 1);
+              titl = presultTitle.remove(presultTitle.size() - 1);
             }
-            else
+            // concatenate all results in one window
+            while (aresult.size() > 0)
             {
-              ar.append(aresult.remove(0));
+              if (ar == null)
+              {
+                ar = aresult.remove(0);
+              }
+              else
+              {
+                ar.append(aresult.remove(0));
+              }
             }
+            addToLast = true;
+            presult.add(ar);
+            presultTitle.add(titl);
           }
-          addToLast = true;
-          presult.add(ar);
-          presultTitle.add(titl);
         }
+        showProgress(MessageManager.getString("status.finshed_querying"));
+        return STATE_NEXT_SOURCE;
+      case STATE_PARSE_RESULTS:
+        while (presult.size() > 0)
+        {
+          parseResult(presult.remove(0), presultTitle.remove(0), null,
+                  preferredFeatureColours);
+        }
+        break;
+      case STATE_TASK_ERROR:
+        showProgress(null);
+        super.cancelAsync();
+        return 0; // arbitrary; ignored
       }
-      guiWindow.setProgressBar(
-              MessageManager.getString("status.finshed_querying"),
-              Thread.currentThread().hashCode());
+      return STATE_DONE;
     }
-    guiWindow
-            .setProgressBar(
-                    (presult.size() > 0)
-                            ? MessageManager
-                                    .getString("status.parsing_results")
-                            : MessageManager.getString("status.processing"),
-                    Thread.currentThread().hashCode());
-    // process results
-    while (presult.size() > 0)
-    {
-      parseResult(presult.remove(0), presultTitle.remove(0), null,
-              preferredFeatureColours);
+
+    protected void resume()
+    {
+      if (!isAsync)
+      {
+        return;
+      }
+      super.setPaused(false);
+      super.stateLoop();
     }
-    // only remove visual delay after we finished parsing.
-    guiWindow.setProgressBar(null, Thread.currentThread().hashCode());
-    if (nextFetch.size() > 0)
-    {
-      StringBuffer sb = new StringBuffer();
-      sb.append("Didn't retrieve the following "
-              + (nextFetch.size() == 1 ? "query"
-                      : nextFetch.size() + " queries")
-              + ": \n");
-      int l = sb.length(), lr = 0;
-      for (String s : nextFetch)
+
+    private int runSubtask(Runnable subtask)
+    {
+
+      Runnable r = new Runnable()
       {
-        if (l != sb.length())
+
+        @Override
+        public void run()
         {
-          sb.append("; ");
+          try
+          {
+            subtask.run();
+          } catch (Throwable e)
+          {
+            taskError = e;
+          }
+          if (checkError(taskError))
+          {
+            setProgressAsync(STATE_TASK_ERROR);
+          }
+          else
+          {
+            taskError = null;
+          }
+          if (isAsync)
+          {
+            resume();
+          }
         }
-        if (lr - sb.length() > 40)
+      };
+
+      if (isAsync)
+      {
+        super.setPaused(true);
+        new Thread(r).start();
+        return 0; // arbitrary return -- ignored because we are paused.
+      }
+      r.run();
+      return super.getProgressAsync();
+    }
+
+    @Override
+    public void doneAsync()
+    {
+      showProgress(null);
+      if (fetchList.size() > 0)
+      {
+        StringBuffer sb = new StringBuffer();
+        sb.append("Didn't retrieve the following "
+                + (fetchList.size() == 1 ? "query"
+                        : fetchList.size() + " queries")
+                + ": \n");
+        int l = sb.length(), lr = 0;
+        for (String s : fetchList)
         {
-          sb.append("\n");
+          if (l != sb.length())
+          {
+            sb.append("; ");
+          }
+          if (lr - sb.length() > 40)
+          {
+            sb.append("\n");
+          }
+          sb.append(s);
         }
-        sb.append(s);
+        showErrorMessage(sb.toString());
       }
-      showErrorMessage(sb.toString());
+      resetDialog();
     }
-    resetDialog();
+
+    /**
+     * 
+     * @param e
+     * @return true if there was an error and we need to STOP
+     */
+    protected boolean checkError(Throwable e)
+    {
+      if (e == null)
+      {
+        return false;
+      }
+      String problem = "retrieving " + ids + " from "
+              + database.getSelectedItem();
+      if (e instanceof Exception)
+      {
+        showErrorMessage("Error " + problem);
+        System.err.println("Retrieval failed for source ='"
+                + database.getSelectedItem() + "' and query\n'"
+                + ids + "'\n");
+      }
+      else if (e instanceof OutOfMemoryError)
+      {
+        showErrorMessage("Out of Memory when " + problem
+                + "\nPlease see the Jalview FAQ for instructions for increasing the memory available to Jalview.\n");
+        // option here to return false and quit this, but that is not how
+        // original code works - BH
+        // return false;
+      }
+      else
+      {
+        showErrorMessage("Serious Error " + problem);
+      }
+      e.printStackTrace();
+      return true;
+    }
+
+    private void showProgress(String msg)
+    {
+      guiWindow.setProgressBar(msg, myID);
+    }
+
   }
 
   /**
@@ -700,48 +888,19 @@ public class SequenceFetcher extends JPanel implements Runnable
    *          a list of successful queries to add to
    * @param aresult
    *          a list of retrieved alignments to add to
-   * @return true if the fetch was successful, else false
+   * @return null if the fetch was successful; the accession if not
    */
-  boolean fetchSingleAccession(DbSourceProxy proxy, String accession,
-          List<String> aresultq, List<AlignmentI> aresult)
+  String fetchSingleAccession(DbSourceProxy proxy, String accession,
+          List<String> aresultq, List<AlignmentI> aresult) throws Throwable
   {
-    boolean success = false;
-    try
-    {
-      if (aresult != null)
-      {
-        try
-        {
-          // give the server a chance to breathe
-          Thread.sleep(5);
-        } catch (Exception e)
-        {
-          //
-        }
-      }
-
-      AlignmentI indres = null;
-      try
-      {
-        indres = proxy.getSequenceRecords(accession);
-      } catch (OutOfMemoryError oome)
-      {
-        new OOMWarning(
-                "fetching " + accession + " from " + proxy.getDbName(),
-                oome, this);
-      }
-      if (indres != null)
-      {
-        aresultq.add(accession);
-        aresult.add(indres);
-        success = true;
-      }
-    } catch (Exception e)
+    AlignmentI indres = proxy.getSequenceRecords(accession);
+    if (indres == null)
     {
-      Cache.log.info("Error retrieving " + accession + " from "
-              + proxy.getDbName(), e);
+      return accession;
     }
-    return success;
+    aresultq.add(accession);
+    aresult.add(indres);
+    return null;
   }
 
   /**
@@ -761,12 +920,12 @@ public class SequenceFetcher extends JPanel implements Runnable
 
     for (String q : queries)
     {
-       // BH 2019.01.25 dbr is never used.
-//      DBRefEntry dbr = new DBRefEntry();
-//      dbr.setSource(proxy.getDbSource());
-//      dbr.setVersion(null);
+      // BH 2019.01.25 dbr is never used.
+      // DBRefEntry dbr = new DBRefEntry();
+      // dbr.setSource(proxy.getDbSource());
+      // dbr.setVersion(null);
       String accId = proxy.getAccessionIdFromQuery(q);
-//      dbr.setAccessionId(accId);
+      // dbr.setAccessionId(accId);
       boolean rfound = false;
       for (int r = 0, nr = rs.length; r < nr; r++)
       {
@@ -835,7 +994,7 @@ public class SequenceFetcher extends JPanel implements Runnable
         {
           af.getViewport().applyFeaturesStyle(preferredFeatureColours);
         }
-        if (Cache.getDefault("HIDE_INTRONS", true))
+        if (Cache.getDefault(Preferences.HIDE_INTRONS, true))
         {
           af.hideFeatureColumns(SequenceOntologyI.EXON, false);
         }
@@ -847,7 +1006,8 @@ public class SequenceFetcher extends JPanel implements Runnable
 
         try
         {
-          af.setMaximum(Cache.getDefault("SHOW_FULLSCREEN", false));
+          af.setMaximum(
+                  Cache.getDefault(Preferences.SHOW_FULLSCREEN, false));
         } catch (Exception ex)
         {
         }
@@ -868,7 +1028,8 @@ public class SequenceFetcher extends JPanel implements Runnable
       @Override
       public void run()
       {
-        JvOptionPane.showInternalMessageDialog(Desktop.desktop, error,
+        JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
+                error,
                 MessageManager.getString("label.error_retrieving_data"),
                 JvOptionPane.WARNING_MESSAGE);
       }
@@ -894,11 +1055,6 @@ public class SequenceFetcher extends JPanel implements Runnable
     frame.setVisible(false);
   }
 
-  public void setQuery(String ids)
-  {
-    textArea.setText(ids);
-  }
-
   /**
    * Called to modify the search panel for embedding as an alternative tab of a
    * free text search panel. The database choice list is hidden (since the
@@ -913,4 +1069,6 @@ public class SequenceFetcher extends JPanel implements Runnable
     backBtn.setVisible(true);
     parentSearchPanel = parentPanel;
   }
+
+
 }
index 7daa7b4..0290919 100644 (file)
@@ -134,7 +134,7 @@ public class DBRefFetcher implements Runnable
     }
     this.dataset = ds;
     // TODO Jalview 2.5 lots of this code should be in the gui package!
-    sfetcher = jalview.gui.SequenceFetcher.getSequenceFetcherSingleton();
+    sfetcher = jalview.ws.SequenceFetcher.getInstance();
     // set default behaviour for transferring excess sequence data to the
     // dataset
     trimDsSeqs = Cache.getDefault(TRIM_RETRIEVED_SEQUENCES, true);
index a480176..0612530 100644 (file)
@@ -90,4 +90,17 @@ public class SequenceFetcher extends ASequenceFetcher
     Collections.sort(src, String.CASE_INSENSITIVE_ORDER);
     return src.toArray(new String[src.size()]);
   }
+
+  private static SequenceFetcher mockFetcher;
+
+  /**
+   * used in jalview.gui.SequenceFetcher
+   * 
+   * @return
+   */
+  public static SequenceFetcher getInstance()
+  {
+    return (mockFetcher == null ? mockFetcher = new SequenceFetcher() : mockFetcher);
+  }
+
 }
index 3ca6ed8..120a4f7 100644 (file)
@@ -186,7 +186,7 @@ public class CrossRef2xmlTests extends Jalview2xmlBase
 
         SequenceFetcher sf = new SequenceFetcher(Desktop.instance,
                 forSource, forAccession);
-        sf.run();
+        sf.fetch(null, false);
         AlignFrame[] afs = Desktop.getAlignFrames();
         if (afs.length == 0)
         {