JAL-3144 SequenceFetcher without JDatabaseTree
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Mon, 29 Oct 2018 16:13:23 +0000 (16:13 +0000)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Mon, 29 Oct 2018 16:13:23 +0000 (16:13 +0000)
12 files changed:
src/jalview/fts/core/GFTSPanel.java
src/jalview/fts/service/pdb/PDBFTSPanel.java
src/jalview/fts/service/pdb/PDBFTSRestClient.java
src/jalview/fts/service/uniprot/UniProtFTSRestClient.java
src/jalview/fts/service/uniprot/UniprotFTSPanel.java
src/jalview/gui/AlignFrame.java
src/jalview/gui/SequenceFetcher.java
src/jalview/jbgui/GAlignFrame.java
src/jalview/ws/DBRefFetcher.java
src/jalview/ws/SequenceFetcher.java
test/jalview/io/CrossRef2xmlTests.java
utils/test/JalviewJSTest.java

index 38ea958..557b713 100644 (file)
@@ -131,7 +131,7 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI
 
   protected JLabel lbl_blank = new JLabel(balnkPlaceholderImage);
 
-  private JTabbedPane tabbedPane = jalview.jbgui.GDesktop.createTabbedPane();
+  JTabbedPane tabbedPane = jalview.jbgui.GDesktop.createTabbedPane();
 
   private JPanel pnl_actions = new JPanel();
 
@@ -259,8 +259,7 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI
       {
         tabs.addTab(MessageManager.getString("label.retrieve_ids"),
                 fetcher);
-        fetcher.setDatabaseChooserVisible(false);
-        fetcher.embedWithFTSPanel(this);
+        fetcher.embedIn(this);
       }
       mainFrame.setMinimumSize(new Dimension(MIN_WIDTH, MIN_HEIGHT));
       final JPanel ftsPanel = this;
@@ -842,6 +841,10 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI
     }
   }
 
+  /**
+   * Action on Back button is to close this panel and open a new Sequence
+   * Fetcher panel
+   */
   public void btn_back_ActionPerformed()
   {
     closeAction();
@@ -893,7 +896,7 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI
 
   public void transferToSequenceFetcher(String ids)
   {
-    seqFetcher.getTextArea().setText(ids);
+    seqFetcher.setQuery(ids);
     Thread worker = new Thread(seqFetcher);
     worker.start();
   }
index 053d91b..90b6d06 100644 (file)
@@ -121,16 +121,14 @@ public class PDBFTSPanel extends GFTSPanel
 
           if (isPaginationEnabled() && resultSetCount > 0)
           {
+            String f1 = totalNumberformatter.format(Integer.valueOf(offSet + 1));
+            String f2 = totalNumberformatter
+                    .format(Integer.valueOf(offSet + resultSetCount));
+            String f3 = totalNumberformatter
+                    .format(Integer.valueOf(totalResultSetCount));
             updateSearchFrameTitle(defaultFTSFrameTitle + " - " + result
-                    + " "
-                    + totalNumberformatter.format((Number) (offSet + 1))
-                    + " to "
-                    + totalNumberformatter
-                            .format((Number) (offSet + resultSetCount))
-                    + " of "
-                    + totalNumberformatter
-                            .format((Number) totalResultSetCount)
-                    + " " + " (" + (endTime - startTime) + " milli secs)");
+                    + " " + f1 + " to " + f2 + " of " + f3 + " " + " ("
+                    + (endTime - startTime) + " milli secs)");
           }
           else
           {
@@ -220,8 +218,7 @@ public class PDBFTSPanel extends GFTSPanel
     }
 
     String ids = selectedIds.toString();
-    // System.out.println(">>>>>>>>>>>>>>>> selected Ids: " + ids);
-    seqFetcher.getTextArea().setText(ids);
+    seqFetcher.setQuery(ids);
     Thread worker = new Thread(seqFetcher);
     worker.start();
     delayAndEnableActionButtons();
index a5b441f..301cb16 100644 (file)
@@ -43,26 +43,15 @@ import org.json.simple.JSONObject;
 import org.json.simple.parser.JSONParser;
 import org.json.simple.parser.ParseException;
 
-//import jalview.javascript.web.Client;
-//import jalview.javascript.web.ClientResponse;
-//import jalview.javascript.web.WebResource;
-
 import com.sun.jersey.api.client.Client;
 import com.sun.jersey.api.client.ClientResponse;
 import com.sun.jersey.api.client.WebResource;
