JAL-2071 further refactoring, optimisation, and house keeping for the generic Free...
[jalview.git] / src / jalview / gui / StructureChooser.java
index 720dc9e..d924e73 100644 (file)
 
 package jalview.gui;
 
+import jalview.bin.Jalview;
 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.FTSRestRequest;
+import jalview.fts.core.FTSRestResponse;
+import jalview.fts.service.pdb.PDBFTSRestClient;
 import jalview.jbgui.GStructureChooser;
-import jalview.jbgui.PDBDocFieldPreferences;
 import jalview.structure.StructureSelectionManager;
 import jalview.util.MessageManager;
-import jalview.ws.dbsources.PDBRestClient;
-import jalview.ws.dbsources.PDBRestClient.PDBDocField;
-import jalview.ws.uimodel.PDBRestRequest;
-import jalview.ws.uimodel.PDBRestResponse;
-import jalview.ws.uimodel.PDBRestResponse.PDBResponseSummary;
+import jalview.ws.sifts.SiftsSettings;
 
 import java.awt.event.ItemEvent;
 import java.util.ArrayList;
@@ -41,6 +43,8 @@ import java.util.Collection;
 import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.List;
+import java.util.Objects;
+import java.util.Vector;
 
 import javax.swing.JCheckBox;
 import javax.swing.JComboBox;
@@ -55,7 +59,8 @@ import javax.swing.table.AbstractTableModel;
  *
  */
 @SuppressWarnings("serial")
