JAL-3829 3d-beacons structure chooser logic (not yet finished)
authorJim Procter <j.procter@dundee.ac.uk>
Thu, 26 Aug 2021 13:56:05 +0000 (14:56 +0100)
committerJim Procter <j.procter@dundee.ac.uk>
Mon, 30 Aug 2021 11:17:32 +0000 (12:17 +0100)
src/jalview/datamodel/PDBEntry.java
src/jalview/fts/api/FTSRestClientI.java
src/jalview/fts/core/FTSDataColumnPreferences.java
src/jalview/fts/core/FTSRestClient.java
src/jalview/fts/service/pdb/PDBFTSRestClient.java
src/jalview/fts/service/threedbeacons/TDBeaconsFTSRestClient.java
src/jalview/gui/StructureChooser.java
src/jalview/gui/StructureChooserQuerySource.java [deleted file]
src/jalview/gui/structurechooser/StructureChooserQuerySource.java [new file with mode: 0644]
test/jalview/gui/StructureChooserTest.java

index c1dc77c..1edc94b 100755 (executable)
@@ -460,4 +460,21 @@ public class PDBEntry
     }
     return true;
   }
+  
+
+  /**
+   * Permanent URI for retrieving the original structure data
+   * @param urlStr
+   */
+  public void setRetrievalUrl(String urlStr)
+  {
+    setProperty("RETRIEVE_FROM", urlStr);
+  }
+  /**
+   * get the Permanent URI for retrieving the original structure data
+   */
+  public String getRetrievalUrl()
+  {
+    return (String) getProperty("RETRIEVE_FROM");
+  }
 }
index 84d8e0d..31d5c7c 100644 (file)
@@ -22,6 +22,7 @@
 package jalview.fts.api;
 
 import jalview.fts.api.FTSDataColumnI.FTSDataColumnGroupI;
+import jalview.fts.core.FTSDataColumnPreferences.PreferenceSource;
 import jalview.fts.core.FTSRestRequest;
 import jalview.fts.core.FTSRestResponse;
 
@@ -136,4 +137,6 @@ public interface FTSRestClientI
    * @return the default response page size
    */
   public int getDefaultResponsePageSize();
+
+  public String[] getPreferencesColumnsFor(PreferenceSource source);
 }
index c0b6d05..0335d65 100644 (file)
@@ -23,6 +23,7 @@ package jalview.fts.core;
 import jalview.fts.api.FTSDataColumnI;
 import jalview.fts.api.FTSDataColumnI.FTSDataColumnGroupI;
 import jalview.fts.api.FTSRestClientI;
+import jalview.fts.api.StructureFTSRestClientI;
 import jalview.fts.service.pdb.PDBFTSRestClient;
 
 import java.util.ArrayList;
@@ -76,7 +77,7 @@ public class FTSDataColumnPreferences extends JScrollPane
     if (source.equals(PreferenceSource.STRUCTURE_CHOOSER)
             || source.equals(PreferenceSource.PREFERENCES))
     {
-      structSummaryColumns = ((PDBFTSRestClient) ftsRestClient)
+      structSummaryColumns = ((StructureFTSRestClientI) ftsRestClient)
               .getAllDefaultDisplayedStructureDataColumns();
     }
     allFTSDataColumns.addAll(ftsRestClient.getAllFTSDataColumns());
@@ -85,22 +86,7 @@ public class FTSDataColumnPreferences extends JScrollPane
     this.getViewport().add(tbl_FTSDataColumnPrefs);
     this.currentSource = source;
 
-    String[] columnNames = null;
-    switch (source)
-    {
-    case SEARCH_SUMMARY:
-      columnNames = new String[] { "", "Display", "Group" };
-      break;
-    case STRUCTURE_CHOOSER:
-      columnNames = new String[] { "", "Display", "Group" };
-      break;
-    case PREFERENCES:
-      columnNames = new String[] { "PDB Field", "Show in search summary",
-          "Show in structure summary" };
-      break;
-    default:
-      break;
-    }
+    String[] columnNames = ftsRestClient.getPreferencesColumnsFor(source);
 
     Object[][] data = new Object[allFTSDataColumns.size()][3];
 
index 7a8a695..f651707 100644 (file)
@@ -30,6 +30,7 @@ import java.util.Objects;
 
 import jalview.fts.api.FTSDataColumnI;
 import jalview.fts.api.FTSDataColumnI.FTSDataColumnGroupI;
+import jalview.fts.core.FTSDataColumnPreferences.PreferenceSource;
 import jalview.fts.api.FTSRestClientI;
 
 /**
@@ -504,4 +505,19 @@ public abstract class FTSRestClient implements FTSRestClientI
     return defaultResponsePageSize;
   }
 
+  @Override
+  public String[] getPreferencesColumnsFor(PreferenceSource source)
+  {
+    String[] columnNames = null;
+    switch (source)
+    {
+    case SEARCH_SUMMARY:
+      columnNames = new String[] { "", "Display", "Group" };
+      break;
+    default:
+      // non structure sources don't return any other kind of preferences columns
+      break;
+    }
+    return columnNames;
+  }
 }
index dc7fe41..313f0b6 100644 (file)
@@ -41,6 +41,9 @@ import jalview.datamodel.SequenceI;
 import jalview.fts.api.FTSData;
 import jalview.fts.api.FTSDataColumnI;
 import jalview.fts.api.FTSRestClientI;
+import jalview.fts.api.StructureFTSRestClientI;
+import jalview.fts.core.FTSDataColumnPreferences;
+import jalview.fts.core.FTSDataColumnPreferences.PreferenceSource;
 import jalview.fts.core.FTSRestClient;
 import jalview.fts.core.FTSRestRequest;
 import jalview.fts.core.FTSRestResponse;
@@ -53,7 +56,7 @@ import jalview.util.Platform;
  * 
  * @author tcnofoegbu
  */