-
-import com.sun.jersey.api.client.config.ClientConfig;
 import com.sun.jersey.api.client.config.DefaultClientConfig;
 
 /**
  * A rest client for querying the Search endpoint of the PDB API
  * 
- * BH 2018: just a tiny tweak here - for SwingJS, we coerce the classes to be
- * from jalview.javascript.web instead of com.sun.jersey.api.client
- * 
- * 
  * @author tcnofoegbu
- *
  */
 public class PDBFTSRestClient extends FTSRestClient
 {
@@ -90,9 +79,6 @@ public class PDBFTSRestClient extends FTSRestClient
   {
     try
     {
-      Client client;
-      WebResource webResource;
-
       String wantedFields = getDataColumnsFieldsAsCommaDelimitedString(
               pdbRestRequest.getWantedFields());
       int responseSize = (pdbRestRequest.getResponseSize() == 0)
@@ -137,6 +123,7 @@ public class PDBFTSRestClient extends FTSRestClient
 
       // BH 2018 the trick here is to coerce the classes in Javascript to be 
       // different from the ones in Java yet still allow this to be correct for Java
+      Client client;
       Class<ClientResponse> clientResponseClass;
       if (/** @j2sNative true || */
       false)
@@ -152,6 +139,7 @@ public class PDBFTSRestClient extends FTSRestClient
         clientResponseClass = ClientResponse.class;
       }
 
+      WebResource webResource;
       if (pdbRestRequest.isFacet())
       {
         webResource = client.resource(PDB_SEARCH_ENDPOINT)
index 262ed86..924b061 100644 (file)
@@ -22,6 +22,7 @@
 package jalview.fts.service.uniprot;
 
 import jalview.bin.Cache;
+import jalview.bin.Jalview;
 import jalview.fts.api.FTSData;
 import jalview.fts.api.FTSDataColumnI;
 import jalview.fts.api.FTSRestClientI;
@@ -40,7 +41,6 @@ import javax.ws.rs.core.MediaType;
 import com.sun.jersey.api.client.Client;
 import com.sun.jersey.api.client.ClientResponse;
 import com.sun.jersey.api.client.WebResource;
-import com.sun.jersey.api.client.config.ClientConfig;
 import com.sun.jersey.api.client.config.DefaultClientConfig;
 
 public class UniProtFTSRestClient extends FTSRestClient
@@ -64,9 +64,6 @@ public class UniProtFTSRestClient extends FTSRestClient
   {
     try
     {
-      ClientConfig clientConfig = new DefaultClientConfig();
-      Client client = Client.create(clientConfig);
-
       String wantedFields = getDataColumnsFieldsAsCommaDelimitedString(
               uniportRestRequest.getWantedFields());
       int responseSize = (uniportRestRequest.getResponseSize() == 0)
@@ -90,6 +87,25 @@ public class UniProtFTSRestClient extends FTSRestClient
                                 + uniportRestRequest.getSearchTerm();
       }
 
+      // BH 2018 the trick here is to coerce the classes in Javascript to be
+      // different from the ones in Java yet still allow this to be correct for
+      // Java
+      Client client;
+      Class<ClientResponse> clientResponseClass;
+      if (/** @j2sNative true || */
+      false)
+      {
+        // JavaScript only -- coerce types to Java types for Java
+        client = (Client) (Object) new jalview.javascript.web.Client();
+        clientResponseClass = (Class<ClientResponse>) (Object) jalview.javascript.web.ClientResponse.class;
+      }
+      else
+      {
+        // Java only
+        client = Client.create(new DefaultClientConfig());
+        clientResponseClass = ClientResponse.class;
+      }
+
       WebResource webResource = null;
       webResource = client.resource(uniprotSearchEndpoint)
               .queryParam("format", "tab")
@@ -99,7 +115,7 @@ public class UniProtFTSRestClient extends FTSRestClient
               .queryParam("sort", "score").queryParam("query", query);
       // Execute the REST request
       ClientResponse clientResponse = webResource
-              .accept(MediaType.TEXT_PLAIN).get(ClientResponse.class);
+              .accept(MediaType.TEXT_PLAIN).get(clientResponseClass);
       String uniProtTabDelimittedResponseString = clientResponse
               .getEntity(String.class);
       // Make redundant objects eligible for garbage collection to conserve
@@ -113,8 +129,9 @@ public class UniProtFTSRestClient extends FTSRestClient
         throw new Exception(errorMessage);
 
       }
-      int xTotalResults = Integer.valueOf(
-              clientResponse.getHeaders().get("X-Total-Results").get(0));
+      int xTotalResults = Jalview.isJS() ? 1
+              : Integer.valueOf(clientResponse.getHeaders()
+                      .get("X-Total-Results").get(0));
       clientResponse = null;
       client = null;
       return parseUniprotResponse(uniProtTabDelimittedResponseString,
index df54dea..09c6ab8 100644 (file)
@@ -46,6 +46,12 @@ public class UniprotFTSPanel extends GFTSPanel
 
   private static final String UNIPROT_AUTOSEARCH = "FTS.UNIPROT.AUTOSEARCH";
 
+  /**
+   * Constructor given an (optional) sequence fetcher panel to revert to on
+   * clicking the 'Back' button
+   * 
+   * @param fetcher
+   */
   public UniprotFTSPanel(SequenceFetcher fetcher)
   {
     super(fetcher);
@@ -122,13 +128,15 @@ public class UniprotFTSPanel extends GFTSPanel
           {
             updateSearchFrameTitle(defaultFTSFrameTitle + " - " + result
                     + " "
-                    + totalNumberformatter.format((Number) (offSet + 1))
+                    + totalNumberformatter
+                            .format(Integer.valueOf(offSet + 1))
                     + " to "
                     + totalNumberformatter
-                            .format((Number) (offSet + resultSetCount))
+                            .format(Integer
+                                    .valueOf(offSet + resultSetCount))
                     + " of "
                     + totalNumberformatter
-                            .format((Number) totalResultSetCount)
+                            .format(Integer.valueOf(totalResultSetCount))
                     + " " + " (" + (endTime - startTime) + " milli secs)");
           }
           else
@@ -209,8 +217,7 @@ public class UniprotFTSPanel extends GFTSPanel
     }
 
     String ids = selectedIds.toString();
-    // System.out.println(">>>>>>>>>>>>>>>> selected Ids: " + ids);
-    seqFetcher.getTextArea().setText(ids);
+    seqFetcher.setQuery(ids);
     Thread worker = new Thread(seqFetcher);
     worker.start();
     delayAndEnableActionButtons();
index 161fd7e..f3583e2 100644 (file)
@@ -1010,9 +1010,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   }
 
   @Override
-  public void fetchSequence_actionPerformed(ActionEvent e)
+  public void fetchSequence_actionPerformed()
   {
-    new jalview.gui.SequenceFetcher(this);
+    new SequenceFetcher(this);
   }
 
   @Override
@@ -5013,22 +5013,19 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
 
     });
     rfetch.add(fetchr);
-    final AlignFrame me = this;
     new Thread(new Runnable()
     {
       @Override
       public void run()
       {
         final jalview.ws.SequenceFetcher sf = jalview.gui.SequenceFetcher
-                .getSequenceFetcherSingleton(me);
+                .getSequenceFetcherSingleton();
         javax.swing.SwingUtilities.invokeLater(new Runnable()
         {
           @Override
           public void run()
           {
-            String[] dbclasses = sf.getOrderedSupportedSources();
-            // sf.getDbInstances(jalview.ws.dbsources.DasSequenceSource.class);
-            // jalview.util.QuickSort.sort(otherdb, otherdb);
+            String[] dbclasses = sf.getNonAlignmentSources();
             List<DbSourceProxy> otherdb;
             JMenu dfetch = new JMenu();
             JMenu ifetch = new JMenu();
@@ -5045,12 +5042,6 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
               {
                 continue;
               }
-              // List<DbSourceProxy> dbs=otherdb;
-              // otherdb=new ArrayList<DbSourceProxy>();
-              // for (DbSourceProxy db:dbs)
-              // {
-              // if (!db.isA(DBRefSource.ALIGNMENTDB)
-              // }
               if (mname == null)
               {
                 mname = "From " + dbclass;
index 118d877..8037fed 100755 (executable)
@@ -43,59 +43,46 @@ import java.awt.event.KeyAdapter;
 import java.awt.event.KeyEvent;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 
 import javax.swing.JButton;
 import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
 import javax.swing.JInternalFrame;
 import javax.swing.JLabel;
 import javax.swing.JPanel;
 import javax.swing.JScrollPane;
 import javax.swing.JTextArea;
 import javax.swing.SwingConstants;
-import javax.swing.tree.DefaultMutableTreeNode;
 
+/**
+ * A panel where the use may choose a database source, and enter one or more
+ * accessions, to retrieve entries from the database.
+ * <p>
+ * 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
 {
-  JLabel dbeg = new JLabel();
-
-  JDatabaseTree database;
-
-  JButton databaseButt;
-
-  JLabel jLabel1 = new JLabel();
-
-  JCheckBox replacePunctuation = new JCheckBox();
-
-  JButton ok = new JButton();
-
-  JButton clear = new JButton();
-
-  JButton example = new JButton();
-
-  JButton close = new JButton();
-
-  JButton back = new JButton();
-
-  JPanel jPanel1 = new JPanel();
+  private static jalview.ws.SequenceFetcher sfetch = null;
 
-  JTextArea textArea = new JTextArea();
+  JLabel exampleAccession;
 
-  JScrollPane jScrollPane1 = new JScrollPane();
+  JComboBox<String> database;
 
-  JPanel jPanel2 = new JPanel();
+  JCheckBox replacePunctuation;
 
-  JPanel jPanel3 = new JPanel();
+  JButton okBtn;
 
-  JPanel jPanel4 = new JPanel();
+  JButton exampleBtn;
 
-  BorderLayout borderLayout1 = new BorderLayout();
+  JButton closeBtn;
 
-  BorderLayout borderLayout2 = new BorderLayout();
+  JButton backBtn;
 
-  BorderLayout borderLayout3 = new BorderLayout();
+  JTextArea textArea;
 
   JInternalFrame frame;
 
@@ -103,265 +90,63 @@ public class SequenceFetcher extends JPanel implements Runnable
 
   AlignFrame alignFrame;
 
-  StringBuffer result;
+  GFTSPanel parentSearchPanel;
 
-  final String noDbSelected = "-- Select Database --";
+  IProgressIndicator progressIndicator;
 
-  private static jalview.ws.SequenceFetcher sfetch = null;
-
-  private static boolean _initingFetcher = false;
-
-  private static Thread initingThread = null;
-
-  public JTextArea getTextArea()
-  {
-    return textArea;
-  }
+  volatile boolean _isConstructing = false;
 
   /**
-   * Blocking method that initialises and returns the shared instance of the
-   * SequenceFetcher client
+   * Returns the shared instance of the SequenceFetcher client
    * 
-   * @param guiWindow
-   *          - where the initialisation delay message should be shown
-   * @return the singleton instance of the sequence fetcher client
+   * @return
    */
-  public static jalview.ws.SequenceFetcher getSequenceFetcherSingleton(
-          final IProgressIndicator guiWindow)
+  public static jalview.ws.SequenceFetcher getSequenceFetcherSingleton()
   {
-    if (_initingFetcher && initingThread != null && initingThread.isAlive())
-    {
-      if (guiWindow != null)
-      {
-        guiWindow.setProgressBar(
-                MessageManager.getString(
-                        "status.waiting_sequence_database_fetchers_init"),
-                Thread.currentThread().hashCode());
-      }
-      // initting happening on another thread - so wait around to see if it
-      // finishes.
-      while (_initingFetcher && initingThread != null
-              && initingThread.isAlive())
-      {
-        try
-        {
-          Thread.sleep(10);
-        } catch (Exception e)
-        {
-        }
-        ;
-      }
-      if (guiWindow != null)
-      {
-        guiWindow.setProgressBar(
-                MessageManager.getString(
-                        "status.waiting_sequence_database_fetchers_init"),
-                Thread.currentThread().hashCode());
-      }
-    }
     if (sfetch == null)
     {
-      _initingFetcher = true;
-      initingThread = Thread.currentThread();
-      /**
-       * give a visual indication that sequence fetcher construction is occuring
-       */
-      if (guiWindow != null)
-      {
-        guiWindow.setProgressBar(
-                MessageManager.getString(
-                        "status.init_sequence_database_fetchers"),
-                Thread.currentThread().hashCode());
-      }
-
-      jalview.ws.SequenceFetcher sf = new jalview.ws.SequenceFetcher();
-      if (guiWindow != null)
-      {
-        guiWindow.setProgressBar(null, Thread.currentThread().hashCode());
-      }
-      sfetch = sf;
-      _initingFetcher = false;
-      initingThread = null;
+      sfetch = new jalview.ws.SequenceFetcher();
     }
     return sfetch;
   }
 
-  private IProgressIndicator progressIndicator;
-
-  private volatile boolean _isConstructing = false;
-
-  private List<AlignFrame> newAlframes = null;
-
-  public SequenceFetcher(IProgressIndicator guiIndic)
-  {
-    this(guiIndic, null, null);
-  }
-
-  public SequenceFetcher(IProgressIndicator guiIndic,
-          final String selectedDb, final String queryString)
-  {
-    this._isConstructing = true;
-    this.progressIndicator = guiIndic;
-    final SequenceFetcher us = this;
-    // launch initialiser thread
-    Thread sf = new Thread(new Runnable()
-    {
-
-      @Override
-      public void run()
-      {
-        if (getSequenceFetcherSingleton(progressIndicator) != null)
-        {
-          us.initGui(progressIndicator, selectedDb, queryString);
-          us._isConstructing = false;
-        }
-        else
-        {
-          javax.swing.SwingUtilities.invokeLater(new Runnable()
-          {
-            @Override
-            public void run()
-            {
-              JvOptionPane.showInternalMessageDialog(Desktop.desktop,
-                      MessageManager.getString(
-                              "warn.couldnt_create_sequence_fetcher_client"),
-                      MessageManager.getString(
-                              "label.couldnt_create_sequence_fetcher"),
-                      JvOptionPane.ERROR_MESSAGE);
-            }
-          });
-
-          // raise warning dialog
-        }
-      }
-    });
-    sf.start();
-  }
-
   /**
-   * blocking call which creates a new sequence fetcher panel, configures it and
-   * presses the OK button with the given database and query.
+   * Constructor given a client to receive any status or progress messages
+   * (currently either the Desktop, or an AlignFrame panel)
    * 
-   * @param database
-   * @param query
+   * @param guiIndic
    */
-  public static List<AlignFrame> fetchAndShow(String database, String query)
+  public SequenceFetcher(IProgressIndicator guiIndic)
   {
-    final SequenceFetcher sf = new SequenceFetcher(Desktop.instance,
-            database, query);
-    while (sf._isConstructing)
-    {
-      try
-      {
-        Thread.sleep(50);
-      } catch (Exception q)
-      {
-        return Collections.emptyList();
-      }
-    }
-    sf.newAlframes = new ArrayList<>();
-    sf.run();
-    return sf.newAlframes;
+    this(guiIndic, null, null);
   }
 
-  private class DatabaseAuthority extends DefaultMutableTreeNode
-  {
-
-  };
-
-  private class DatabaseSource extends DefaultMutableTreeNode
-  {
-
-  };
-
   /**
-   * initialise the database and query for this fetcher panel
+   * Constructor with specified database and accession(s) to retrieve
    * 
+   * @param guiIndic
    * @param selectedDb
-   *          - string that should correspond to a sequence fetcher
    * @param queryString
-   *          - string that will be entered in the query dialog
-   * @return true if UI was configured with valid database and query string
    */
-  protected boolean setInitialQuery(String selectedDb, String queryString)
+  public SequenceFetcher(IProgressIndicator guiIndic,
+          final String selectedDb, final String queryString)
   {
-    if (selectedDb == null || selectedDb.trim().length() == 0)
-    {
-      return false;
-    }
-    try
-    {
-      List<DbSourceProxy> sp = sfetch.getSourceProxy(selectedDb);
-      for (DbSourceProxy sourcep : sp)
-      {
-        if (sourcep.getTier() == 0)
-        {
-          database.selection = Arrays
-                  .asList(new DbSourceProxy[]
-                  { sourcep });
-          break;
-        }
-      }
-      if (database.selection == null || database.selection.size() == 0)
-      {
-        System.err.println(
-                "Ignoring fetch parameter db='" + selectedDb + "'");
-        return false;
-      }
-      textArea.setText(queryString);
-    } catch (Exception q)
-    {
-      System.err.println("Ignoring fetch parameter db='" + selectedDb
-              + "' and query='" + queryString + "'");
-      return false;
-    }
-    return true;
-  }
+    this.progressIndicator = guiIndic;
+    getSequenceFetcherSingleton();
+    this.guiWindow = progressIndicator;
 
-  /**
-   * called by thread spawned by constructor
-   * 
-   * @param guiWindow
-   * @param queryString
-   * @param selectedDb
-   */
-  private void initGui(IProgressIndicator guiWindow, String selectedDb,
-          String queryString)
-  {
-    this.guiWindow = guiWindow;
-    if (guiWindow instanceof AlignFrame)
-    {
-      alignFrame = (AlignFrame) guiWindow;
-    }
-    database = new JDatabaseTree(sfetch);
-    try
+    if (progressIndicator instanceof AlignFrame)
     {
-      jbInit();
-      /*
-       * configure the UI with any query parameters we were called with
-       */
-      if (!setInitialQuery(selectedDb, queryString))
-      {
-        /*
-         * none provided, so show the database chooser
-         */
-        database.waitForInput();
-      }
-    } catch (Exception ex)
-    {
-      ex.printStackTrace();
+      alignFrame = (AlignFrame) progressIndicator;
     }
 
+    jbInit(selectedDb);
+    textArea.setText(queryString);
+
     frame = new JInternalFrame();
     frame.setContentPane(this);
-    if (Platform.isAMac())
-    {
-      Desktop.addInternalFrame(frame, getFrameTitle(), false, 400, 240);
-    }
-    else
-    {
-      Desktop.addInternalFrame(frame, getFrameTitle(), false, 400, 180);
-    }
+    int height = Platform.isAMac() ? 240 : 180;
+    Desktop.addInternalFrame(frame, getFrameTitle(), true, 400, height);
   }
 
   private String getFrameTitle()
@@ -372,33 +157,64 @@ public class SequenceFetcher extends JPanel implements Runnable
                     .getString("label.additional_sequence_fetcher"));
   }
 
-  GFTSPanel parentFTSframe = null;
-  /**
-   * change the buttons so they fit with the FTS panel.
-   */
-  public void embedWithFTSPanel(GFTSPanel toClose)
+  private void jbInit(String selectedDb)
   {
-    back.setVisible(true);
-    parentFTSframe = toClose;
-  }
-  private void jbInit() throws Exception
-  {
-    this.setLayout(borderLayout2);
+    this.setLayout(new BorderLayout());
 
+    database = new JComboBox<>();
     database.setFont(JvSwingUtils.getLabelFont());
-    dbeg.setFont(new java.awt.Font("Verdana", Font.BOLD, 11));
-    jLabel1.setFont(new java.awt.Font("Verdana", Font.ITALIC, 11));
-    jLabel1.setHorizontalAlignment(SwingConstants.CENTER);
-    jLabel1.setText(MessageManager
+    database.setPrototypeDisplayValue("ENSEMBLGENOMES   ");
+    String[] sources = new jalview.ws.SequenceFetcher().getSupportedDb();
+    Arrays.sort(sources, String.CASE_INSENSITIVE_ORDER);
+    database.addItem(MessageManager.getString("action.select_ddbb"));
+    for (String source : sources)
+    {
+      database.addItem(source);
+    }
+    database.setSelectedItem(selectedDb);
+    if (database.getSelectedIndex() == -1)
+    {
+      database.setSelectedIndex(0);
+    }
+    database.setMaximumRowCount(database.getItemCount());
+    database.addActionListener(new ActionListener()
+    {
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        String currentSelection = (String) database.getSelectedItem();
+        updateExampleQuery(currentSelection);
+
+        if ("pdb".equalsIgnoreCase(currentSelection))
+        {
+          new PDBFTSPanel(SequenceFetcher.this);
+          frame.dispose();
+        }
+        else if ("uniprot".equalsIgnoreCase(currentSelection))
+        {
+          new UniprotFTSPanel(SequenceFetcher.this);
+          frame.dispose();
+        }
+        else
+        {
+          otherSourceAction();
+        }
+      }
+    });
+
+    exampleAccession = new JLabel("");
+    exampleAccession.setFont(new Font("Verdana", Font.BOLD, 11));
+    JLabel jLabel1 = new JLabel(MessageManager
             .getString("label.separate_multiple_accession_ids"));
+    jLabel1.setFont(new Font("Verdana", Font.ITALIC, 11));
+    jLabel1.setHorizontalAlignment(SwingConstants.CENTER);
 
-    replacePunctuation.setHorizontalAlignment(SwingConstants.CENTER);
-    replacePunctuation
-            .setFont(new java.awt.Font("Verdana", Font.ITALIC, 11));
-    replacePunctuation.setText(
+    replacePunctuation = new JCheckBox(
             MessageManager.getString("label.replace_commas_semicolons"));
-    ok.setText(MessageManager.getString("action.ok"));
-    ok.addActionListener(new ActionListener()
+    replacePunctuation.setHorizontalAlignment(SwingConstants.CENTER);
+    replacePunctuation.setFont(new Font("Verdana", Font.ITALIC, 11));
+    okBtn = new JButton(MessageManager.getString("action.ok"));
+    okBtn.addActionListener(new ActionListener()
     {
       @Override
       public void actionPerformed(ActionEvent e)
@@ -406,7 +222,7 @@ public class SequenceFetcher extends JPanel implements Runnable
         ok_actionPerformed();
       }
     });
-    clear.setText(MessageManager.getString("action.clear"));
+    JButton clear = new JButton(MessageManager.getString("action.clear"));
     clear.addActionListener(new ActionListener()
     {
       @Override
@@ -416,8 +232,8 @@ public class SequenceFetcher extends JPanel implements Runnable
       }
     });
 
-    example.setText(MessageManager.getString("label.example"));
-    example.addActionListener(new ActionListener()
+    exampleBtn = new JButton(MessageManager.getString("label.example"));
+    exampleBtn.addActionListener(new ActionListener()
     {
       @Override
       public void actionPerformed(ActionEvent e)
@@ -425,8 +241,8 @@ public class SequenceFetcher extends JPanel implements Runnable
         example_actionPerformed();
       }
     });
-    close.setText(MessageManager.getString("action.cancel"));
-    close.addActionListener(new ActionListener()
+    closeBtn = new JButton(MessageManager.getString("action.cancel"));
+    closeBtn.addActionListener(new ActionListener()
     {
       @Override
       public void actionPerformed(ActionEvent e)
@@ -434,17 +250,19 @@ public class SequenceFetcher extends JPanel implements Runnable
         close_actionPerformed(e);
       }
     });
-    back.setText(MessageManager.getString("action.back"));
-    back.addActionListener(new ActionListener()
+    backBtn = new JButton(MessageManager.getString("action.back"));
+    backBtn.addActionListener(new ActionListener()
     {
       @Override
       public void actionPerformed(ActionEvent e)
       {
-        parentFTSframe.btn_back_ActionPerformed();
+        parentSearchPanel.btn_back_ActionPerformed();
       }
     });
     // back not visible unless embedded
-    back.setVisible(false);
+    backBtn.setVisible(false);
+
+    textArea = new JTextArea();
     textArea.setFont(JvSwingUtils.getLabelFont());
     textArea.setLineWrap(true);
     textArea.addKeyListener(new KeyAdapter()
@@ -458,99 +276,71 @@ public class SequenceFetcher extends JPanel implements Runnable
         }
       }
     });
-    jPanel3.setLayout(borderLayout1);
-    borderLayout1.setVgap(5);
-    jPanel1.add(back);
-    jPanel1.add(example);
-    jPanel1.add(clear);
-    jPanel1.add(ok);
-    jPanel1.add(close);
-    jPanel2.setLayout(borderLayout3);
-    databaseButt = /*database.getDatabaseSelectorButton();
-                   final JButton viewdbs =*/new JButton(
-            MessageManager.getString("action.select_ddbb"));
-    databaseButt.addActionListener(new ActionListener()
-    {
 
-      @Override
-      public void actionPerformed(ActionEvent arg0)
-      {
-        hidePanel();
-        database.showDialog();
-      }
-    });
-    databaseButt.setFont(JvSwingUtils.getLabelFont());
-    database.addActionListener(new ActionListener()
-    {
-      @Override
-      public void actionPerformed(ActionEvent e)
-      {
-        String currentSelection = database.getSelectedItem();
-        if (currentSelection == null)
-        {
-          close_actionPerformed(null);
-        }
-
-        showPanel();
-
-        if ("pdb".equalsIgnoreCase(currentSelection))
-        {
-          pdbSourceAction();
-        }
-        else if ("uniprot".equalsIgnoreCase(currentSelection))
-        {
-          uniprotSourceAction();
-        }
-        else
-        {
-          otherSourceAction();
-        }
-        database.action = -1;
-      }
-    });
-
-    dbeg.setText("");
-    jPanel2.add(databaseButt, java.awt.BorderLayout.NORTH);
-    jPanel2.add(dbeg, java.awt.BorderLayout.CENTER);
+    JPanel actionPanel = new JPanel();
+    actionPanel.add(backBtn);
+    actionPanel.add(exampleBtn);
+    actionPanel.add(clear);
+    actionPanel.add(okBtn);
+    actionPanel.add(closeBtn);
+
+    JPanel databasePanel = new JPanel();
+    databasePanel.setLayout(new BorderLayout());
+    databasePanel.add(database, BorderLayout.NORTH);
+    databasePanel.add(exampleAccession, BorderLayout.CENTER);
     JPanel jPanel2a = new JPanel(new BorderLayout());
-    jPanel2a.add(jLabel1, java.awt.BorderLayout.NORTH);
-    jPanel2a.add(replacePunctuation, java.awt.BorderLayout.SOUTH);
-    jPanel2.add(jPanel2a, java.awt.BorderLayout.SOUTH);
-    // jPanel2.setPreferredSize(new Dimension())
-    jPanel3.add(jScrollPane1, java.awt.BorderLayout.CENTER);
-    this.add(jPanel1, java.awt.BorderLayout.SOUTH);
-    this.add(jPanel3, java.awt.BorderLayout.CENTER);
-    this.add(jPanel2, java.awt.BorderLayout.NORTH);
+    jPanel2a.add(jLabel1, BorderLayout.NORTH);
+    jPanel2a.add(replacePunctuation, BorderLayout.SOUTH);
+    databasePanel.add(jPanel2a, BorderLayout.SOUTH);
+
+    JPanel idsPanel = new JPanel();
+    idsPanel.setLayout(new BorderLayout(0, 5));
+    JScrollPane jScrollPane1 = new JScrollPane();
     jScrollPane1.getViewport().add(textArea);
-  }
+    idsPanel.add(jScrollPane1, BorderLayout.CENTER);
 
-  private void pdbSourceAction()
-  {
-    databaseButt.setText(database.getSelectedItem());
-    new PDBFTSPanel(this);
-    frame.dispose();
+    this.add(actionPanel, BorderLayout.SOUTH);
+    this.add(idsPanel, BorderLayout.CENTER);
+    this.add(databasePanel, BorderLayout.NORTH);
   }
 
-  private void uniprotSourceAction()
+  /**
+   * Answers a semi-colon-delimited string with the example query or queries for
+   * the selected database
+   * 
+   * @param db
+   * @return
+   */
+  protected String getExampleQueries(String db)
   {
-    databaseButt.setText(database.getSelectedItem());
-    new UniprotFTSPanel(this);
-    frame.dispose();
+    StringBuilder sb = new StringBuilder();
+    HashSet<String> hs = new HashSet<>();
+    for (DbSourceProxy dbs : sfetch.getSourceProxy(db))
+    {
+      String tq = dbs.getTestQuery();
+      if (hs.add(tq)) // not a duplicate source
+      {
+        if (sb.length() > 0)
+        {
+          sb.append(";");
+        }
+        sb.append(tq);
+      }
+    }
+    return sb.toString();
   }
 
-  private void otherSourceAction()
+  /**
+   * Action on selected a database other than Uniprot or PDB is to enable or
+   * disable 'Replace commas', and await input in the query field
+   */
+  protected void otherSourceAction()
   {
     try
     {
-      databaseButt.setText(database.getSelectedItem()
-              + (database.getSelectedSources().size() > 1 ? " (and "
-                      + database.getSelectedSources().size() + " others)"
-                      : ""));
-      String eq = database.getExampleQueries();
-      dbeg.setText(MessageManager.formatMessage("label.example_query_param",
-              new String[]
-              { eq }));
-      // TODO this should be a property of the SequenceFetcher whether commas are and
+      String eq = exampleAccession.getText();
+      // TODO this should be a property of the SequenceFetcher whether commas
+      // are and
       // colons are allowed in the IDs...
 
       boolean enablePunct = !(eq != null && eq.indexOf(",") > -1);
@@ -558,109 +348,121 @@ public class SequenceFetcher extends JPanel implements Runnable
 
     } catch (Exception ex)
     {
-      dbeg.setText("");
+      exampleAccession.setText("");
       replacePunctuation.setEnabled(true);
     }
-    jPanel2.repaint();
+    repaint();
+  }
+
+  /**
+   * Sets the text of the example query to incorporate the example accession
+   * provided by the selected database source
+   * 
+   * @param selectedDatabase
+   * @return
+   */
+  protected String updateExampleQuery(String selectedDatabase)
+  {
+    String eq = getExampleQueries(selectedDatabase);
+    exampleAccession.setText(MessageManager
+            .formatMessage("label.example_query_param", new String[]
+            { eq }));
+    return eq;
   }
 
+  /**
+   * Action on clicking the 'Example' button is to write the example accession
+   * as the query text field value
+   */
   protected void example_actionPerformed()
   {
-    DbSourceProxy db = null;
-    try
-    {
-      textArea.setText(database.getExampleQueries());
-    } catch (Exception ex)
-    {
-    }
-    jPanel3.repaint();
+    String eq = getExampleQueries((String) database.getSelectedItem());
+    textArea.setText(eq);
+    repaint();
   }
 
+  /**
+   * Clears the query input field
+   */
   protected void clear_actionPerformed()
   {
     textArea.setText("");
-    jPanel3.repaint();
+    repaint();
   }
 
-  public void close_actionPerformed(ActionEvent e)
+  /**
+   * Action on Close button is to close this frame, and also (if it is embedded
+   * in a search panel) to close the search panel
+   * 
+   * @param e
+   */
+  protected void close_actionPerformed(ActionEvent e)
   {
     try
     {
       frame.setClosed(true);
-      if (parentFTSframe!=null)
+      if (parentSearchPanel != null)
       {
-        parentFTSframe.btn_cancel_ActionPerformed();
+        parentSearchPanel.btn_cancel_ActionPerformed();
       }
     } catch (Exception ex)
     {
     }
   }
 
+  /**
+   * Action on OK is to start the fetch for entered accession(s)
+   */
   public void ok_actionPerformed()
   {
-    databaseButt.setEnabled(false);
-    example.setEnabled(false);
+    /*
+     * tidy inputs and check there is something to search for
+     */
+    String text = textArea.getText();
+    if (replacePunctuation.isEnabled() && replacePunctuation.isSelected())
+    {
+      text = text.replace(",", ";");
+    }
+    text = text.replaceAll("(\\s|[,; ])+", ";");
+    textArea.setText(text);
+    if (text.isEmpty())
+    {
+      // todo i18n
+      showErrorMessage(
+              "Please enter a (semi-colon separated list of) database id(s)");
+      resetDialog();
+      return;
+    }
+    exampleBtn.setEnabled(false);
     textArea.setEnabled(false);
-    ok.setEnabled(false);
-    close.setEnabled(false);
-    back.setEnabled(false);
+    okBtn.setEnabled(false);
+    closeBtn.setEnabled(false);
+    backBtn.setEnabled(false);
+
     Thread worker = new Thread(this);
     worker.start();
   }
 
   private void resetDialog()
   {
-    databaseButt.setEnabled(true);
-    example.setEnabled(true);
+    exampleBtn.setEnabled(true);
     textArea.setEnabled(true);
-    ok.setEnabled(true);
-    close.setEnabled(true);
-    back.setEnabled(parentFTSframe != null);
+    okBtn.setEnabled(true);
+    closeBtn.setEnabled(true);
+    backBtn.setEnabled(parentSearchPanel != null);
   }
 
   @Override
   public void run()
   {
-    String error = "";
-    if (!database.hasSelection())
-    {
-      error += "Please select the source database\n";
-    }
-    // TODO: make this transformation more configurable
-    com.stevesoft.pat.Regex empty;
-    if (replacePunctuation.isEnabled() && replacePunctuation.isSelected())
-    {
-      empty = new com.stevesoft.pat.Regex(
-              // replace commas and spaces with a semicolon
-              "(\\s|[,; ])+", ";");
-    }
-    else
-    {
-      // just turn spaces and semicolons into single semicolons
-      empty = new com.stevesoft.pat.Regex("(\\s|[; ])+", ";");
-    }
-    textArea.setText(empty.replaceAll(textArea.getText()));
-    // see if there's anthing to search with
-    if (!new com.stevesoft.pat.Regex("[A-Za-z0-9_.]")
-            .search(textArea.getText()))
-    {
-      error += "Please enter a (semi-colon separated list of) database id(s)";
-    }
-    if (error.length() > 0)
-    {
-      showErrorMessage(error);
-      resetDialog();
-      return;
-    }
-    // TODO: Refactor to GUI independent code and write tests.
-    // indicate if successive sources should be merged into one alignment.
     boolean addToLast = false;
     List<String> aresultq = new ArrayList<>();
     List<String> presultTitle = new ArrayList<>();
     List<AlignmentI> presult = new ArrayList<>();
     List<AlignmentI> aresult = new ArrayList<>();
-    Iterator<DbSourceProxy> proxies = database.getSelectedSources()
-            .iterator();
+    List<DbSourceProxy> sources = sfetch
+            .getSourceProxy((String) database.getSelectedItem());
+    Iterator<DbSourceProxy> proxies = sources.iterator();
     String[] qries;
     List<String> nextFetch = Arrays
             .asList(qries = textArea.getText().split(";"));
@@ -1002,10 +804,7 @@ public class SequenceFetcher extends JPanel implements Runnable
                 AlignFrame.DEFAULT_HEIGHT);
         if (currentFileFormat != null)
         {
-          af.currentFileFormat = currentFileFormat; // WHAT IS THE DEFAULT
-          // FORMAT FOR
-          // NON-FormatAdapter Sourced
-          // Alignments?
+          af.currentFileFormat = currentFileFormat;
         }
 
         List<SequenceI> alsqs = al.getSequences();
@@ -1029,10 +828,6 @@ public class SequenceFetcher extends JPanel implements Runnable
         {
           af.hideFeatureColumns(SequenceOntologyI.EXON, false);
         }
-        if (newAlframes != null)
-        {
-          newAlframes.add(af);
-        }
         Desktop.addInternalFrame(af, title, AlignFrame.DEFAULT_WIDTH,
                 AlignFrame.DEFAULT_HEIGHT);
 
@@ -1080,15 +875,6 @@ public class SequenceFetcher extends JPanel implements Runnable
   }
 
   /**
-   * Make this panel visible (after a selection has been made in the database
-   * chooser)
-   */
-  void showPanel()
-  {
-    frame.setVisible(true);
-  }
-
-  /**
    * Hide this panel (on clicking the database button to open the database
    * chooser)
    */
@@ -1097,8 +883,23 @@ public class SequenceFetcher extends JPanel implements Runnable
     frame.setVisible(false);
   }
 
-  public void setDatabaseChooserVisible(boolean b)
+  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
+   * choice has been made), and a Back button is made visible (which reopens the
+   * Sequence Fetcher panel).
+   * 
+   * @param parentPanel
+   */
+  public void embedIn(GFTSPanel parentPanel)
   {
-    databaseButt.setVisible(b);
+    database.setVisible(false);
+    backBtn.setVisible(true);
+    parentSearchPanel = parentPanel;
   }
 }
