JSON refactoring
[jalview.git] / src / jalview / fts / service / pdb / PDBFTSRestClient.java
index 8e63463..b4e5660 100644 (file)
@@ -20,6 +20,7 @@
  */
 package jalview.fts.service.pdb;
 
+import jalview.bin.Jalview;
 import jalview.datamodel.SequenceI;
 import jalview.fts.api.FTSData;
 import jalview.fts.api.FTSDataColumnI;
@@ -27,39 +28,37 @@ import jalview.fts.api.FTSRestClientI;
 import jalview.fts.core.FTSRestClient;
 import jalview.fts.core.FTSRestRequest;
 import jalview.fts.core.FTSRestResponse;
+import jalview.util.JSONUtils;
 import jalview.util.MessageManager;
 
+import java.net.URI;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 
 import javax.ws.rs.core.MediaType;
 
-import org.json.simple.JSONArray;
-import org.json.simple.JSONObject;
-import org.json.simple.parser.JSONParser;
 import org.json.simple.parser.ParseException;
 
 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
  * 
  * @author tcnofoegbu
- *
  */
 public class PDBFTSRestClient extends FTSRestClient
 {
 
   private static FTSRestClientI instance = null;
 
-  public static final String PDB_SEARCH_ENDPOINT = "http://www.ebi.ac.uk/pdbe/search/pdb/select?";
+  public static final String PDB_SEARCH_ENDPOINT = "https://www.ebi.ac.uk/pdbe/search/pdb/select?";
 
   protected PDBFTSRestClient()
   {
@@ -73,19 +72,19 @@ public class PDBFTSRestClient extends FTSRestClient
    * @return the pdbResponse object for the given request
    * @throws Exception
    */
+  @SuppressWarnings({ "unused", "unchecked" })
   @Override
   public FTSRestResponse executeRequest(FTSRestRequest pdbRestRequest)
           throws Exception
   {
     try
     {
-      ClientConfig clientConfig = new DefaultClientConfig();
-      Client client = Client.create(clientConfig);
-
-      String wantedFields = getDataColumnsFieldsAsCommaDelimitedString(pdbRestRequest
-              .getWantedFields());
-      int responseSize = (pdbRestRequest.getResponseSize() == 0) ? getDefaultResponsePageSize()
+      String wantedFields = getDataColumnsFieldsAsCommaDelimitedString(
+              pdbRestRequest.getWantedFields());
+      int responseSize = (pdbRestRequest.getResponseSize() == 0)
+              ? getDefaultResponsePageSize()
               : pdbRestRequest.getResponseSize();
+      int offSet = pdbRestRequest.getOffSet();
       String sortParam = null;
       if (pdbRestRequest.getFieldToSortBy() == null
               || pdbRestRequest.getFieldToSortBy().trim().isEmpty())
@@ -107,11 +106,11 @@ public class PDBFTSRestClient extends FTSRestClient
         }
       }
 
-      String facetPivot = (pdbRestRequest.getFacetPivot() == null || pdbRestRequest
-              .getFacetPivot().isEmpty()) ? "" : pdbRestRequest
-              .getFacetPivot();
-      String facetPivotMinCount = String.valueOf(pdbRestRequest
-              .getFacetPivotMinCount());
+      String facetPivot = (pdbRestRequest.getFacetPivot() == null
+              || pdbRestRequest.getFacetPivot().isEmpty()) ? ""
+                      : pdbRestRequest.getFacetPivot();
+      String facetPivotMinCount = String
+              .valueOf(pdbRestRequest.getFacetPivotMinCount());
 
       String query = pdbRestRequest.getFieldToSearchBy()
               + pdbRestRequest.getSearchTerm()
@@ -121,13 +120,32 @@ public class PDBFTSRestClient extends FTSRestClient
                       : " AND status:REL");
 
       // Build request parameters for the REST Request
-      WebResource webResource = null;
+
+      // 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 (Jalview.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
+        client = Client.create(new DefaultClientConfig());
+        clientResponseClass = ClientResponse.class;
+      }
+
+      WebResource webResource;
       if (pdbRestRequest.isFacet())
       {
         webResource = client.resource(PDB_SEARCH_ENDPOINT)
                 .queryParam("wt", "json").queryParam("fl", wantedFields)
                 .queryParam("rows", String.valueOf(responseSize))
                 .queryParam("q", query)
+                .queryParam("start", String.valueOf(offSet))
                 .queryParam("sort", sortParam).queryParam("facet", "true")
                 .queryParam("facet.pivot", facetPivot)
                 .queryParam("facet.pivot.mincount", facetPivotMinCount);
@@ -137,12 +155,15 @@ public class PDBFTSRestClient extends FTSRestClient
         webResource = client.resource(PDB_SEARCH_ENDPOINT)
                 .queryParam("wt", "json").queryParam("fl", wantedFields)
                 .queryParam("rows", String.valueOf(responseSize))
-                .queryParam("q", query)
-                .queryParam("sort", sortParam);
+                .queryParam("start", String.valueOf(offSet))
+                .queryParam("q", query).queryParam("sort", sortParam);
       }