-public class PDBFTSRestClient extends FTSRestClient
+public class PDBFTSRestClient extends FTSRestClient implements StructureFTSRestClientI
 {
 
   private static FTSRestClientI instance = null;
@@ -470,7 +473,7 @@ public static String parseJsonExceptionString(String jsonErrorResponse)
   }
 
   private Collection<FTSDataColumnI> allDefaultDisplayedStructureDataColumns;
-
+  @Override
   public Collection<FTSDataColumnI> getAllDefaultDisplayedStructureDataColumns()
   {
     if (allDefaultDisplayedStructureDataColumns == null
@@ -482,6 +485,24 @@ public static String parseJsonExceptionString(String jsonErrorResponse)
     }
     return allDefaultDisplayedStructureDataColumns;
   }
-  
-  
+  @Override
+  public String[] getPreferencesColumnsFor(PreferenceSource source) {
+    String[] columnNames = null;
+    switch (source)
+    {
+    case SEARCH_SUMMARY:
+      columnNames = new String[] { "", "Display", "Group" };
+      break;
+    case STRUCTURE_CHOOSER:
+      columnNames = new String[] { "", "Display", "Group" };
+      break;
+    case PREFERENCES:
+      columnNames = new String[] { "PDB Field", "Show in search summary",
+          "Show in structure summary" };
+      break;
+    default:
+      break;
+    }
+    return columnNames;
+  }
 }
index e956461..a57cf3b 100644 (file)
@@ -21,25 +21,27 @@ import jalview.datamodel.SequenceI;
 import jalview.fts.api.FTSData;
 import jalview.fts.api.FTSDataColumnI;
 import jalview.fts.api.FTSRestClientI;
+import jalview.fts.api.StructureFTSRestClientI;
 import jalview.fts.core.FTSRestClient;
 import jalview.fts.core.FTSRestRequest;
 import jalview.fts.core.FTSRestResponse;
+import jalview.fts.core.FTSDataColumnPreferences.PreferenceSource;
 import jalview.fts.service.pdb.PDBFTSRestClient;
 import jalview.util.JSONUtils;
 import jalview.util.MessageManager;
 import jalview.util.Platform;
 
 public class TDBeaconsFTSRestClient extends FTSRestClient
+        implements StructureFTSRestClientI
 {
-  private static final String DEFAULT_THREEDBEACONS_DOMAIN = 
-          "https://wwwdev.ebi.ac.uk/pdbe/pdbe-kb/3dbeacons/api/uniprot/summary/";
-  
+  private static final String DEFAULT_THREEDBEACONS_DOMAIN = "https://wwwdev.ebi.ac.uk/pdbe/pdbe-kb/3dbeacons/api/uniprot/summary/";
+
   private static FTSRestClientI instance = null;
-  
+
   protected TDBeaconsFTSRestClient()
-  {   
+  {
   }
-  
+
   @SuppressWarnings("unchecked")
   @Override
   public FTSRestResponse executeRequest(FTSRestRequest tdbRestRequest)
@@ -59,6 +61,7 @@ public class TDBeaconsFTSRestClient extends FTSRestClient
       else
       /**
        * Java only
+       * 
        * @j2sIgnore
        */
       {
@@ -70,16 +73,16 @@ public class TDBeaconsFTSRestClient extends FTSRestClient
               .path(query);
       URI uri = webResource.getURI();
       System.out.println(uri.toString());
-        
+
       // Execute the REST request
       ClientResponse clientResponse = webResource
               .accept(MediaType.APPLICATION_JSON).get(clientResponseClass);
-  
+
       // Get the JSON string from the response object or directly from the
       // client (JavaScript)
       Map<String, Object> jsonObj = null;
       String responseString = null;
-  
+
       // Check the response status and report exception if one occurs
       int responseStatus = clientResponse.getStatus();
       switch (responseStatus)
@@ -102,7 +105,8 @@ public class TDBeaconsFTSRestClient extends FTSRestClient
                 getMessageByHTTPStatusCode(responseStatus, "3DBeacons"));
       }
       // Process the response and return the result to the caller.
-      return parseTDBeaconsJsonResponse(responseString, jsonObj, tdbRestRequest);
+      return parseTDBeaconsJsonResponse(responseString, jsonObj,
+              tdbRestRequest);
     } catch (Exception e)
     {
       String exceptionMsg = e.getMessage();
@@ -123,52 +127,59 @@ public class TDBeaconsFTSRestClient extends FTSRestClient
         throw e;
       }
     }
