TDB.executeRequest fix & test passed
[jalview.git] / src / jalview / fts / service / threedbeacons / TDBeaconsFTSRestClient.java
1 package jalview.fts.service.threedbeacons;
2
3 import java.net.URI;
4 import java.util.ArrayList;
5 import java.util.Collection;
6 import java.util.Iterator;
7 import java.util.List;
8 import java.util.Map;
9 import java.util.Objects;
10
11 import javax.ws.rs.core.MediaType;
12
13 import org.json.simple.parser.ParseException;
14
15 import com.sun.jersey.api.client.Client;
16 import com.sun.jersey.api.client.ClientResponse;
17 import com.sun.jersey.api.client.WebResource;
18 import com.sun.jersey.api.client.config.DefaultClientConfig;
19
20 import jalview.datamodel.SequenceI;
21 import jalview.fts.api.FTSData;
22 import jalview.fts.api.FTSDataColumnI;
23 import jalview.fts.api.FTSRestClientI;
24 import jalview.fts.core.FTSRestClient;
25 import jalview.fts.core.FTSRestRequest;
26 import jalview.fts.core.FTSRestResponse;
27 import jalview.fts.service.pdb.PDBFTSRestClient;
28 import jalview.util.JSONUtils;
29 import jalview.util.MessageManager;
30 import jalview.util.Platform;
31
32 public class TDBeaconsFTSRestClient extends FTSRestClient
33 {
34   private static final String DEFAULT_THREEDBEACONS_DOMAIN = 
35           "https://wwwdev.ebi.ac.uk/pdbe/pdbe-kb/3dbeacons-hub-api/uniprot/";
36   
37   private static FTSRestClientI instance = null;
38   
39   protected TDBeaconsFTSRestClient()
40   {   
41   }
42   
43   @SuppressWarnings("unchecked")
44   @Override
45   public FTSRestResponse executeRequest(FTSRestRequest tdbRestRequest)
46           throws Exception
47   {
48     try
49     {
50       // Removed wantedFields, sortParam & facetPivot from PDBFTSRClient
51       String wantedFields = getDataColumnsFieldsAsCommaDelimitedString(
52               tdbRestRequest.getWantedFields());
53       int responseSize = (tdbRestRequest.getResponseSize() == 0)
54               ? getDefaultResponsePageSize()
55               : tdbRestRequest.getResponseSize();
56       //int offSet = pdbRestRequest.getOffSet();
57       
58       String query = tdbRestRequest.getFieldToSearchBy()
59               + tdbRestRequest.getSearchTerm();
60       Client client;
61       Class<ClientResponse> clientResponseClass;
62       if (Platform.isJS())
63       {
64         // JavaScript only
65         client = (Client) (Object) new jalview.javascript.web.Client();
66         clientResponseClass = (Class<ClientResponse>) (Object) jalview.javascript.web.ClientResponse.class;
67       }
68       else
69       /**
70        * Java only
71        * @j2sIgnore
72        */
73       {
74         client = Client.create(new DefaultClientConfig());
75         clientResponseClass = ClientResponse.class;
76       }
77       WebResource webResource;
78       webResource = client.resource(DEFAULT_THREEDBEACONS_DOMAIN).path(query);
79       URI uri = webResource.getURI();
80 //              .queryParam("P", query);
81 //              .queryParam("rows", String.valueOf(responseSize))
82 //              .queryParam("P",query);
83 //      URI uri = webResource.getURI();
84       System.out.println(uri.toString());
85         
86       // Execute the REST request
87       ClientResponse clientResponse = webResource
88               .accept(MediaType.APPLICATION_JSON).get(clientResponseClass);
89   
90       // Get the JSON string from the response object or directly from the
91       // client (JavaScript)
92       Map<String, Object> jsonObj = null;
93       String responseString = null;
94   
95       //System.out.println("query >>>>>>> " + tdbRestRequest.toString());
96         
97       // Check the response status and report exception if one occurs
98       int responseStatus = clientResponse.getStatus();
99       switch (responseStatus)
100       {
101       // if succesful
102       case 200:
103         if (Platform.isJS())
104         {
105           jsonObj = clientResponse.getEntity(Map.class);
106         }
107         else
108         {
109           responseString = clientResponse.getEntity(String.class);
110         }
111         break;
112       case 400:
113         throw new Exception(parseJsonExceptionString(responseString));
114       default:
115         throw new Exception(
116                 getMessageByHTTPStatusCode(responseStatus, "3DBeacons"));
117       }
118       // Process the response and return the result to the caller.
119       return parseTDBeaconsJsonResponse(responseString, jsonObj, tdbRestRequest);
120     } catch (Exception e)
121     {
122       String exceptionMsg = e.getMessage();
123       if (exceptionMsg.contains("SocketException"))
124       {
125         // No internet connection
126         throw new Exception(MessageManager.getString(
127                 "exception.unable_to_detect_internet_connection"));
128       }
129       else if (exceptionMsg.contains("UnknownHostException"))
130       {
131         // The server is unreachable
132         throw new Exception(MessageManager.formatMessage(
133                 "exception.fts_server_unreachable", "3DB Hub"));
134       }
135       else
136       {
137         throw e;
138       }
139     }
140       
141   }
142   
143   public String setSearchTerm(String term) {
144     return term;
145   }
146   
147   public static FTSRestResponse parseTDBeaconsJsonResponse(
148           String tdbJsonResponseString, FTSRestRequest tdbRestRequest)
149   {
150     return parseTDBeaconsJsonResponse(tdbJsonResponseString,
151             (Map<String, Object>) null, tdbRestRequest);
152   }
153   
154   @SuppressWarnings("unchecked")
155   public static FTSRestResponse parseTDBeaconsJsonResponse(String tdbJsonResponseString,
156           Map<String, Object> jsonObj, FTSRestRequest tdbRestRequest)
157   {
158     FTSRestResponse searchResult = new FTSRestResponse();
159     //searchResult.setNumberOfItemsFound(1);
160     List<FTSData> result = null;
161     
162     try
163     {
164       if (jsonObj == null)
165       {
166         jsonObj = (Map<String, Object>) JSONUtils.parse(tdbJsonResponseString);
167       }
168       //Map<String, Object> tdbResponse = (Map<String, Object>) jsonObj.get("structures");
169       //String seqLength = tdbEntry.get("sequence_length").toString();
170       //int seqLength = Integer.valueOf(tdbEntry.get("sequence_length").toString());
171       
172       Long seqLength = (Long) ((Map<String, Object>) jsonObj.get("uniprot_entry")).get("sequence_length");
173       result = new ArrayList<>();
174       List<Object> structures = (List<Object>) jsonObj.get("structures");
175       int numFound = 0;
176       for (Iterator<Object> strucIter = structures.iterator(); strucIter
177               .hasNext();)
178       {
179         Map<String, Object> structure = (Map<String, Object>) strucIter.next();
180         result.add(getFTSData(structure, tdbRestRequest));
181         numFound++;
182       }
183         searchResult.setNumberOfItemsFound(numFound); 
184         searchResult.setSearchSummary(result);
185         searchResult.setSequenceLength(seqLength);
186         
187     } catch (ParseException e)
188     {
189       e.printStackTrace();
190     }
191     return searchResult;
192   }
193
194 private static FTSData getFTSData(Map<String, Object> tdbJsonStructure,
195           FTSRestRequest tdbRequest)
196   {
197     // TODO Auto-generated method stub
198     String primaryKey = null;
199     Object[] summaryRowData;
200     Collection<FTSDataColumnI> displayFields = tdbRequest.getWantedFields();
201     int colCounter = 0;
202     summaryRowData = new Object[displayFields.size()];
203     for (FTSDataColumnI field : displayFields) {
204       String fieldData = (tdbJsonStructure.get(field.getCode()) == null) ? " " 
205               : tdbJsonStructure.get(field.getCode()).toString();
206       if (field.isPrimaryKeyColumn())
207       {
208         primaryKey = fieldData;
209         summaryRowData[colCounter++] = primaryKey;
210       }
211       else if (fieldData == null || fieldData.isEmpty())
212       {
213         summaryRowData[colCounter++] = null;
214       }
215       else 
216       {
217         try
218         {
219           summaryRowData[colCounter++] = (field.getDataType()
220                   .getDataTypeClass() == Integer.class)
221                           ? Integer.valueOf(fieldData)
222                           : (field.getDataType()
223                                   .getDataTypeClass() == Double.class)
224                                           ? Double.valueOf(fieldData)
225                                           : fieldData;
226         } catch (Exception e)
227         {
228           e.printStackTrace();
229           System.out.println("offending value:" + fieldData);
230         }
231       }
232     }
233     final String primaryKey1 = primaryKey;
234     final Object[] summaryRowData1 = summaryRowData;
235     
236     return new FTSData()
237     {
238
239       @Override
240       public Object[] getSummaryData()
241       {
242         return summaryRowData1;
243       }
244
245       @Override
246       public Object getPrimaryKey()
247       {
248         return primaryKey1;
249       }
250       
251       /**
252        * Returns a string representation of this object;
253        */
254       @Override
255       public String toString()
256       {
257         StringBuilder summaryFieldValues = new StringBuilder();
258         for (Object summaryField : summaryRowData1)
259         {
260           summaryFieldValues.append(
261                   summaryField == null ? " " : summaryField.toString())
262                   .append("\t");
263         }
264         return summaryFieldValues.toString();
265       }
266       
267       /**
268        * Returns hash code value for this object
269        */
270       @Override
271       public int hashCode()
272       {
273         return Objects.hash(primaryKey1, this.toString());
274       }
275
276       @Override
277       public boolean equals(Object that)
278       {
279         return this.toString().equals(that.toString());
280       }
281     };
282   }
283
284 //  private static FTSData getFTSData(Map<String, Object> doc,
285 //          FTSRestRequest tdbRestRequest)
286 //  {
287 //    String primaryKey = null;
288 //
289 //    Object[] summaryRowData;
290 //
291 //    Collection<FTSDataColumnI> displayFields = tdbRestRequest.getWantedFields();
292 //    int colCounter = 0;
293 //    summaryRowData = new Object[displayFields.size() + 1];
294 // 
295 //    return null;
296 //  }
297
298   private String parseJsonExceptionString(String jsonErrorString)
299   {
300     // TODO Auto-generated method stub
301     return null;
302   }
303
304   @Override
305   public String getColumnDataConfigFileName()
306   {
307     return "/fts/tdbeacons_data_columns.txt";
308   }
309   
310   public static FTSRestClientI getInstance()
311   {
312     if (instance == null)
313     {
314       instance = new TDBeaconsFTSRestClient();
315     }
316     return instance;
317   }
318   
319   private Collection<FTSDataColumnI> allDefaultDisplayedStructureDataColumns;
320
321   public Collection<FTSDataColumnI> getAllDefaultDisplayedStructureDataColumns()
322   {
323     if (allDefaultDisplayedStructureDataColumns == null
324             || allDefaultDisplayedStructureDataColumns.isEmpty())
325     {
326       allDefaultDisplayedStructureDataColumns = new ArrayList<>();
327       allDefaultDisplayedStructureDataColumns
328               .addAll(super.getAllDefaultDisplayedFTSDataColumns());
329     }
330     return allDefaultDisplayedStructureDataColumns;
331   }
332   
333 }