+
+      URI uri = webResource.getURI();
+
       // Execute the REST request
-      ClientResponse clientResponse = webResource.accept(
-              MediaType.APPLICATION_JSON).get(ClientResponse.class);
+      ClientResponse clientResponse = webResource
+              .accept(MediaType.APPLICATION_JSON).get(clientResponseClass );
 
       // Get the JSON string from the response object
       String responseString = clientResponse.getEntity(String.class);
@@ -159,8 +180,8 @@ public class PDBFTSRestClient extends FTSRestClient
         }
         else
         {
-          errorMessage = getMessageByHTTPStatusCode(clientResponse
-                  .getStatus());
+          errorMessage = getMessageByHTTPStatusCode(
+                  clientResponse.getStatus(), "PDB");
           throw new Exception(errorMessage);
         }
       }
@@ -178,16 +199,14 @@ public class PDBFTSRestClient extends FTSRestClient
       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"))
       {
         // The server 'www.ebi.ac.uk' is unreachable
-        throw new Exception(
-                MessageManager
-                        .getString("exception.pdb_server_unreachable"));
+        throw new Exception(MessageManager.formatMessage(
+                "exception.fts_server_unreachable", "PDB Solr"));
       }
       else
       {
@@ -196,36 +215,6 @@ public class PDBFTSRestClient extends FTSRestClient
     }
   }
 
-  public String getMessageByHTTPStatusCode(int code)
-  {
-    String message = "";
-    switch (code)
-    {
-    case 410:
-      message = MessageManager
-              .getString("exception.pdb_rest_service_no_longer_available");
-      break;
-    case 403:
-    case 404:
-      message = MessageManager.getString("exception.resource_not_be_found");
-      break;
-    case 408:
-    case 409:
-    case 500:
-    case 501:
-    case 502:
-    case 503:
-    case 504:
-    case 505:
-      message = MessageManager.getString("exception.pdb_server_error");
-      break;
-
-    default:
-      break;
-    }
-    return message;
-  }
-
   /**
    * Process error response from PDB server if/when one occurs.
    * 
@@ -233,20 +222,40 @@ public class PDBFTSRestClient extends FTSRestClient
    *          the JSON string containing error message from the server
    * @return the processed error message from the JSON string
    */
