JAL-4036 use the legacy endpoint (and report the FTS query when debug/trace enabled)
[jalview.git] / src / jalview / fts / service / uniprot / UniProtFTSRestClient.java
index 8a21ffb..2606b62 100644 (file)
 
 package jalview.fts.service.uniprot;
 
-import jalview.fts.api.FTSData;
-import jalview.fts.api.FTSDataColumnI;
-import jalview.fts.api.FTSRestClientI;
-import jalview.fts.core.FTSRestClient;
-import jalview.fts.core.FTSRestRequest;
-import jalview.fts.core.FTSRestResponse;
-import jalview.util.MessageManager;
-
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
@@ -39,53 +31,106 @@ 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;
 
+import jalview.bin.Cache;
+import jalview.bin.Console;
+import jalview.fts.api.FTSData;
+import jalview.fts.api.FTSDataColumnI;
+import jalview.fts.api.FTSRestClientI;
+import jalview.fts.core.FTSRestClient;
+import jalview.fts.core.FTSRestRequest;
+import jalview.fts.core.FTSRestResponse;
+import jalview.util.MessageManager;
+import jalview.util.Platform;
+
 public class UniProtFTSRestClient extends FTSRestClient
 {
+  private static final String DEFAULT_UNIPROT_DOMAIN = "https://legacy.uniprot.org";
+
+  static
+  {
+    Platform.addJ2SDirectDatabaseCall(DEFAULT_UNIPROT_DOMAIN);
+  }
+
   private static FTSRestClientI instance = null;
 
-  public static final String UNIPROT_SEARCH_ENDPOINT = "http://www.uniprot.org/uniprot/?";
+  public final String uniprotSearchEndpoint;
 
+  public UniProtFTSRestClient()
+  {
+    super();
+    uniprotSearchEndpoint = Cache.getDefault("UNIPROT_DOMAIN",
+            DEFAULT_UNIPROT_DOMAIN) + "/uniprot/";
+  }
+
+  @SuppressWarnings("unchecked")
   @Override
-  public FTSRestResponse executeRequest(FTSRestRequest uniportRestRequest)
+  public FTSRestResponse executeRequest(FTSRestRequest uniprotRestRequest)
           throws Exception
   {
     try
     {
-      ClientConfig clientConfig = new DefaultClientConfig();
-      Client client = Client.create(clientConfig);
-
-      String wantedFields = getDataColumnsFieldsAsCommaDelimitedString(uniportRestRequest
-              .getWantedFields());
-      int responseSize = (uniportRestRequest.getResponseSize() == 0) ? getDefaultResponsePageSize()
-              : uniportRestRequest.getResponseSize();
+      String wantedFields = getDataColumnsFieldsAsCommaDelimitedString(
+              uniprotRestRequest.getWantedFields());
+      int responseSize = (uniprotRestRequest.getResponseSize() == 0)
+              ? getDefaultResponsePageSize()
+              : uniprotRestRequest.getResponseSize();
 
-      int offSet = uniportRestRequest.getOffSet();
+      int offSet = uniprotRestRequest.getOffSet();
+      String query;
+      if (isAdvancedQuery(uniprotRestRequest.getSearchTerm()))
+      {
+        query = uniprotRestRequest.getSearchTerm();
+      }
+      else
+      {
+        query = uniprotRestRequest.getFieldToSearchBy()
+                .equalsIgnoreCase("Search All")
+                        ? uniprotRestRequest.getSearchTerm()
+                                + " or mnemonic:"
+                                + uniprotRestRequest.getSearchTerm()
+                        : uniprotRestRequest.getFieldToSearchBy() + ":"
+                                + uniprotRestRequest.getSearchTerm();
+      }
 
-      String query = uniportRestRequest.getFieldToSearchBy()
-              .equalsIgnoreCase("Search All") ? uniportRestRequest
-              .getSearchTerm() : uniportRestRequest.getFieldToSearchBy()
-              + ":" + 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 (Platform.isJS())
+      {
+        // 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
+       * 
+       * @j2sIgnore
+       */
+      {
+        // Java only
+        client = Client.create(new DefaultClientConfig());
+        clientResponseClass = ClientResponse.class;
+      }
 
-      // + (uniportRestRequest.isAllowUnpublishedEntries() ? ""
-      // : " AND status:REL");
-      // System.out.println(">>>>> Query : " + query);
-      // System.out.println(">>>>> Columns : " + wantedFields);
-      // System.out.println(">>>>> Response size: " + responseSize
-      // + " offset : "
-      // + offSet);
       WebResource webResource = null;
-      webResource = client.resource(UNIPROT_SEARCH_ENDPOINT)
+      webResource = client.resource(uniprotSearchEndpoint)
               .queryParam("format", "tab")
               .queryParam("columns", wantedFields)
               .queryParam("limit", String.valueOf(responseSize))
               .queryParam("offset", String.valueOf(offSet))
               .queryParam("sort", "score").queryParam("query", query);
+      if (Console.isDebugEnabled())
+      {
+        Console.debug("Uniprot FTS Request: " + webResource.toString());
+      }
       // Execute the REST request
-      ClientResponse clientResponse = webResource.accept(
-              MediaType.TEXT_PLAIN).get(ClientResponse.class);
+      ClientResponse clientResponse = webResource
+              .accept(MediaType.TEXT_PLAIN).get(clientResponseClass);
       String uniProtTabDelimittedResponseString = clientResponse
               .getEntity(String.class);
       // Make redundant objects eligible for garbage collection to conserve
@@ -99,19 +144,21 @@ public class UniProtFTSRestClient extends FTSRestClient
         throw new Exception(errorMessage);
 
       }
+      int xTotalResults = Platform.isJS() ? 1
+              : Integer.valueOf(clientResponse.getHeaders()
+                      .get("X-Total-Results").get(0));
       clientResponse = null;
       client = null;
       return parseUniprotResponse(uniProtTabDelimittedResponseString,
-              uniportRestRequest);
+              uniprotRestRequest, xTotalResults);
     } catch (Exception e)
     {
       String exceptionMsg = e.getMessage();
       if (exceptionMsg.contains("SocketException"))
       {
         // No internet connection
-        throw new Exception(
-                MessageManager
-                        .getString("exception.unable_to_detect_internet_connection"));
+        throw new Exception(MessageManager.getString(
+                "exception.unable_to_detect_internet_connection"));
       }
       else if (exceptionMsg.contains("UnknownHostException"))
       {
@@ -126,10 +173,21 @@ public class UniProtFTSRestClient extends FTSRestClient
     }
   }
 
+  public boolean isAdvancedQuery(String query)
+  {
+    if (query.contains(" AND ") || query.contains(" OR ")
+            || query.contains(" NOT ") || query.contains(" ! ")
+            || query.contains(" || ") || query.contains(" && ")
+            || query.contains(":") || query.contains("-"))
+    {
+      return true;
+    }
+    return false;
+  }
 
   public FTSRestResponse parseUniprotResponse(
           String uniProtTabDelimittedResponseString,
-          FTSRestRequest uniprotRestRequest)
+          FTSRestRequest uniprotRestRequest, int xTotalResults)
   {
     FTSRestResponse searchResult = new FTSRestResponse();
     List<FTSData> result = null;
@@ -142,58 +200,59 @@ public class UniProtFTSRestClient extends FTSRestClient
     String[] foundDataRow = uniProtTabDelimittedResponseString.split("\n");
     if (foundDataRow != null && foundDataRow.length > 0)
     {
-      result = new ArrayList<FTSData>();
-      String titleRow = getDataColumnsFieldsAsTabDelimitedString(uniprotRestRequest
-              .getWantedFields());
-      // System.out.println(">>>>Title row : " + titleRow);
+      result = new ArrayList<>();
+      boolean firstRow = true;
       for (String dataRow : foundDataRow)
       {
-        if (dataRow.equalsIgnoreCase(titleRow))
+        // The first data row is usually the header data. This should be
+        // filtered out from the rest of the data See: JAL-2485
+        if (firstRow)
         {
-          // System.out.println(">>>>>>>>>> matched!!!");
+          firstRow = false;
           continue;
         }
         // System.out.println(dataRow);
         result.add(getFTSData(dataRow, uniprotRestRequest));
       }
-      searchResult.setNumberOfItemsFound(result.size());
+      searchResult.setNumberOfItemsFound(xTotalResults);
       searchResult.setSearchSummary(result);
     }
     return searchResult;
   }
 