-public class StructureChooser extends GStructureChooser
+public class StructureChooser extends GStructureChooser implements
+        IProgressIndicator
 {
   private boolean structuresDiscovered = false;
 
@@ -65,11 +70,11 @@ public class StructureChooser extends GStructureChooser
 
   private IProgressIndicator progressIndicator;
 
-  private Collection<PDBResponseSummary> discoveredStructuresSet;
+  private Collection<FTSData> discoveredStructuresSet;
 
-  private PDBRestRequest lastPdbRequest;
+  private FTSRestRequest lastPdbRequest;
 
-  private PDBRestClient pdbRestCleint;
+  private FTSRestClientI pdbRestCleint;
 
   private String selectedPdbFileName;
 
@@ -90,6 +95,11 @@ public class StructureChooser extends GStructureChooser
    */
   public void init()
   {
+    if (!Jalview.isHeadlessMode())
+    {
+      progressBar = new ProgressBar(this.statusPanel, this.statusBar);
+    }
+
     Thread discoverPDBStructuresThread = new Thread(new Runnable()
     {
       @Override
@@ -136,22 +146,22 @@ public class StructureChooser extends GStructureChooser
   public void fetchStructuresMetaData()
   {
     long startTime = System.currentTimeMillis();
-    Collection<PDBDocField> wantedFields = PDBDocFieldPreferences
-            .getStructureSummaryFields();
+    pdbRestCleint = PDBFTSRestClient.getInstance();
+    Collection<FTSDataColumnI> wantedFields = pdbRestCleint
+            .getAllDefaulDisplayedDataColumns();
 
-    discoveredStructuresSet = new LinkedHashSet<PDBResponseSummary>();
+    discoveredStructuresSet = new LinkedHashSet<FTSData>();
     HashSet<String> errors = new HashSet<String>();
     for (SequenceI seq : selectedSequences)
     {
-      PDBRestRequest pdbRequest = new PDBRestRequest();
+      FTSRestRequest pdbRequest = new FTSRestRequest();
       pdbRequest.setAllowEmptySeq(false);
       pdbRequest.setResponseSize(500);
       pdbRequest.setFieldToSearchBy("(");
       pdbRequest.setWantedFields(wantedFields);
       pdbRequest.setSearchTerm(buildQuery(seq) + ")");
       pdbRequest.setAssociatedSequence(seq);
-      pdbRestCleint = new PDBRestClient();
-      PDBRestResponse resultList;
+      FTSRestResponse resultList;
       try
       {
         resultList = pdbRestCleint.executeRequest(pdbRequest);
@@ -175,7 +185,7 @@ public class StructureChooser extends GStructureChooser
     if (discoveredStructuresSet != null
             && !discoveredStructuresSet.isEmpty())
     {
-      tbl_summary.setModel(PDBRestResponse.getTableModel(lastPdbRequest,
+      tbl_summary.setModel(FTSRestResponse.getTableModel(lastPdbRequest,
               discoveredStructuresSet));
       structuresDiscovered = true;
       noOfStructuresFound = discoveredStructuresSet.size();
@@ -245,7 +255,7 @@ public class StructureChooser extends GStructureChooser
       {
         if (isValidSeqName(entry.getId()))
         {
-          queryBuilder.append(PDBRestClient.PDBDocField.PDB_ID.getCode())
+          queryBuilder.append("pdb_id")
                   .append(":")
 .append(entry.getId().toLowerCase())
                   .append(" OR ");
@@ -264,12 +274,11 @@ public class StructureChooser extends GStructureChooser
           if (dbRef.getSource().equalsIgnoreCase(DBRefSource.UNIPROT))
           {
             queryBuilder
-                    .append(PDBRestClient.PDBDocField.UNIPROT_ACCESSION
-                            .getCode()).append(":")
+.append("uniprot_accession").append(":")
                     .append(getDBRefId(dbRef))
                     .append(" OR ");
             queryBuilder
-                    .append(PDBRestClient.PDBDocField.UNIPROT_ID.getCode())
+.append("uniprot_id")
                     .append(":")
                     .append(getDBRefId(dbRef)).append(" OR ");
             isUniProtRefsFound = true;
@@ -277,7 +286,7 @@ public class StructureChooser extends GStructureChooser
           else if (dbRef.getSource().equalsIgnoreCase(DBRefSource.PDB))
           {
 
-            queryBuilder.append(PDBRestClient.PDBDocField.PDB_ID.getCode())
+            queryBuilder.append("pdb_id")
                     .append(":").append(getDBRefId(dbRef).toLowerCase())
                     .append(" OR ");
             isPDBRefsFound = true;
@@ -293,6 +302,7 @@ public class StructureChooser extends GStructureChooser
     if (!isPDBRefsFound && !isUniProtRefsFound)
     {
       String seqName = seq.getName();
+      seqName = sanitizeSeqName(seqName);
       String[] names = seqName.toLowerCase().split("\\|");
       for (String name : names)
       {
@@ -320,6 +330,21 @@ public class StructureChooser extends GStructureChooser
   }
 
   /**
+   * Remove the following special characters from input string +, -, &, |, !, (,
+   * ), {, }, [, ], ^, ", ~, *, ?, :, \
+   * 
+   * @param seqName
+   * @return
+   */
+  private 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
    * 
@@ -369,24 +394,41 @@ public class StructureChooser extends GStructureChooser
       public void run()
       {
         long startTime = System.currentTimeMillis();
+        pdbRestCleint = PDBFTSRestClient.getInstance();
         lbl_loading.setVisible(true);
-        Collection<PDBDocField> wantedFields = PDBDocFieldPreferences
-                .getStructureSummaryFields();
-        Collection<PDBResponseSummary> filteredResponse = new HashSet<PDBResponseSummary>();
+        Collection<FTSDataColumnI> wantedFields = pdbRestCleint
+                .getAllDefaulDisplayedDataColumns();
+        Collection<FTSData> filteredResponse = new HashSet<FTSData>();
         HashSet<String> errors = new HashSet<String>();
+
         for (SequenceI seq : selectedSequences)
         {
-          PDBRestRequest pdbRequest = new PDBRestRequest();
-          pdbRequest.setAllowEmptySeq(false);
-          pdbRequest.setResponseSize(1);
-          pdbRequest.setFieldToSearchBy("(");
-          pdbRequest.setFieldToSortBy(fieldToFilterBy,
-                  !chk_invertFilter.isSelected());
-          pdbRequest.setSearchTerm(buildQuery(seq) + ")");
-          pdbRequest.setWantedFields(wantedFields);
-          pdbRequest.setAssociatedSequence(seq);
-          pdbRestCleint = new PDBRestClient();
-          PDBRestResponse resultList;
+          FTSRestRequest pdbRequest = new FTSRestRequest();
+          if (fieldToFilterBy.equalsIgnoreCase("uniprot_coverage"))
+          {
+            System.out.println(">>>>>> Filtering with uniprot coverate");
+            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,
+                    !chk_invertFilter.isSelected());
+            pdbRequest.setSearchTerm(buildQuery(seq) + ")");
+            pdbRequest.setWantedFields(wantedFields);
+            pdbRequest.setAssociatedSequence(seq);
+          }
+          FTSRestResponse resultList;
           try
           {
             resultList = pdbRestCleint.executeRequest(pdbRequest);
@@ -409,12 +451,16 @@ public class StructureChooser extends GStructureChooser
         if (!filteredResponse.isEmpty())
         {
           final int filterResponseCount = filteredResponse.size();
-          Collection<PDBResponseSummary> reorderedStructuresSet = new LinkedHashSet<PDBResponseSummary>();
+          Collection<FTSData> reorderedStructuresSet = new LinkedHashSet<FTSData>();
           reorderedStructuresSet.addAll(filteredResponse);
           reorderedStructuresSet.addAll(discoveredStructuresSet);
-          tbl_summary.setModel(PDBRestResponse.getTableModel(
+          tbl_summary.setModel(FTSRestResponse.getTableModel(
                   lastPdbRequest, reorderedStructuresSet));
 
+          FTSRestResponse.configureTableColumn(tbl_summary, wantedFields);
+          tbl_summary.getColumn("Ref Sequence").setPreferredWidth(120);
+          tbl_summary.getColumn("Ref Sequence").setMinWidth(100);
+          tbl_summary.getColumn("Ref Sequence").setMaxWidth(200);
           // Update table selection model here
           tbl_summary.addRowSelectionInterval(0, filterResponseCount - 1);
           mainFrame.setTitle(MessageManager.formatMessage(
@@ -482,17 +528,17 @@ public class StructureChooser extends GStructureChooser
     if (isStructuresDiscovered())
     {
       cmb_filterOption.addItem(new FilterOption("Best Quality",
-              PDBDocField.OVERALL_QUALITY.getCode(), VIEWS_FILTER));
-      cmb_filterOption.addItem(new FilterOption("Best UniProt Coverage",
-              PDBDocField.UNIPROT_COVERAGE.getCode(), VIEWS_FILTER));
-      cmb_filterOption.addItem(new FilterOption("Highest Resolution",
-              PDBDocField.RESOLUTION.getCode(), VIEWS_FILTER));
-      cmb_filterOption.addItem(new FilterOption("Highest Protein Chain",
-              PDBDocField.PROTEIN_CHAIN_COUNT.getCode(), VIEWS_FILTER));
-      cmb_filterOption.addItem(new FilterOption("Highest Bound Molecules",
-              PDBDocField.BOUND_MOLECULE_COUNT.getCode(), VIEWS_FILTER));
-      cmb_filterOption.addItem(new FilterOption("Highest Polymer Residues",
-              PDBDocField.POLYMER_RESIDUE_COUNT.getCode(), VIEWS_FILTER));
+              "overall_quality", VIEWS_FILTER));
+      cmb_filterOption.addItem(new FilterOption("Most UniProt Coverage",
+              "uniprot_coverage", VIEWS_FILTER));
+      cmb_filterOption.addItem(new FilterOption("Best Resolution",
+              "resolution", VIEWS_FILTER));
+      cmb_filterOption.addItem(new FilterOption("Most Protein Chain",
+              "number_of_protein_chains", VIEWS_FILTER));
+      cmb_filterOption.addItem(new FilterOption("Most Bound Molecules",
+              "number_of_bound_molecules", VIEWS_FILTER));
+      cmb_filterOption.addItem(new FilterOption("Most Polymer Residues",
+              "number_of_polymer_residues", VIEWS_FILTER));
     }
     cmb_filterOption.addItem(new FilterOption("Enter PDB Id", "-",
             VIEWS_ENTER_ID));
@@ -669,13 +715,22 @@ public class StructureChooser extends GStructureChooser
   @Override
   public void ok_ActionPerformed()
   {
+    final long progressSessionId = System.currentTimeMillis();
+    final StructureSelectionManager ssm = ap.getStructureSelectionManager();
+    ssm.setProgressIndicator(this);
+    ssm.setProgressSessionId(progressSessionId);
+    new Thread(new Runnable()
+    {
+      @Override
+      public void run()
+      {
     FilterOption selectedFilterOpt = ((FilterOption) cmb_filterOption
             .getSelectedItem());
     String currentView = selectedFilterOpt.getView();
     if (currentView == VIEWS_FILTER)
     {
-      int pdbIdColIndex = tbl_summary.getColumn(
-              PDBRestClient.PDBDocField.PDB_ID.getName()).getModelIndex();
+          int pdbIdColIndex = tbl_summary.getColumn("PDB Id")
+                  .getModelIndex();
       int refSeqColIndex = tbl_summary.getColumn("Ref Sequence")
               .getModelIndex();
       int[] selectedRows = tbl_summary.getSelectedRows();
@@ -689,7 +744,12 @@ public class StructureChooser extends GStructureChooser
         SequenceI selectedSeq = (SequenceI) tbl_summary.getValueAt(row,
                 refSeqColIndex);
         selectedSeqsToView.add(selectedSeq);
-        PDBEntry pdbEntry = selectedSeq.getPDBEntry(pdbIdStr);
+            PDBEntry pdbEntry = selectedSeq.getPDBEntry(pdbIdStr);
+            if (pdbEntry == null)
+            {
+              pdbEntry = getFindEntry(pdbIdStr,
+                      selectedSeq.getAllPDBEntries());
+            }
         if (pdbEntry == null)
         {
           pdbEntry = new PDBEntry();
@@ -701,16 +761,15 @@ public class StructureChooser extends GStructureChooser
       }
       SequenceI[] selectedSeqs = selectedSeqsToView
               .toArray(new SequenceI[selectedSeqsToView.size()]);
-      launchStructureViewer(ap.getStructureSelectionManager(),
-              pdbEntriesToView, ap, selectedSeqs);
+          launchStructureViewer(ssm, pdbEntriesToView, ap, selectedSeqs);
     }
     else if (currentView == VIEWS_LOCAL_PDB)
     {
       int[] selectedRows = tbl_local_pdb.getSelectedRows();
       PDBEntry[] pdbEntriesToView = new PDBEntry[selectedRows.length];
       int count = 0;
-      int pdbIdColIndex = tbl_local_pdb.getColumn(
-              PDBRestClient.PDBDocField.PDB_ID.getName()).getModelIndex();
+          int pdbIdColIndex = tbl_local_pdb.getColumn("PDB Id")
+                  .getModelIndex();
       int refSeqColIndex = tbl_local_pdb.getColumn("Ref Sequence")
               .getModelIndex();
       ArrayList<SequenceI> selectedSeqsToView = new ArrayList<SequenceI>();
@@ -725,8 +784,7 @@ public class StructureChooser extends GStructureChooser
       }
       SequenceI[] selectedSeqs = selectedSeqsToView
               .toArray(new SequenceI[selectedSeqsToView.size()]);
-      launchStructureViewer(ap.getStructureSelectionManager(),
-              pdbEntriesToView, ap, selectedSeqs);
+          launchStructureViewer(ssm, pdbEntriesToView, ap, selectedSeqs);
     }
     else if (currentView == VIEWS_ENTER_ID)
     {
@@ -748,8 +806,8 @@ public class StructureChooser extends GStructureChooser
       }
 
       PDBEntry[] pdbEntriesToView = new PDBEntry[] { pdbEntry };
-      launchStructureViewer(ap.getStructureSelectionManager(),
-              pdbEntriesToView, ap, new SequenceI[] { selectedSequence });
+          launchStructureViewer(ssm, pdbEntriesToView, ap,
+                  new SequenceI[] { selectedSequence });
     }
     else if (currentView == VIEWS_FROM_FILE)
     {
@@ -764,26 +822,50 @@ public class StructureChooser extends GStructureChooser
                       jalview.io.AppletFormatAdapter.FILE,
                       selectedSequence, true, Desktop.instance);
 
-      launchStructureViewer(ap.getStructureSelectionManager(),
-              new PDBEntry[] { fileEntry }, ap,
-              new SequenceI[] { selectedSequence });
+          launchStructureViewer(ssm, new PDBEntry[] { fileEntry }, ap,
+                  new SequenceI[] { selectedSequence });
     }
     mainFrame.dispose();
+      }
+    }).start();
   }
 
-  private void launchStructureViewer(final StructureSelectionManager ssm,
+  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;
+  }
+
+  private void launchStructureViewer(StructureSelectionManager ssm,
           final PDBEntry[] pdbEntriesToView,
-          final AlignmentPanel alignPanel, final SequenceI[] sequences)
+          final AlignmentPanel alignPanel, SequenceI[] sequences)
   {
+    ssm.setProgressBar("Launching PDB structure viewer..");
     final StructureViewer sViewer = new StructureViewer(ssm);
 
-    new jalview.ws.DBRefFetcher(sequences, null, null, null, false)
-            .fetchDBRefs(true);
-    new Thread(new Runnable()
+    if (SiftsSettings.isMapWithSifts())
     {
-      @Override
-      public void run()
+      for (SequenceI seq : sequences)
       {
+        if (seq.getSourceDBRef() == null)
+        {
+          ssm.setProgressBar(null);
+          ssm.setProgressBar("Fetching Database refs..");
+          new jalview.ws.DBRefFetcher(sequences, null, null, null, false)
+                  .fetchDBRefs(true);
+          break;
+        }
+      }
+    }
         if (pdbEntriesToView.length > 1)
         {
           ArrayList<SequenceI[]> seqsMap = new ArrayList<SequenceI[]>();
@@ -792,14 +874,17 @@ public class StructureChooser extends GStructureChooser
             seqsMap.add(new SequenceI[] { seq });
           }
           SequenceI[][] collatedSeqs = seqsMap.toArray(new SequenceI[0][0]);
+      ssm.setProgressBar(null);
+      ssm.setProgressBar("Fetching PDB Structures for selected entries..");
           sViewer.viewStructures(pdbEntriesToView, collatedSeqs, alignPanel);
         }
         else
         {
+      ssm.setProgressBar(null);
+      ssm.setProgressBar("Fetching PDB Structure for "
+              + pdbEntriesToView[0].getId());
           sViewer.viewStructures(pdbEntriesToView[0], sequences, alignPanel);
         }
-      }
-    }).start();
   }
 
   /**
@@ -841,7 +926,7 @@ public class StructureChooser extends GStructureChooser
     this.structuresDiscovered = structuresDiscovered;
   }
 
-  public Collection<PDBResponseSummary> getDiscoveredStructuresSet()
+  public Collection<FTSData> getDiscoveredStructuresSet()
   {
     return discoveredStructuresSet;
   }
@@ -858,17 +943,18 @@ public class StructureChooser extends GStructureChooser
         isValidPBDEntry = false;
         if (txt_search.getText().length() > 0)
         {
-          List<PDBDocField> wantedFields = new ArrayList<PDBDocField>();
-          wantedFields.add(PDBDocField.PDB_ID);
-          PDBRestRequest pdbRequest = new PDBRestRequest();
+          List<FTSDataColumnI> wantedFields = new ArrayList<FTSDataColumnI>();
+          FTSRestRequest pdbRequest = new FTSRestRequest();
           pdbRequest.setAllowEmptySeq(false);
           pdbRequest.setResponseSize(1);
           pdbRequest.setFieldToSearchBy("(pdb_id:");
           pdbRequest.setWantedFields(wantedFields);
-          pdbRequest.setSearchTerm(txt_search.getText() + ")");
+          pdbRequest
+                  .setSearchTerm(txt_search.getText().toLowerCase() + ")");
           pdbRequest.setAssociatedSequence(selectedSequence);
-          pdbRestCleint = new PDBRestClient();
-          PDBRestResponse resultList;
+          pdbRestCleint = PDBFTSRestClient.getInstance();
+          wantedFields.add(pdbRestCleint.getPrimaryKeyColumn());
+          FTSRestResponse resultList;
           try
           {
             resultList = pdbRestCleint.executeRequest(pdbRequest);
@@ -1008,4 +1094,24 @@ public class StructureChooser extends GStructureChooser
     }
 
   }
+
+  private IProgressIndicator progressBar;
+
+  @Override
+  public void setProgressBar(String message, long id)
+  {
+    progressBar.setProgressBar(message, id);
+  }
+
+  @Override
+  public void registerHandler(long id, IProgressIndicatorHandler handler)
+  {
+    progressBar.registerHandler(id, handler);
+  }
+
+  @Override
+  public boolean operationInProgress()
+  {
+    return progressBar.operationInProgress();
+  }
 }