-      
+
   }
-  
-  public String setSearchTerm(String term) {
+
+  public String setSearchTerm(String term)
+  {
     return term;
   }
-  
+
   public static FTSRestResponse parseTDBeaconsJsonResponse(
           String tdbJsonResponseString, FTSRestRequest tdbRestRequest)
   {
     return parseTDBeaconsJsonResponse(tdbJsonResponseString,
             (Map<String, Object>) null, tdbRestRequest);
   }
-  
+
   @SuppressWarnings("unchecked")
-  public static FTSRestResponse parseTDBeaconsJsonResponse(String tdbJsonResponseString,
-          Map<String, Object> jsonObj, FTSRestRequest tdbRestRequest)
+  public static FTSRestResponse parseTDBeaconsJsonResponse(
+          String tdbJsonResponseString, Map<String, Object> jsonObj,
+          FTSRestRequest tdbRestRequest)
   {
     FTSRestResponse searchResult = new FTSRestResponse();
     List<FTSData> result = null;
-    
+
     try
     {
       if (jsonObj == null)
       {
-        jsonObj = (Map<String, Object>) JSONUtils.parse(tdbJsonResponseString);
+        jsonObj = (Map<String, Object>) JSONUtils
+                .parse(tdbJsonResponseString);
       }
-      
-      Object uniprot_entry = jsonObj.get("uniprot_entry"); 
-      // TODO: decide if anything from uniprot_entry needs to be reported via the FTSRestResponse object
-      // Arnaud added seqLength = (Long) ((Map<String, Object>) jsonObj.get("uniprot_entry")).get("sequence_length");
+
+      Object uniprot_entry = jsonObj.get("uniprot_entry");
+      // TODO: decide if anything from uniprot_entry needs to be reported via
+      // the FTSRestResponse object
+      // Arnaud added seqLength = (Long) ((Map<String, Object>)
+      // jsonObj.get("uniprot_entry")).get("sequence_length");
 
       List<Object> structures = (List<Object>) jsonObj.get("structures");
       result = new ArrayList<>();
-      
+
       int numFound = 0;
-      for (Iterator<Object> strucIter = structures.iterator(); strucIter.hasNext();)
+      for (Iterator<Object> strucIter = structures.iterator(); strucIter
+              .hasNext();)
       {
-        Map<String, Object> structure = (Map<String, Object>) strucIter.next();
+        Map<String, Object> structure = (Map<String, Object>) strucIter
+                .next();
         result.add(getFTSData(structure, tdbRestRequest));
         numFound++;
       }
-      
-      searchResult.setNumberOfItemsFound(numFound); 
+
+      searchResult.setNumberOfItemsFound(numFound);
       searchResult.setSearchSummary(result);
-        
+
     } catch (ParseException e)
     {
       e.printStackTrace();
@@ -176,20 +187,35 @@ public class TDBeaconsFTSRestClient extends FTSRestClient
     return searchResult;
   }
 
-private static FTSData getFTSData(Map<String, Object> tdbJsonStructure,
+  private static FTSData getFTSData(Map<String, Object> tdbJsonStructure,
           FTSRestRequest tdbRequest)
   {
-    // TODO Auto-generated method stub
+    // TODO: consider reusing PDBFTSRestClient.getFTSData ?
+
     String primaryKey = null;
     Object[] summaryRowData;
+
+    SequenceI associatedSequence;
+
     Collection<FTSDataColumnI> displayFields = tdbRequest.getWantedFields();
+    SequenceI associatedSeq = tdbRequest.getAssociatedSequence();
     int colCounter = 0;
-    summaryRowData = new Object[displayFields.size()];
-    
-    for (FTSDataColumnI field : displayFields) {
-      String fieldData = (tdbJsonStructure.get(field.getCode()) == null) ? " " 
+    summaryRowData = new Object[(associatedSeq != null)
+                                ? displayFields.size() + 1
+                                : displayFields.size()];
+                        if (associatedSeq != null)
+                        {
+                          associatedSequence = associatedSeq;
+                          summaryRowData[0] = associatedSequence;
+                          colCounter = 1;
+                        }
+
+    for (FTSDataColumnI field : displayFields)
+    {
+      String fieldData = (tdbJsonStructure.get(field.getCode()) == null)
+              ? " "
               : tdbJsonStructure.get(field.getCode()).toString();
-      // System.out.println("Field : " + field + "  Data : " + fieldData);
+      // System.out.println("Field : " + field + " Data : " + fieldData);
       if (field.isPrimaryKeyColumn())
       {
         primaryKey = fieldData;
@@ -199,7 +225,7 @@ private static FTSData getFTSData(Map<String, Object> tdbJsonStructure,
       {
         summaryRowData[colCounter++] = null;
       }
-      else 
+      else
       {
         try
         {
@@ -212,14 +238,14 @@ private static FTSData getFTSData(Map<String, Object> tdbJsonStructure,
                                           : fieldData;
         } catch (Exception e)
         {
-          //e.printStackTrace();
+          // e.printStackTrace();
           System.out.println("offending value:" + fieldData + fieldData);
         }
       }
     }
     final String primaryKey1 = primaryKey;
     final Object[] summaryRowData1 = summaryRowData;
-    
+
     return new FTSData()
     {
 
@@ -234,7 +260,7 @@ private static FTSData getFTSData(Map<String, Object> tdbJsonStructure,
       {
         return primaryKey1;
       }
-      
+
       /**
        * Returns a string representation of this object;
        */
@@ -250,7 +276,7 @@ private static FTSData getFTSData(Map<String, Object> tdbJsonStructure,
         }
         return summaryFieldValues.toString();
       }
-      
+
       /**
        * Returns hash code value for this object
        */
@@ -268,19 +294,20 @@ private static FTSData getFTSData(Map<String, Object> tdbJsonStructure,
     };
   }
 
-//  private static FTSData getFTSData(Map<String, Object> doc,
-//          FTSRestRequest tdbRestRequest)
-//  {
-//    String primaryKey = null;
-//
-//    Object[] summaryRowData;
-//
-//    Collection<FTSDataColumnI> displayFields = tdbRestRequest.getWantedFields();
-//    int colCounter = 0;
-//    summaryRowData = new Object[displayFields.size() + 1];
-// 
-//    return null;
-//  }
+  // private static FTSData getFTSData(Map<String, Object> doc,
+  // FTSRestRequest tdbRestRequest)
+  // {
+  // String primaryKey = null;
+  //
+  // Object[] summaryRowData;
+  //
+  // Collection<FTSDataColumnI> displayFields =
+  // tdbRestRequest.getWantedFields();
+  // int colCounter = 0;
+  // summaryRowData = new Object[displayFields.size() + 1];
+  //
+  // return null;
+  // }
 
   private String parseJsonExceptionString(String jsonErrorString)
   {
@@ -293,7 +320,7 @@ private static FTSData getFTSData(Map<String, Object> tdbJsonStructure,
   {
     return "/fts/tdbeacons_data_columns.txt";
   }
-  
+
   public static FTSRestClientI getInstance()
   {
     if (instance == null)
@@ -302,7 +329,7 @@ private static FTSData getFTSData(Map<String, Object> tdbJsonStructure,
     }
     return instance;
   }
-  
+
   private Collection<FTSDataColumnI> allDefaultDisplayedStructureDataColumns;
 
   public Collection<FTSDataColumnI> getAllDefaultDisplayedStructureDataColumns()
@@ -316,5 +343,26 @@ private static FTSData getFTSData(Map<String, Object> tdbJsonStructure,
     }
     return allDefaultDisplayedStructureDataColumns;
   }
-  
+
+  @Override
+  public String[] getPreferencesColumnsFor(PreferenceSource source)
+  {
+    String[] columnNames = null;
+    switch (source)
+    {
+    case SEARCH_SUMMARY:
+      columnNames = new String[] { "", "Display", "Group" };
+      break;
+    case STRUCTURE_CHOOSER:
+      columnNames = new String[] { "", "Display", "Group" };
+      break;
+    case PREFERENCES:
+      columnNames = new String[] { "3DB Beacons Field", "Show in search summary",
+          "Show in structure summary" };
+      break;
+    default:
+      break;
+    }
+    return columnNames;
+  }
 }
index ebba2e5..ea2d50d 100644 (file)
@@ -35,6 +35,8 @@ import jalview.fts.core.FTSDataColumnPreferences;
 import jalview.fts.core.FTSRestRequest;
 import jalview.fts.core.FTSRestResponse;
 import jalview.fts.service.pdb.PDBFTSRestClient;
+import jalview.gui.structurechooser.PDBStructureChooserQuerySource;
+import jalview.gui.structurechooser.StructureChooserQuerySource;
 import jalview.io.DataSourceType;
 import jalview.jbgui.GStructureChooser;
 import jalview.jbgui.GStructureChooser.FilterOption;
@@ -102,7 +104,7 @@ public class StructureChooser extends GStructureChooser
   {
     // which FTS engine to use
     data = StructureChooserQuerySource
-            .getPDBfts();
+            .getTDBfts();
     initDialog();
     
     this.ap = ap;
@@ -243,6 +245,12 @@ public class StructureChooser extends GStructureChooser
       {
         resultList = data.fetchStructuresMetaData(seq, wantedFields,
                 selectedFilterOpt, !chk_invertFilter.isSelected());
+        // null response means the FTSengine didn't yield a query for this
+        // consider designing a special exception if we really wanted to be OOCrazy
+        if (resultList==null)
+        {
+          continue;
+        }
       } catch (Exception e)
       {
         e.printStackTrace();
@@ -735,36 +743,11 @@ public class StructureChooser extends GStructureChooser
 
         if (currentView == VIEWS_FILTER)
         {
-          int pdbIdColIndex = restable.getColumn("PDB Id").getModelIndex();
-          int refSeqColIndex = restable.getColumn("Ref Sequence")
-                  .getModelIndex();
           int[] selectedRows = restable.getSelectedRows();
           PDBEntry[] pdbEntriesToView = new PDBEntry[selectedRows.length];
-          int count = 0;
           List<SequenceI> selectedSeqsToView = new ArrayList<>();
-          for (int row : selectedRows)
-          {
-            String pdbIdStr = restable.getValueAt(row, pdbIdColIndex)
-                    .toString();
-            SequenceI selectedSeq = (SequenceI) restable.getValueAt(row,
-                    refSeqColIndex);
-            selectedSeqsToView.add(selectedSeq);
-            PDBEntry pdbEntry = selectedSeq.getPDBEntry(pdbIdStr);
-            if (pdbEntry == null)
-            {
-              pdbEntry = getFindEntry(pdbIdStr,
-                      selectedSeq.getAllPDBEntries());
-            }
+          pdbEntriesToView = data.collectSelectedRows(restable,selectedRows,selectedSeqsToView);
 
-            if (pdbEntry == null)
-            {
-              pdbEntry = new PDBEntry();
-              pdbEntry.setId(pdbIdStr);
-              pdbEntry.setType(PDBEntry.Type.PDB);
-              selectedSeq.getDatasetSequence().addPDBId(pdbEntry);
-            }
-            pdbEntriesToView[count++] = pdbEntry;
-          }
           SequenceI[] selectedSeqs = selectedSeqsToView
                   .toArray(new SequenceI[selectedSeqsToView.size()]);
           sViewer = launchStructureViewer(ssm, pdbEntriesToView, ap,
@@ -872,21 +855,6 @@ public class StructureChooser extends GStructureChooser
     }
   }
 
-  private PDBEntry getFindEntry(String id, Vector<PDBEntry> pdbEntries)
-  {
-    Objects.requireNonNull(id);
-    Objects.requireNonNull(pdbEntries);
-    PDBEntry foundEntry = null;
-    for (PDBEntry entry : pdbEntries)
-    {
-      if (entry.getId().equalsIgnoreCase(id))
-      {
-        return entry;
-      }
-    }
-    return foundEntry;
-  }
-
   /**
    * Answers a structure viewer (new or existing) configured to superimpose
    * added structures or not according to the user's choice
diff --git a/src/jalview/gui/StructureChooserQuerySource.java b/src/jalview/gui/StructureChooserQuerySource.java
deleted file mode 100644 (file)
index 637f168..0000000
+++ /dev/null
@@ -1,315 +0,0 @@
-package jalview.gui;
-
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-
-import javax.swing.table.TableModel;
-
-import jalview.datamodel.DBRefEntry;
-import jalview.datamodel.DBRefSource;
-import jalview.datamodel.PDBEntry;
-import jalview.datamodel.SequenceI;
-import jalview.fts.api.FTSData;
-import jalview.fts.api.FTSDataColumnI;
-import jalview.fts.api.FTSRestClientI;
-import jalview.fts.core.FTSDataColumnPreferences;
-import jalview.fts.core.FTSDataColumnPreferences.PreferenceSource;
-import jalview.fts.core.FTSRestRequest;
-import jalview.fts.core.FTSRestResponse;
-import jalview.fts.service.pdb.PDBFTSRestClient;
-import jalview.jbgui.GStructureChooser.FilterOption;
-
-/**
- * logic for querying sources of structural data for structures of sequences
- * 
- * @author jprocter
- *
- * @param <T>
- */
-public class StructureChooserQuerySource
-{
-  private FTSRestRequest lastPdbRequest;
-
-  private FTSRestClientI pdbRestClient;
-
-  private FTSDataColumnPreferences docFieldPrefs;
-
-  private static int MAX_QLENGTH = 7820;
-
-  public StructureChooserQuerySource()
-  {
-  }
-
-  public static StructureChooserQuerySource getPDBfts()
-  {
-    StructureChooserQuerySource pdbfts = new StructureChooserQuerySource();
-    pdbfts.pdbRestClient = PDBFTSRestClient.getInstance();
-    pdbfts.docFieldPrefs = new FTSDataColumnPreferences(
-            PreferenceSource.STRUCTURE_CHOOSER,
-            PDBFTSRestClient.getInstance());
-    return pdbfts;
-  }
-
-  public FTSDataColumnPreferences getDocFieldPrefs()
-  {
-    return docFieldPrefs;
-  }
-
-  public void setDocFieldPrefs(FTSDataColumnPreferences docFieldPrefs)
-  {
-    this.docFieldPrefs = docFieldPrefs;
-  }
-
-  /**
-   * Builds a query string for a given sequences using its DBRef entries
-   * 
-   * @param seq
-   *          the sequences to build a query for
-   * @return the built query string
-   */
-
-  String buildQuery(SequenceI seq)
-  {
-    boolean isPDBRefsFound = false;
-    boolean isUniProtRefsFound = false;
-    StringBuilder queryBuilder = new StringBuilder();
-    Set<String> seqRefs = new LinkedHashSet<>();
-
-    /*
-     * note PDBs as DBRefEntry so they are not duplicated in query
-     */
-    Set<String> pdbids = new HashSet<>();
-
-    if (seq.getAllPDBEntries() != null
-            && queryBuilder.length() < MAX_QLENGTH)
-    {
-      for (PDBEntry entry : seq.getAllPDBEntries())
-      {
-        if (isValidSeqName(entry.getId()))
-        {
-          String id = entry.getId().toLowerCase();
-          queryBuilder.append("pdb_id:").append(id).append(" OR ");
-          isPDBRefsFound = true;
-          pdbids.add(id);
-        }
-      }
-    }
-
-    List<DBRefEntry> refs = seq.getDBRefs();
-    if (refs != null && refs.size() != 0)
-    {
-      for (int ib = 0, nb = refs.size(); ib < nb; ib++)
-      {
-        DBRefEntry dbRef = refs.get(ib);
-        if (isValidSeqName(getDBRefId(dbRef))
-                && queryBuilder.length() < MAX_QLENGTH)
-        {
-          if (dbRef.getSource().equalsIgnoreCase(DBRefSource.UNIPROT))
-          {
-            queryBuilder.append("uniprot_accession:")
-                    .append(getDBRefId(dbRef)).append(" OR ");
-            queryBuilder.append("uniprot_id:").append(getDBRefId(dbRef))
-                    .append(" OR ");
-            isUniProtRefsFound = true;
-          }
-          else if (dbRef.getSource().equalsIgnoreCase(DBRefSource.PDB))
-          {
-
-            String id = getDBRefId(dbRef).toLowerCase();
-            if (!pdbids.contains(id))
-            {
-              queryBuilder.append("pdb_id:").append(id).append(" OR ");
-              isPDBRefsFound = true;
-              pdbids.add(id);
-            }
-          }
-          else
-          {
-            seqRefs.add(getDBRefId(dbRef));
-          }
-        }
-      }
-    }
-
-    if (!isPDBRefsFound && !isUniProtRefsFound)
-    {
-      String seqName = seq.getName();
-      seqName = sanitizeSeqName(seqName);
-      String[] names = seqName.toLowerCase().split("\\|");
-      for (String name : names)
-      {
-        // System.out.println("Found name : " + name);
-        name.trim();
-        if (isValidSeqName(name))
-        {
-          seqRefs.add(name);
-        }
-      }
-
-      for (String seqRef : seqRefs)
-      {
-        queryBuilder.append("text:").append(seqRef).append(" OR ");
-      }
-    }
-
-    int endIndex = queryBuilder.lastIndexOf(" OR ");
-    if (queryBuilder.toString().length() < 6)
-    {
-      return null;
-    }
-    String query = queryBuilder.toString().substring(0, endIndex);
-    return query;
-  }
-
-  /**
-   * Remove the following special characters from input string +, -, &, !, (, ),
-   * {, }, [, ], ^, ", ~, *, ?, :, \
-   * 
-   * @param seqName
-   * @return
-   */
-  static String sanitizeSeqName(String seqName)
-  {
-    Objects.requireNonNull(seqName);
-    return seqName.replaceAll("\\[\\d*\\]", "")
-            .replaceAll("[^\\dA-Za-z|_]", "").replaceAll("\\s+", "+");
-  }
-
-  /**
-   * Ensures sequence ref names are not less than 3 characters and does not
-   * contain a database name
-   * 
-   * @param seqName
-   * @return
-   */
-  static boolean isValidSeqName(String seqName)
-  {
-    // System.out.println("seqName : " + seqName);
-    String ignoreList = "pdb,uniprot,swiss-prot";
-    if (seqName.length() < 3)
-    {
-      return false;
-    }
-    if (seqName.contains(":"))
-    {
-      return false;
-    }
-    seqName = seqName.toLowerCase();
-    for (String ignoredEntry : ignoreList.split(","))
-    {
-      if (seqName.contains(ignoredEntry))
-      {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  static String getDBRefId(DBRefEntry dbRef)
-  {
-    String ref = dbRef.getAccessionId().replaceAll("GO:", "");
-    return ref;
-  }
-
-  /**
-   * FTSRestClient specific query builder to recover associated structure data
-   * records for a sequence
-   * 
-   * @param seq
-   *          - seq to generate a query for
-   * @param wantedFields
-   *          - fields to retrieve
-   * @param selectedFilterOpt
-   *          - criterion for ranking results (e.g. resolution)
-   * @param b
-   *          - sort ascending or descending
-   * @return
-   * @throws Exception
-   */
-  public FTSRestResponse fetchStructuresMetaData(SequenceI seq,
-          Collection<FTSDataColumnI> wantedFields,
-          FilterOption selectedFilterOpt, boolean b) throws Exception
-  {
-    FTSRestResponse resultList;
-    FTSRestRequest pdbRequest = new FTSRestRequest();
-    pdbRequest.setAllowEmptySeq(false);
-    pdbRequest.setResponseSize(500);
-    pdbRequest.setFieldToSearchBy("(");
-    pdbRequest.setFieldToSortBy(selectedFilterOpt.getValue(), b);
-    pdbRequest.setWantedFields(wantedFields);
-    pdbRequest.setSearchTerm(buildQuery(seq) + ")");
-    pdbRequest.setAssociatedSequence(seq);
-    resultList = pdbRestClient.executeRequest(pdbRequest);
-
-    lastPdbRequest = pdbRequest;
-    return resultList;
-  }
-
-  /**
-   * FTSRestClient specific query builder to pick top ranked entry from a
-   * fetchStructuresMetaData query
-   * 
-   * @param seq
-   *          - seq to generate a query for
-   * @param wantedFields
-   *          - fields to retrieve
-   * @param selectedFilterOpt
-   *          - criterion for ranking results (e.g. resolution)
-   * @param b
-   *          - sort ascending or descending
-   * @return
-   * @throws Exception
-   */
-  public FTSRestResponse selectFirstRankedQuery(SequenceI seq,
-          Collection<FTSDataColumnI> wantedFields, String fieldToFilterBy,
-          boolean b) throws Exception
-  {
-
-    FTSRestResponse resultList;
-    FTSRestRequest pdbRequest = new FTSRestRequest();
-    if (fieldToFilterBy.equalsIgnoreCase("uniprot_coverage"))
-    {
-      pdbRequest.setAllowEmptySeq(false);
-      pdbRequest.setResponseSize(1);
-      pdbRequest.setFieldToSearchBy("(");
-      pdbRequest.setSearchTerm(buildQuery(seq) + ")");
-      pdbRequest.setWantedFields(wantedFields);
-      pdbRequest.setAssociatedSequence(seq);
-      pdbRequest.setFacet(true);
-      pdbRequest.setFacetPivot(fieldToFilterBy + ",entry_entity");
-      pdbRequest.setFacetPivotMinCount(1);
-    }
-    else
-    {
-      pdbRequest.setAllowEmptySeq(false);
-      pdbRequest.setResponseSize(1);
-      pdbRequest.setFieldToSearchBy("(");
-      pdbRequest.setFieldToSortBy(fieldToFilterBy, b);
-      pdbRequest.setSearchTerm(buildQuery(seq) + ")");
-      pdbRequest.setWantedFields(wantedFields);
-      pdbRequest.setAssociatedSequence(seq);
-    }
-    resultList = pdbRestClient.executeRequest(pdbRequest);
-
-    lastPdbRequest = pdbRequest;
-    return resultList;
-  }
-
-  public TableModel getTableModel(
-          Collection<FTSData> discoveredStructuresSet)
-  {
-    return FTSRestResponse.getTableModel(lastPdbRequest,
-            discoveredStructuresSet);
-  }
-
-  public FTSDataColumnPreferences getInitialFieldPreferences()
-  {
-    // TODO Auto-generated method stub
-    return null;
-  }
-
-}
\ No newline at end of file
diff --git a/src/jalview/gui/structurechooser/StructureChooserQuerySource.java b/src/jalview/gui/structurechooser/StructureChooserQuerySource.java
new file mode 100644 (file)
index 0000000..9861b1a
--- /dev/null
@@ -0,0 +1,207 @@
+package jalview.gui.structurechooser;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.Vector;
+
+import javax.swing.JTable;
+import javax.swing.table.TableModel;
+
+import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.DBRefSource;
+import jalview.datamodel.PDBEntry;
+import jalview.datamodel.SequenceI;
+import jalview.fts.api.FTSData;
+import jalview.fts.api.FTSDataColumnI;
+import jalview.fts.api.FTSRestClientI;
+import jalview.fts.core.FTSDataColumnPreferences;
+import jalview.fts.core.FTSDataColumnPreferences.PreferenceSource;
+import jalview.fts.core.FTSRestRequest;
+import jalview.fts.core.FTSRestResponse;
+import jalview.fts.service.pdb.PDBFTSRestClient;
+import jalview.jbgui.GStructureChooser.FilterOption;
+
+/**
+ * logic for querying sources of structural data for structures of sequences
+ * 
+ * @author jprocter
+ *
+ * @param <T>
+ */
+public abstract class StructureChooserQuerySource
+{
+  protected FTSRestRequest lastPdbRequest;
+
+  protected FTSRestClientI pdbRestClient;
+
+  protected FTSDataColumnPreferences docFieldPrefs;
+
+  /**
+   * max length of a GET URL (probably :( )
+   */
+  protected static int MAX_QLENGTH = 7820;
+
+  public StructureChooserQuerySource()
+  {
+  }
+
+  public static StructureChooserQuerySource getPDBfts()
+  {
+          return new PDBStructureChooserQuerySource();
+  }
+
+  public static StructureChooserQuerySource getTDBfts()
+  {
+    return new ThreeDBStructureChooserQuerySource();
+  }
+
+  public FTSDataColumnPreferences getDocFieldPrefs()
+  {
+    return docFieldPrefs;
+  }
+
+  public void setDocFieldPrefs(FTSDataColumnPreferences docFieldPrefs)
+  {
+    this.docFieldPrefs = docFieldPrefs;
+  }
+
+  public FTSDataColumnPreferences getInitialFieldPreferences()
+  {
+    return docFieldPrefs;
+  }
+
+
+  /**
+   * Builds a query string for a given sequences using its DBRef entries
+   * 
+   * @param seq
+   *          the sequences to build a query for
+   * @return the built query string
+   */
+
+  public abstract String buildQuery(SequenceI seq);
+  
+
+  /**
+   * Remove the following special characters from input string +, -, &, !, (, ),
+   * {, }, [, ], ^, ", ~, *, ?, :, \
+   * 
+   * @param seqName
+   * @return
+   */
+  public static String sanitizeSeqName(String seqName)
+  {
+    Objects.requireNonNull(seqName);
+    return seqName.replaceAll("\\[\\d*\\]", "")
+            .replaceAll("[^\\dA-Za-z|_]", "").replaceAll("\\s+", "+");
+  }
+
+  /**
+   * Ensures sequence ref names are not less than 3 characters and does not
+   * contain a database name
+   * 
+   * @param seqName
+   * @return
+   */
+  static boolean isValidSeqName(String seqName)
+  {
+    // System.out.println("seqName : " + seqName);
+    String ignoreList = "pdb,uniprot,swiss-prot";
+    if (seqName.length() < 3)
+    {
+      return false;
+    }
+    if (seqName.contains(":"))
+    {
+      return false;
+    }
+    seqName = seqName.toLowerCase();
+    for (String ignoredEntry : ignoreList.split(","))
+    {
+      if (seqName.contains(ignoredEntry))
+      {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  static String getDBRefId(DBRefEntry dbRef)
+  {
+    String ref = dbRef.getAccessionId().replaceAll("GO:", "");
+    return ref;
+  }
+
+  static PDBEntry getFindEntry(String id, Vector<PDBEntry> pdbEntries)
+  {
+    Objects.requireNonNull(id);
+    Objects.requireNonNull(pdbEntries);
+    PDBEntry foundEntry = null;
+    for (PDBEntry entry : pdbEntries)
+    {
+      if (entry.getId().equalsIgnoreCase(id))
+      {
+        return entry;
+      }
+    }
+    return foundEntry;
+  }
+
+  /**
+   * FTSRestClient specific query builder to recover associated structure data
+   * records for a sequence
+   * 
+   * @param seq
+   *          - seq to generate a query for
+   * @param wantedFields
+   *          - fields to retrieve
+   * @param selectedFilterOpt
+   *          - criterion for ranking results (e.g. resolution)
+   * @param b
+   *          - sort ascending or descending
+   * @return
+   * @throws Exception
+   */
+  public abstract FTSRestResponse fetchStructuresMetaData(SequenceI seq,
+          Collection<FTSDataColumnI> wantedFields,
+          FilterOption selectedFilterOpt, boolean b) throws Exception;
+
+  /**
+   * FTSRestClient specific query builder to pick top ranked entry from a
+   * fetchStructuresMetaData query
+   * 
+   * @param seq
+   *          - seq to generate a query for
+   * @param wantedFields
+   *          - fields to retrieve
+   * @param selectedFilterOpt
+   *          - criterion for ranking results (e.g. resolution)
+   * @param b
+   *          - sort ascending or descending
+   * @return
+   * @throws Exception
+   */
+  public abstract FTSRestResponse selectFirstRankedQuery(SequenceI seq,
+          Collection<FTSDataColumnI> wantedFields, String fieldToFilterBy,
+          boolean b) throws Exception;
+
+  /**
+   * 
+   * @param discoveredStructuresSet
+   * @return the table model for the given result set for this engine
+   */
+  public TableModel getTableModel(
+          Collection<FTSData> discoveredStructuresSet)
+  {
+    return FTSRestResponse.getTableModel(lastPdbRequest,
+            discoveredStructuresSet);
+  }
+
+  public abstract PDBEntry[] collectSelectedRows(JTable restable,
+          int[] selectedRows, List<SequenceI> selectedSeqsToView);
+
+}
\ No newline at end of file
index 66e606a..31f5f8b 100644 (file)
@@ -30,6 +30,8 @@ import jalview.datamodel.PDBEntry;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
 import jalview.fts.api.FTSData;
+import jalview.gui.structurechooser.PDBStructureChooserQuerySource;
+import jalview.gui.structurechooser.StructureChooserQuerySource;
 import jalview.jbgui.GStructureChooser.FilterOption;
 import jalview.ws.params.InvalidArgumentException;
 
@@ -165,17 +167,17 @@ public class StructureChooserTest
   public void sanitizeSeqNameTest()
   {
     String name = "ab_cdEF|fwxyz012349";
-    assertEquals(name, StructureChooserQuerySource.sanitizeSeqName(name));
+    assertEquals(name, PDBStructureChooserQuerySource.sanitizeSeqName(name));
 
     // remove a [nn] substring
     name = "abcde12[345]fg";
-    assertEquals("abcde12fg", StructureChooserQuerySource.sanitizeSeqName(name));
+    assertEquals("abcde12fg", PDBStructureChooserQuerySource.sanitizeSeqName(name));
 
     // remove characters other than a-zA-Z0-9 | or _
     name = "ab[cd],.\t£$*!- \\\"@:e";
-    assertEquals("abcde", StructureChooserQuerySource.sanitizeSeqName(name));
+    assertEquals("abcde", PDBStructureChooserQuerySource.sanitizeSeqName(name));
 
     name = "abcde12[345a]fg";
-    assertEquals("abcde12345afg", StructureChooserQuerySource.sanitizeSeqName(name));
+    assertEquals("abcde12345afg", PDBStructureChooserQuerySource.sanitizeSeqName(name));
   }
 }