-  public static String parseJsonExceptionString(String jsonErrorResponse)
+  @SuppressWarnings("unchecked")
+public static String parseJsonExceptionString(String jsonErrorResponse)
   {
     StringBuilder errorMessage = new StringBuilder(
             "\n============= PDB Rest Client RunTime error =============\n");
 
+    
+//    {
+//      "responseHeader":{
+//        "status":0,
+//        "QTime":0,
+//        "params":{
+//          "q":"(text:q93xj9_soltu) AND molecule_sequence:['' TO *] AND status:REL",
+//          "fl":"pdb_id,title,experimental_method,resolution",
+//          "start":"0",
+//          "sort":"overall_quality desc",
+//          "rows":"500",
+//          "wt":"json"}},
+//      "response":{"numFound":1,"start":0,"docs":[
+//          {
+//            "experimental_method":["X-ray diffraction"],
+//            "pdb_id":"4zhp",
+//            "resolution":2.46,
+//            "title":"The crystal structure of Potato ferredoxin I with 2Fe-2S cluster"}]
+//      }}
+//    
     try
     {
-      JSONParser jsonParser = new JSONParser();
-      JSONObject jsonObj = (JSONObject) jsonParser.parse(jsonErrorResponse);
-      JSONObject errorResponse = (JSONObject) jsonObj.get("error");
+      Map<String, Object> jsonObj = (Map<String, Object>) JSONUtils.parse(jsonErrorResponse);
+      Map<String, Object> errorResponse = (Map<String, Object>) jsonObj.get("error");
 
-      JSONObject responseHeader = (JSONObject) jsonObj
+      Map<String, Object> responseHeader = (Map<String, Object>) jsonObj
               .get("responseHeader");
-      JSONObject paramsObj = (JSONObject) responseHeader.get("params");
+      Map<String, Object> paramsObj = (Map<String, Object>) responseHeader.get("params");
       String status = responseHeader.get("status").toString();
       String message = errorResponse.get("msg").toString();
       String query = paramsObj.get("q").toString();
@@ -284,23 +293,20 @@ public class PDBFTSRestClient extends FTSRestClient
     List<FTSData> result = null;
     try
     {
-      JSONParser jsonParser = new JSONParser();
-      JSONObject jsonObj = (JSONObject) jsonParser
-              .parse(pdbJsonResponseString);
-
-      JSONObject pdbResponse = (JSONObject) jsonObj.get("response");
-      String queryTime = ((JSONObject) jsonObj.get("responseHeader")).get(
-              "QTime").toString();
+      Map<String, Object> jsonObj = (Map<String, Object>) JSONUtils.parse(pdbJsonResponseString);
+      Map<String, Object> pdbResponse = (Map<String, Object>) jsonObj.get("response");
+      String queryTime = ((Map<String, Object>) jsonObj.get("responseHeader"))
+              .get("QTime").toString();
       int numFound = Integer
               .valueOf(pdbResponse.get("numFound").toString());
       if (numFound > 0)
       {
         result = new ArrayList<FTSData>();
-        JSONArray docs = (JSONArray) pdbResponse.get("docs");
-        for (Iterator<JSONObject> docIter = docs.iterator(); docIter
+        List<Object> docs = (List<Object>) pdbResponse.get("docs");
+        for (Iterator<Object> docIter = docs.iterator(); docIter
                 .hasNext();)
         {
-          JSONObject doc = docIter.next();
+          Map<String, Object> doc = (Map<String, Object>) docIter.next();
           result.add(getFTSData(doc, pdbRestRequest));
         }
         searchResult.setNumberOfItemsFound(numFound);
@@ -314,7 +320,7 @@ public class PDBFTSRestClient extends FTSRestClient
     return searchResult;
   }
 
-  public static FTSData getFTSData(JSONObject pdbJsonDoc,
+  public static FTSData getFTSData(Map<String, Object> pdbJsonDoc,
           FTSRestRequest request)
   {
 
@@ -327,8 +333,9 @@ public class PDBFTSRestClient extends FTSRestClient
     Collection<FTSDataColumnI> diplayFields = request.getWantedFields();
     SequenceI associatedSeq = request.getAssociatedSequence();
     int colCounter = 0;
-    summaryRowData = new Object[(associatedSeq != null) ? diplayFields
-            .size() + 1 : diplayFields.size()];
+    summaryRowData = new Object[(associatedSeq != null)
+            ? diplayFields.size() + 1
+            : diplayFields.size()];
     if (associatedSeq != null)
     {
       associatedSequence = associatedSeq;
@@ -353,15 +360,17 @@ public class PDBFTSRestClient 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)
+                          : (field.getDataType()
+                                  .getDataTypeClass() == Double.class)
+                                          ? Double.valueOf(fieldData)
+                                          : sanitiseData(fieldData);
         } catch (Exception e)
         {
           e.printStackTrace();
-            System.out.println("offending value:" + fieldData);
+          System.out.println("offending value:" + fieldData);
         }
       }
     }
@@ -407,16 +416,29 @@ public class PDBFTSRestClient extends FTSRestClient
       {
         return Objects.hash(primaryKey1, this.toString());
       }
+
+      @Override
+      public boolean equals(Object that)
+      {
+        return this.toString().equals(that.toString());
+      }
     };
   }
 
+  private static String sanitiseData(String data)
+  {
+    String cleanData = data.replaceAll("\\[\"", "").replaceAll("\\]\"", "")
+            .replaceAll("\\[", "").replaceAll("\\]", "")
+            .replaceAll("\",\"", ", ").replaceAll("\"", "");
+    return cleanData;
+  }
+
   @Override
   public String getColumnDataConfigFileName()
   {
-    return getResourceFile("/fts/pdb_data_columns.conf");
+    return "/fts/pdb_data_columns.txt";
   }
 
-
   public static FTSRestClientI getInstance()
   {
     if (instance == null)
@@ -425,4 +447,47 @@ public class PDBFTSRestClient extends FTSRestClient
     }
     return instance;
   }
+
+  private Collection<FTSDataColumnI> allDefaultDisplayedStructureDataColumns;
+
+  public Collection<FTSDataColumnI> getAllDefaultDisplayedStructureDataColumns()
+  {
+    if (allDefaultDisplayedStructureDataColumns == null
+            || allDefaultDisplayedStructureDataColumns.isEmpty())
+    {
+      allDefaultDisplayedStructureDataColumns = new ArrayList<FTSDataColumnI>();
+      allDefaultDisplayedStructureDataColumns
+              .addAll(super.getAllDefaultDisplayedFTSDataColumns());
+    }
+    return allDefaultDisplayedStructureDataColumns;
+  }
+  
+  @SuppressWarnings("unchecked")
+public static void main(String[] args) {
+    
+    
+    // check for transpiler fix associated with JSONParser yylex.java use of charAt()
+    // instead of codePointAt()
+
+    String s = "e";
+    char c = 'c';
+    char f = 'f';
+    s += c | f; 
+    int x = c&f;
+    int y = 2 & c;
+    int z = c ^ 5;
+    String result = s +x + y + z;
+    assert (result == "e103982102");
+    try
+    {
+      Map<String, Object> jsonObj = (Map<String, Object>) JSONUtils.parse("{\"a\":3}");
+      System.out.println(jsonObj);
+    } catch (ParseException e)
+    {
+      e.printStackTrace();
+    }
+    
+  }
+  
+  
 }