index 342d95a..4fb5a44 100755 (executable)
@@ -1292,6 +1292,10 @@ public class GAlignFrame extends JInternalFrame
         featureSettings_actionPerformed(e);
       }
     });
+
+    /*
+     * add sub-menu of database we can fetch from
+     */
     JMenuItem fetchSequence = new JMenuItem(
             MessageManager.getString("label.fetch_sequences"));
     fetchSequence.addActionListener(new ActionListener()
@@ -1299,7 +1303,7 @@ public class GAlignFrame extends JInternalFrame
       @Override
       public void actionPerformed(ActionEvent e)
       {
-        fetchSequence_actionPerformed(e);
+        fetchSequence_actionPerformed();
       }
     });
 
@@ -2468,7 +2472,7 @@ public class GAlignFrame extends JInternalFrame
 
   }
 
-  public void fetchSequence_actionPerformed(ActionEvent e)
+  public void fetchSequence_actionPerformed()
   {
 
   }
index 061e70c..3543204 100644 (file)
@@ -134,8 +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(progressIndicatorFrame);
+    sfetcher = jalview.gui.SequenceFetcher.getSequenceFetcherSingleton();
     // set default behaviour for transferring excess sequence data to the
     // dataset
     trimDsSeqs = Cache.getDefault(TRIM_RETRIEVED_SEQUENCES, true);