-  /**
-   * Takes a collection of FTSDataColumnI and converts its 'code' values into a
-   * tab delimited string.
-   * 
-   * @param dataColumnFields
-   *          the collection of FTSDataColumnI to process
-   * @return the generated comma delimited string from the supplied
-   *         FTSDataColumnI collection
-   */
-  private String getDataColumnsFieldsAsTabDelimitedString(
-          Collection<FTSDataColumnI> dataColumnFields)
-  {
-    String result = "";
-    if (dataColumnFields != null && !dataColumnFields.isEmpty())
-    {
-      StringBuilder returnedFields = new StringBuilder();
-      for (FTSDataColumnI field : dataColumnFields)
-      {
-        if (field.getName().equalsIgnoreCase("Uniprot Id"))
-        {
-          returnedFields.append("\t").append("Entry");
-        }
-        else
-        {
-          returnedFields.append("\t").append(field.getName());
-        }
-      }
-      returnedFields.deleteCharAt(0);
-      result = returnedFields.toString();
-    }
-    return result;
-  }
+  // /**
+  // * Takes a collection of FTSDataColumnI and converts its 'code' values into
+  // a
+  // * tab delimited string.
+  // *
+  // * @param dataColumnFields
+  // * the collection of FTSDataColumnI to process
+  // * @return the generated comma delimited string from the supplied
+  // * FTSDataColumnI collection
+  // */
+  // private String getDataColumnsFieldsAsTabDelimitedString(
+  // Collection<FTSDataColumnI> dataColumnFields)
+  // {
+  // String result = "";
+  // if (dataColumnFields != null && !dataColumnFields.isEmpty())
+  // {
+  // StringBuilder returnedFields = new StringBuilder();
+  // for (FTSDataColumnI field : dataColumnFields)
+  // {
+  // if (field.getName().equalsIgnoreCase("Uniprot Id"))
+  // {
+  // returnedFields.append("\t").append("Entry");
+  // }
+  // else
+  // {
+  // returnedFields.append("\t").append(field.getName());
+  // }
+  // }
+  // returnedFields.deleteCharAt(0);
+  // result = returnedFields.toString();
+  // }
+  // return result;
+  // }
 
   public static FTSData getFTSData(String tabDelimittedDataStr,
           FTSRestRequest request)
@@ -224,14 +283,17 @@ public class UniProtFTSRestClient extends FTSRestClient
         {
           try
           {
-            summaryRowData[colCounter++] = (field.getDataColumnClass() == Integer.class) ? Integer
-                    .valueOf(fieldData)
-                    : (field.getDataColumnClass() == Double.class) ? Double
-                            .valueOf(fieldData) : fieldData;
+            summaryRowData[colCounter++] = (field.getDataType()
+                    .getDataTypeClass() == Integer.class)
+                            ? Integer.valueOf(fieldData.replace(",", ""))
+                            : (field.getDataType()
+                                    .getDataTypeClass() == Double.class)
+                                            ? Double.valueOf(fieldData)
+                                            : fieldData;
           } catch (Exception e)
           {
             e.printStackTrace();
-              System.out.println("offending value:" + fieldData);
+            System.out.println("offending value:" + fieldData);
           }
         }
       } catch (Exception e)
@@ -290,7 +352,6 @@ public class UniProtFTSRestClient extends FTSRestClient
     };
   }
 
-
   public static FTSRestClientI getInstance()
   {
     if (instance == null)