index 29d4ec7..4526b26 100644 (file)
@@ -33,6 +33,8 @@ import jalview.ws.seqfetcher.ASequenceFetcher;
 import jalview.ws.seqfetcher.DbSourceProxy;
 
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 
 /**
  * This implements the run-time discovery of sequence database clients.
@@ -62,44 +64,30 @@ public class SequenceFetcher extends ASequenceFetcher
   /**
    * return an ordered list of database sources excluding alignment only databases
    */
-  public String[] getOrderedSupportedSources()
+  public String[] getNonAlignmentSources()
   {
     String[] srcs = this.getSupportedDb();
-    ArrayList<String> src = new ArrayList<>();
+    List<String> src = new ArrayList<>();
 
     for (int i = 0; i < srcs.length; i++)
     {
-      boolean skip = false;
+      boolean accept = true;
       for (DbSourceProxy dbs : getSourceProxy(srcs[i]))
       {
         // Skip the alignment databases for the moment - they're not useful for
         // verifying a single sequence against its reference source
         if (dbs.isAlignmentSource())
         {
-          skip = true;
+          accept = false;
+          break;
         }
       }
-      if (skip)
-      {
-        continue;
-      }
+      if (accept)
       {
         src.add(srcs[i]);
       }
     }
-    String[] tosort = src.toArray(new String[0]),
-            sorted = src.toArray(new String[0]);
-    for (int j = 0, jSize = sorted.length; j < jSize; j++)
-    {
-      tosort[j] = tosort[j].toLowerCase();
-    }
-    jalview.util.QuickSort.sort(tosort, sorted);
-    // construct array with all sources listed
-    int i = 0;
-    for (int j = sorted.length - 1; j >= 0; j--, i++)
-    {
-      srcs[i] = sorted[j];
-    }
-    return srcs;
+    Collections.sort(src, String.CASE_INSENSITIVE_ORDER);
+    return src.toArray(new String[src.size()]);
   }
 }
index 2b8a62f..f8157ec 100644 (file)
@@ -31,6 +31,7 @@ import jalview.gui.CrossRefAction;
 import jalview.gui.Desktop;
 import jalview.gui.Jalview2XML;
 import jalview.gui.JvOptionPane;
+import jalview.gui.SequenceFetcher;
 import jalview.util.DBRefUtils;
 
 import java.io.File;
@@ -41,13 +42,13 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import junit.extensions.PA;
-
 import org.testng.Assert;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
+import junit.extensions.PA;
+
 @Test(singleThreaded = true)
 public class CrossRef2xmlTests extends Jalview2xmlBase
 {
@@ -88,9 +89,10 @@ public class CrossRef2xmlTests extends Jalview2xmlBase
     List<String> failedXrefMenuItems = new ArrayList<>();
     List<String> failedProjectRecoveries = new ArrayList<>();
     // only search for ensembl or Uniprot crossrefs
-    List<String> limit=Arrays.asList(new String[] {
-        DBRefUtils.getCanonicalName("ENSEMBL"), 
-        DBRefUtils.getCanonicalName("Uniprot")});
+    List<String> limit = Arrays
+            .asList(new String[]
+            { DBRefUtils.getCanonicalName("ENSEMBL"),
+                DBRefUtils.getCanonicalName("Uniprot") });
     // for every set of db queries
     // retrieve db query
     // verify presence of expected xrefs
@@ -111,326 +113,328 @@ public class CrossRef2xmlTests extends Jalview2xmlBase
     List<String> keyseq = new ArrayList<>();
     Map<String, File> savedProjects = new HashMap<>();
 
-//    for (String[] did : new String[][] { { "UNIPROT", "P00338" } })
-//    {
-      // pass counters - 0 - first pass, 1 means retrieve project rather than
-      // perform action
-      int pass1 = 0, pass2 = 0, pass3 = 0;
-      // each do loop performs two iterations in the first outer loop pass, but
-      // only performs one iteration on the second outer loop
-      // ie. pass 1 = 0 {pass 2= 0 { pass 3 = 0,1 }, pass 2=1 { pass 3 = 0 }}, 1
-      // { pass 2 = 0 { pass 3 = 0 } }
-      do
+    // for (String[] did : new String[][] { { "UNIPROT", "P00338" } })
+    // {
+    // pass counters - 0 - first pass, 1 means retrieve project rather than
+    // perform action
+    int pass1 = 0, pass2 = 0, pass3 = 0;
+    // each do loop performs two iterations in the first outer loop pass, but
+    // only performs one iteration on the second outer loop
+    // ie. pass 1 = 0 {pass 2= 0 { pass 3 = 0,1 }, pass 2=1 { pass 3 = 0 }}, 1
+    // { pass 2 = 0 { pass 3 = 0 } }
+    do
+    {
+      String first = forSource + " " + forAccession;// did[0] + " " + did[1];
+      AlignFrame af = null;
+      boolean dna;
+      AlignmentI retral;
+      AlignmentI dataset;
+      SequenceI[] seqs;
+      List<String> ptypes = null;
+      if (pass1 == 0)
       {
-        String first = forSource + " " + forAccession;//did[0] + " " + did[1];
-        AlignFrame af = null;
-        boolean dna;
-        AlignmentI retral;
-        AlignmentI dataset;
-        SequenceI[] seqs;
-        List<String> ptypes = null;
-        if (pass1 == 0)
-        {
-          // retrieve dbref
+        // retrieve dbref
 
-          List<AlignFrame> afs = jalview.gui.SequenceFetcher.fetchAndShow(
+        SequenceFetcher sf = new SequenceFetcher(Desktop.instance,
                 forSource, forAccession);
-        // did[0], did[1]);
-          if (afs.size() == 0)
-          {
-            failedDBRetr.add("Didn't retrieve " + first);
-            break;
-          }
-          keyseq.add(first);
-          af = afs.get(0);
-
-          // verify references for retrieved data
-          AlignmentTest.assertAlignmentDatasetRefs(af.getViewport()
-                  .getAlignment(), "Pass (" + pass1 + "," + pass2 + ","
-                  + pass3 + "): Fetch " + first + ":");
-          assertDatasetIsNormalisedKnownDefect(af.getViewport()
-                  .getAlignment(), "Pass (" + pass1 + "," + pass2 + ","
-                  + pass3 + "): Fetch " + first + ":");
-          dna = af.getViewport().getAlignment().isNucleotide();
-          retral = af.getViewport().getAlignment();
-          dataset = retral.getDataset();
-          seqs = retral.getSequencesArray();
-
-        }
-        else
+        sf.run();
+        AlignFrame[] afs = Desktop.getAlignFrames();
+        if (afs.length == 0)
         {
-          Desktop.instance.closeAll_actionPerformed(null);
-          // recover stored project
-          af = new FileLoader(false).LoadFileWaitTillLoaded(savedProjects
-                  .get(first).toString(), DataSourceType.FILE);
-          System.out.println("Recovered view for '" + first + "' from '"
-                  + savedProjects.get(first).toString() + "'");
-          dna = af.getViewport().getAlignment().isNucleotide();
-          retral = af.getViewport().getAlignment();
-          dataset = retral.getDataset();
-          seqs = retral.getSequencesArray();
-
-          // verify references for recovered data
-          AlignmentTest.assertAlignmentDatasetRefs(af.getViewport()
-                  .getAlignment(), "Pass (" + pass1 + "," + pass2 + ","
-                  + pass3 + "): Recover " + first + ":");
-          assertDatasetIsNormalisedKnownDefect(af.getViewport()
-                  .getAlignment(), "Pass (" + pass1 + "," + pass2 + ","
-                  + pass3 + "): Recover " + first + ":");
-
+          failedDBRetr.add("Didn't retrieve " + first);
+          break;
         }
+        keyseq.add(first);
+        af = afs[0];
+
+        // verify references for retrieved data
+        AlignmentTest.assertAlignmentDatasetRefs(
+                af.getViewport().getAlignment(), "Pass (" + pass1 + ","
+                        + pass2 + "," + pass3 + "): Fetch " + first + ":");
+        assertDatasetIsNormalisedKnownDefect(
+                af.getViewport().getAlignment(), "Pass (" + pass1 + ","
+                        + pass2 + "," + pass3 + "): Fetch " + first + ":");
+        dna = af.getViewport().getAlignment().isNucleotide();
+        retral = af.getViewport().getAlignment();
+        dataset = retral.getDataset();
+        seqs = retral.getSequencesArray();
 
-        // store project on first pass, compare next pass
-        stringify(dbtoviewBit, savedProjects, first, af.alignPanel);
+      }
+      else
+      {
+        Desktop.instance.closeAll_actionPerformed(null);
+        // recover stored project
+        af = new FileLoader(false).LoadFileWaitTillLoaded(
+                savedProjects.get(first).toString(), DataSourceType.FILE);
+        System.out.println("Recovered view for '" + first + "' from '"
+                + savedProjects.get(first).toString() + "'");
+        dna = af.getViewport().getAlignment().isNucleotide();
+        retral = af.getViewport().getAlignment();
+        dataset = retral.getDataset();
+        seqs = retral.getSequencesArray();
+
+        // verify references for recovered data
+        AlignmentTest.assertAlignmentDatasetRefs(
+                af.getViewport().getAlignment(),
+                "Pass (" + pass1 + "," + pass2 + "," + pass3 + "): Recover "
+                        + first + ":");
+        assertDatasetIsNormalisedKnownDefect(
+                af.getViewport().getAlignment(),
+                "Pass (" + pass1 + "," + pass2 + "," + pass3 + "): Recover "
+                        + first + ":");
 
-        ptypes = (seqs == null || seqs.length == 0) ? null : new CrossRef(
-                seqs, dataset).findXrefSourcesForSequences(dna);
-        filterDbRefs(ptypes, limit);
-        
-        // start of pass2: retrieve each cross-ref for fetched or restored
-        // project.
-        do // first cross ref and recover crossref loop
-        {
+      }
+
+      // store project on first pass, compare next pass
+      stringify(dbtoviewBit, savedProjects, first, af.alignPanel);
+
+      ptypes = (seqs == null || seqs.length == 0) ? null
+              : new CrossRef(seqs, dataset)
+                      .findXrefSourcesForSequences(dna);
+      filterDbRefs(ptypes, limit);
+
+      // start of pass2: retrieve each cross-ref for fetched or restored
+      // project.
+      do // first cross ref and recover crossref loop
+      {
 
-          for (String db : ptypes)
+        for (String db : ptypes)
+        {
+          // counter for splitframe views retrieved via crossref
+          int firstcr_ap = 0;
+          // build next key so we an retrieve all views
+          String nextxref = first + " -> " + db + "{" + firstcr_ap + "}";
+          // perform crossref action, or retrieve stored project
+          List<AlignmentViewPanel> cra_views = new ArrayList<>();
+          CrossRefAction cra = null;
+
+          if (pass2 == 0)
+          { // retrieve and show cross-refs in this thread
+            cra = CrossRefAction.getHandlerFor(seqs, dna, db, af);
+            cra.run();
+            cra_views = (List<AlignmentViewPanel>) PA.getValue(cra,
+                    "xrefViews");
+            if (cra_views.size() == 0)
+            {
+              failedXrefMenuItems.add(
+                      "No crossrefs retrieved for " + first + " -> " + db);
+              continue;
+            }
+            assertNucleotide(cra_views.get(0),
+                    "Nucleotide panel included proteins for " + first
+                            + " -> " + db);
+            assertProtein(cra_views.get(1),
+                    "Protein panel included nucleotides for " + first
+                            + " -> " + db);
+          }
+          else
           {
-            // counter for splitframe views retrieved via crossref
-            int firstcr_ap = 0;
-            // build next key so we an retrieve all views
-            String nextxref = first + " -> " + db + "{" + firstcr_ap + "}";
-            // perform crossref action, or retrieve stored project
-            List<AlignmentViewPanel> cra_views = new ArrayList<>();
-            CrossRefAction cra = null;
-
-            if (pass2 == 0)
-            { // retrieve and show cross-refs in this thread
-              cra = CrossRefAction.getHandlerFor(seqs, dna, db, af);
-              cra.run();
-              cra_views = (List<AlignmentViewPanel>) PA.getValue(cra,
-                      "xrefViews");
-              if (cra_views.size() == 0)
-              {
-                failedXrefMenuItems.add("No crossrefs retrieved for "
-                        + first + " -> " + db);
-                continue;
-              }
-              assertNucleotide(cra_views.get(0),
-                      "Nucleotide panel included proteins for " + first
-                              + " -> " + db);
-              assertProtein(cra_views.get(1),
-                      "Protein panel included nucleotides for " + first
-                              + " -> " + db);
+            Desktop.instance.closeAll_actionPerformed(null);
+            pass3 = 0;
+            // recover stored project
+            File storedProject = savedProjects.get(nextxref);
+            if (storedProject == null)
+            {
+              failedProjectRecoveries
+                      .add("Failed to store a view for '" + nextxref + "'");
+              continue;
             }
-            else
+
+            // recover stored project
+            AlignFrame af2 = new FileLoader(false).LoadFileWaitTillLoaded(
+                    savedProjects.get(nextxref).toString(),
+                    DataSourceType.FILE);
+            System.out
+                    .println("Recovered view for '" + nextxref + "' from '"
+                            + savedProjects.get(nextxref).toString() + "'");
+            // gymnastics to recover the alignPanel/Complementary alignPanel
+            if (af2.getViewport().isNucleotide())
             {
-              Desktop.instance.closeAll_actionPerformed(null);
-              pass3 = 0;
-              // recover stored project
-              File storedProject = savedProjects.get(nextxref);
-              if (storedProject == null)
-              {
-                failedProjectRecoveries.add("Failed to store a view for '"
-                        + nextxref + "'");
-                continue;
-              }
-
-              // recover stored project
-              AlignFrame af2 = new FileLoader(false)
-                      .LoadFileWaitTillLoaded(savedProjects.get(nextxref)
-                              .toString(), DataSourceType.FILE);
-              System.out.println("Recovered view for '" + nextxref
-                      + "' from '" + savedProjects.get(nextxref).toString()
-                      + "'");
-              // gymnastics to recover the alignPanel/Complementary alignPanel
-              if (af2.getViewport().isNucleotide())
-              {
-                // top view, then bottom
-                cra_views.add(af2.getViewport().getAlignPanel());
-                cra_views.add(((jalview.gui.AlignViewport) af2
-                        .getViewport().getCodingComplement())
-                        .getAlignPanel());
-
-              }
-              else
-              {
-                // bottom view, then top
-                cra_views.add(((jalview.gui.AlignViewport) af2
-                        .getViewport().getCodingComplement())
-                        .getAlignPanel());
-                cra_views.add(af2.getViewport().getAlignPanel());
+              // top view, then bottom
+              cra_views.add(af2.getViewport().getAlignPanel());
+              cra_views.add(((jalview.gui.AlignViewport) af2.getViewport()
+                      .getCodingComplement()).getAlignPanel());
 
-              }
             }
-            HashMap<String, List<String>> xrptypes = new HashMap<>();
-            // first save/verify views.
-            for (AlignmentViewPanel avp : cra_views)
+            else
             {
-              nextxref = first + " -> " + db + "{" + firstcr_ap++ + "}";
-              // verify references for this panel
-              AlignmentTest.assertAlignmentDatasetRefs(avp.getAlignment(),
-                      "Pass (" + pass1 + "," + pass2 + "," + pass3
-                              + "): before start of pass3: " + nextxref
-                              + ":");
-              assertDatasetIsNormalisedKnownDefect(avp.getAlignment(),
-                      "Pass (" + pass1 + "," + pass2 + "," + pass3
-                              + "): before start of pass3: " + nextxref
-                              + ":");
-
-              SequenceI[] xrseqs = avp.getAlignment().getSequencesArray();
-
-              List<String> _xrptypes = (seqs == null || seqs.length == 0) ? null
-                      : new CrossRef(xrseqs, dataset)
-                              .findXrefSourcesForSequences(avp
-                                      .getAlignViewport().isNucleotide());
-
-              stringify(dbtoviewBit, savedProjects, nextxref, avp);
-              xrptypes.put(nextxref, _xrptypes);
+              // bottom view, then top
+              cra_views.add(((jalview.gui.AlignViewport) af2.getViewport()
+                      .getCodingComplement()).getAlignPanel());
+              cra_views.add(af2.getViewport().getAlignPanel());
 
             }
+          }
+          HashMap<String, List<String>> xrptypes = new HashMap<>();
+          // first save/verify views.
+          for (AlignmentViewPanel avp : cra_views)
+          {
+            nextxref = first + " -> " + db + "{" + firstcr_ap++ + "}";
+            // verify references for this panel
+            AlignmentTest.assertAlignmentDatasetRefs(avp.getAlignment(),
+                    "Pass (" + pass1 + "," + pass2 + "," + pass3
+                            + "): before start of pass3: " + nextxref
+                            + ":");
+            assertDatasetIsNormalisedKnownDefect(avp.getAlignment(),
+                    "Pass (" + pass1 + "," + pass2 + "," + pass3
+                            + "): before start of pass3: " + nextxref
+                            + ":");
+
+            SequenceI[] xrseqs = avp.getAlignment().getSequencesArray();
+
+            List<String> _xrptypes = (seqs == null || seqs.length == 0)
+                    ? null
+                    : new CrossRef(xrseqs, dataset)
+                            .findXrefSourcesForSequences(
+                                    avp.getAlignViewport().isNucleotide());
+
+            stringify(dbtoviewBit, savedProjects, nextxref, avp);
+            xrptypes.put(nextxref, _xrptypes);
+
+          }
 
-            // now do the second xref pass starting from either saved or just
-            // recovered split pane, in sequence
-            do // retrieve second set of cross refs or recover and verify
+          // now do the second xref pass starting from either saved or just
+          // recovered split pane, in sequence
+          do // retrieve second set of cross refs or recover and verify
+          {
+            firstcr_ap = 0;
+            for (AlignmentViewPanel avp : cra_views)
             {
-              firstcr_ap = 0;
-              for (AlignmentViewPanel avp : cra_views)
+              nextxref = first + " -> " + db + "{" + firstcr_ap++ + "}";
+              for (String xrefdb : xrptypes.get(nextxref))
               {
-                nextxref = first + " -> " + db + "{" + firstcr_ap++ + "}";
-                for (String xrefdb : xrptypes.get(nextxref))
-                {
-                  List<AlignmentViewPanel> cra_views2 = new ArrayList<>();
-                  int q = 0;
-                  String nextnextxref = nextxref + " -> " + xrefdb + "{"
-                          + q + "}";
+                List<AlignmentViewPanel> cra_views2 = new ArrayList<>();
+                int q = 0;
+                String nextnextxref = nextxref + " -> " + xrefdb + "{" + q
+                        + "}";
 
-                  if (pass3 == 0)
+                if (pass3 == 0)
+                {
+                  SequenceI[] xrseqs = avp.getAlignment()
+                          .getSequencesArray();
+                  AlignFrame nextaf = Desktop
+                          .getAlignFrameFor(avp.getAlignViewport());
+
+                  cra = CrossRefAction.getHandlerFor(xrseqs,
+                          avp.getAlignViewport().isNucleotide(), xrefdb,
+                          nextaf);
+                  cra.run();
+                  cra_views2 = (List<AlignmentViewPanel>) PA.getValue(cra,
+                          "xrefViews");
+                  if (cra_views2.size() == 0)
                   {
-                    SequenceI[] xrseqs = avp.getAlignment()
-                            .getSequencesArray();
-                    AlignFrame nextaf = Desktop.getAlignFrameFor(avp
-                            .getAlignViewport());
-
-                    cra = CrossRefAction.getHandlerFor(xrseqs, avp
-                            .getAlignViewport().isNucleotide(), xrefdb,
-                            nextaf);
-                    cra.run();
-                    cra_views2 = (List<AlignmentViewPanel>) PA.getValue(
-                            cra, "xrefViews");
-                    if (cra_views2.size() == 0)
-                    {
-                      failedXrefMenuItems
-                              .add("No crossrefs retrieved for '"
-                                      + nextxref + "' to " + xrefdb
-                                      + " via '" + nextaf.getTitle() + "'");
-                      continue;
-                    }
-                    assertNucleotide(cra_views2.get(0),
-                            "Nucleotide panel included proteins for '"
-                                    + nextxref + "' to " + xrefdb
-                                    + " via '" + nextaf.getTitle() + "'");
-                    assertProtein(cra_views2.get(1),
-                            "Protein panel included nucleotides for '"
-                                    + nextxref + "' to " + xrefdb
-                                    + " via '" + nextaf.getTitle() + "'");
-
+                    failedXrefMenuItems.add("No crossrefs retrieved for '"
+                            + nextxref + "' to " + xrefdb + " via '"
+                            + nextaf.getTitle() + "'");
+                    continue;
                   }
-                  else
+                  assertNucleotide(cra_views2.get(0),
+                          "Nucleotide panel included proteins for '"
+                                  + nextxref + "' to " + xrefdb + " via '"
+                                  + nextaf.getTitle() + "'");
+                  assertProtein(cra_views2.get(1),
+                          "Protein panel included nucleotides for '"
+                                  + nextxref + "' to " + xrefdb + " via '"
+                                  + nextaf.getTitle() + "'");
+
+                }
+                else
+                {
+                  Desktop.instance.closeAll_actionPerformed(null);
+                  // recover stored project
+                  File storedProject = savedProjects.get(nextnextxref);
+                  if (storedProject == null)
                   {
-                    Desktop.instance.closeAll_actionPerformed(null);
-                    // recover stored project
-                    File storedProject = savedProjects.get(nextnextxref);
-                    if (storedProject == null)
-                    {
-                      failedProjectRecoveries
-                              .add("Failed to store a view for '"
-                                      + nextnextxref + "'");
-                      continue;
-                    }
-                    AlignFrame af2 = new FileLoader(false)
-                            .LoadFileWaitTillLoaded(
-                                    savedProjects.get(nextnextxref)
-                                            .toString(),
-                                    DataSourceType.FILE);
-                    System.out.println("Recovered view for '"
-                            + nextnextxref + "' from '"
-                            + savedProjects.get(nextnextxref).toString()
-                            + "'");
-                    // gymnastics to recover the alignPanel/Complementary
-                    // alignPanel
-                    if (af2.getViewport().isNucleotide())
-                    {
-                      // top view, then bottom
-                      cra_views2.add(af2.getViewport().getAlignPanel());
-                      cra_views2.add(((jalview.gui.AlignViewport) af2
-                              .getViewport().getCodingComplement())
-                              .getAlignPanel());
-
-                    }
-                    else
-                    {
-                      // bottom view, then top
-                      cra_views2.add(((jalview.gui.AlignViewport) af2
-                              .getViewport().getCodingComplement())
-                              .getAlignPanel());
-                      cra_views2.add(af2.getViewport().getAlignPanel());
-                    }
-                    Assert.assertEquals(cra_views2.size(), 2);
-                    Assert.assertNotNull(cra_views2.get(0));
-                    Assert.assertNotNull(cra_views2.get(1));
+                    failedProjectRecoveries
+                            .add("Failed to store a view for '"
+                                    + nextnextxref + "'");
+                    continue;
                   }
+                  AlignFrame af2 = new FileLoader(false)
+                          .LoadFileWaitTillLoaded(savedProjects
+                                  .get(nextnextxref).toString(),
+                                  DataSourceType.FILE);
+                  System.out
+                          .println("Recovered view for '" + nextnextxref
+                                  + "' from '" + savedProjects
+                                          .get(nextnextxref).toString()
+                                  + "'");
+                  // gymnastics to recover the alignPanel/Complementary
+                  // alignPanel
+                  if (af2.getViewport().isNucleotide())
+                  {
+                    // top view, then bottom
+                    cra_views2.add(af2.getViewport().getAlignPanel());
+                    cra_views2.add(((jalview.gui.AlignViewport) af2
+                            .getViewport().getCodingComplement())
+                                    .getAlignPanel());
 
-                  for (AlignmentViewPanel nextavp : cra_views2)
+                  }
+                  else
                   {
-                    nextnextxref = nextxref + " -> " + xrefdb + "{" + q++
-                            + "}";
-
-                    // verify references for this panel
-                    AlignmentTest.assertAlignmentDatasetRefs(
-                            nextavp.getAlignment(), "" + "Pass (" + pass1
-                                    + "," + pass2 + "): For "
-                                    + nextnextxref + ":");
-                    assertDatasetIsNormalisedKnownDefect(
-                            nextavp.getAlignment(), "" + "Pass (" + pass1
-                                    + "," + pass2 + "): For "
-                                    + nextnextxref + ":");
-
-                    stringify(dbtoviewBit, savedProjects, nextnextxref,
-                            nextavp);
-                    keyseq.add(nextnextxref);
+                    // bottom view, then top
+                    cra_views2.add(((jalview.gui.AlignViewport) af2
+                            .getViewport().getCodingComplement())
+                                    .getAlignPanel());
+                    cra_views2.add(af2.getViewport().getAlignPanel());
                   }
-                } // end of loop around showing all xrefdb for crossrf2
-
-              } // end of loop around all viewpanels from crossrf1
-            } while (pass2 == 2 && pass3++ < 2);
-            // fetchdb->crossref1->crossref-2->verify for xrefs we
-            // either loop twice when pass2=0, or just once when pass2=1
-            // (recovered project from previous crossref)
-
-          } // end of loop over db-xrefs for crossref-2
-
-          // fetchdb-->crossref1
-          // for each xref we try to retrieve xref, store and verify when
-          // pass1=0, or just retrieve and verify when pass1=1
-        } while (pass1 == 1 && pass2++ < 2);
-        // fetchdb
-        // for each ref we
-        // loop twice: first, do the retrieve, second recover from saved project
-
-        // increment pass counters, so we repeat traversal starting from the
-        // oldest saved project first.
-        if (pass1 == 0)
-        {
-          // verify stored projects for first set of cross references
-          pass1 = 1;
-          // and verify cross-references retrieved from stored projects
-          pass2 = 0;
-          pass3 = 0;
-        }
-        else
-        {
-          pass1++;
-        }
-      } while (pass1 < 3);
+                  Assert.assertEquals(cra_views2.size(), 2);
+                  Assert.assertNotNull(cra_views2.get(0));
+                  Assert.assertNotNull(cra_views2.get(1));
+                }
+
+                for (AlignmentViewPanel nextavp : cra_views2)
+                {
+                  nextnextxref = nextxref + " -> " + xrefdb + "{" + q++
+                          + "}";
+
+                  // verify references for this panel
+                  AlignmentTest.assertAlignmentDatasetRefs(
+                          nextavp.getAlignment(),
+                          "" + "Pass (" + pass1 + "," + pass2 + "): For "
+                                  + nextnextxref + ":");
+                  assertDatasetIsNormalisedKnownDefect(
+                          nextavp.getAlignment(),
+                          "" + "Pass (" + pass1 + "," + pass2 + "): For "
+                                  + nextnextxref + ":");
+
+                  stringify(dbtoviewBit, savedProjects, nextnextxref,
+                          nextavp);
+                  keyseq.add(nextnextxref);
+                }
+              } // end of loop around showing all xrefdb for crossrf2
+
+            } // end of loop around all viewpanels from crossrf1
+          } while (pass2 == 2 && pass3++ < 2);
+          // fetchdb->crossref1->crossref-2->verify for xrefs we
+          // either loop twice when pass2=0, or just once when pass2=1
+          // (recovered project from previous crossref)
+
+        } // end of loop over db-xrefs for crossref-2
+
+        // fetchdb-->crossref1
+        // for each xref we try to retrieve xref, store and verify when
+        // pass1=0, or just retrieve and verify when pass1=1
+      } while (pass1 == 1 && pass2++ < 2);
+      // fetchdb
+      // for each ref we
+      // loop twice: first, do the retrieve, second recover from saved project
+
+      // increment pass counters, so we repeat traversal starting from the
+      // oldest saved project first.
+      if (pass1 == 0)
+      {
+        // verify stored projects for first set of cross references
+        pass1 = 1;
+        // and verify cross-references retrieved from stored projects
+        pass2 = 0;
+        pass3 = 0;
+      }
+      else
+      {
+        pass1++;
+      }
+    } while (pass1 < 3);
 
     if (failedXrefMenuItems.size() > 0)
     {
@@ -448,8 +452,9 @@ public class CrossRef2xmlTests extends Jalview2xmlBase
       {
         System.err.println(s);
       }
-      Assert.fail("Didn't recover projects for some retrievals (did they retrieve ?) ("
-              + failedProjectRecoveries.size() + " counts)");
+      Assert.fail(
+              "Didn't recover projects for some retrievals (did they retrieve ?) ("
+                      + failedProjectRecoveries.size() + " counts)");
     }
     if (failedDBRetr.size() > 0)
     {
@@ -501,9 +506,8 @@ public class CrossRef2xmlTests extends Jalview2xmlBase
       }
       else
       {
-        System.out
-                .println("Ignored exception for known defect: JAL-2179 : "
-                        + message);
+        System.out.println("Ignored exception for known defect: JAL-2179 : "
+                + message);
       }
 
     }
@@ -525,8 +529,8 @@ public class CrossRef2xmlTests extends Jalview2xmlBase
           AlignmentViewPanel alignmentViewPanel, String message)
   {
     List<SequenceI> nonType = new ArrayList<>();
-    for (SequenceI sq : alignmentViewPanel.getAlignViewport()
-            .getAlignment().getSequences())
+    for (SequenceI sq : alignmentViewPanel.getAlignViewport().getAlignment()
+            .getSequences())
     {
       if (sq.isProtein() != expectProtein)
       {
@@ -621,8 +625,8 @@ public class CrossRef2xmlTests extends Jalview2xmlBase
     }
     else
     {
-      Assert.assertEquals(sbr.toString(), dbt, "stringify mismatch for "
-              + xrefpath);
+      Assert.assertEquals(sbr.toString(), dbt,
+              "stringify mismatch for " + xrefpath);
     }
   }
 }
index d8fb401..989d13d 100644 (file)
@@ -6,7 +6,7 @@ import java.awt.Dimension;
 import java.awt.Font;
 import java.awt.GridLayout;
 import java.awt.MediaTracker;
-import java.awt.MenuItem;
+import java.text.DecimalFormat;
 
 import javax.swing.ImageIcon;
 import javax.swing.JButton;
@@ -40,6 +40,7 @@ public class JalviewJSTest extends JPanel
    */
   void doTest()
   {
+    new DecimalFormat("###,###").format((Integer) 1);
     JFrame main = new JFrame();
     main.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
     JMenu menu = new JMenu("testing");