e9564615252928532bf4b35fc2817b07c2acc2f6
[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/api/uniprot/summary/";
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       String query = tdbRestRequest.getSearchTerm();
51       Client client;
52       Class<ClientResponse> clientResponseClass;
53       if (Platform.isJS())
54       {
55         // JavaScript only
56         client = (Client) (Object) new jalview.javascript.web.Client();
57         clientResponseClass = (Class<ClientResponse>) (Object) jalview.javascript.web.ClientResponse.class;
58       }
59       else
60       /**
61        * Java only
62        * @j2sIgnore
63        */
64       {
65         client = Client.create(new DefaultClientConfig());
66         clientResponseClass = ClientResponse.class;
67       }
68       WebResource webResource;
69       webResource = client.resource(DEFAULT_THREEDBEACONS_DOMAIN)
70               .path(query);
71       URI uri = webResource.getURI();
72       System.out.println(uri.toString());
73         
74       // Execute the REST request
75       ClientResponse clientResponse = webResource
76               .accept(MediaType.APPLICATION_JSON).get(clientResponseClass);
77   
78       // Get the JSON string from the response object or directly from the
79       // client (JavaScript)
80       Map<String, Object> jsonObj = null;
81       String responseString = null;
82   
83       // Check the response status and report exception if one occurs
84       int responseStatus = clientResponse.getStatus();
85       switch (responseStatus)
86       {
87       // if success
88       case 200:
89         if (Platform.isJS())
90         {
91           jsonObj = clientResponse.getEntity(Map.class);
92         }
93         else
94         {
95           responseString = clientResponse.getEntity(String.class);
96         }
97         break;
98       case 400:
99         throw new Exception(parseJsonExceptionString(responseString));
100       default:
101         throw new Exception(
102                 getMessageByHTTPStatusCode(responseStatus, "3DBeacons"));
103       }
104       // Process the response and return the result to the caller.
105       return parseTDBeaconsJsonResponse(responseString, jsonObj, tdbRestRequest);
106     } catch (Exception e)
107     {
108       String exceptionMsg = e.getMessage();
109       if (exceptionMsg.contains("SocketException"))
110       {
111         // No internet connection
112         throw new Exception(MessageManager.getString(
113                 "exception.unable_to_detect_internet_connection"));
114       }
115       else if (exceptionMsg.contains("UnknownHostException"))
116       {
117         // The server is unreachable
118         throw new Exception(MessageManager.formatMessage(
119                 "exception.fts_server_unreachable", "3DB Hub"));
120       }
121       else
122       {
123         throw e;
124       }
125     }
126       
127   }
128   
129   public String setSearchTerm(String term) {
130     return term;
131   }
132   
133   public static FTSRestResponse parseTDBeaconsJsonResponse(
134           String tdbJsonResponseString, FTSRestRequest tdbRestRequest)
135   {
136     return parseTDBeaconsJsonResponse(tdbJsonResponseString,
137             (Map<String, Object>) null, tdbRestRequest);
138   }
139   
140   @SuppressWarnings("unchecked")
141   public static FTSRestResponse parseTDBeaconsJsonResponse(String tdbJsonResponseString,
142           Map<String, Object> jsonObj, FTSRestRequest tdbRestRequest)
143   {
144     FTSRestResponse searchResult = new FTSRestResponse();
145     List<FTSData> result = null;
146     
147     try
148     {
149       if (jsonObj == null)
150       {
151         jsonObj = (Map<String, Object>) JSONUtils.parse(tdbJsonResponseString);
152       }
153       
154       Object uniprot_entry = jsonObj.get("uniprot_entry"); 
155       // TODO: decide if anything from uniprot_entry needs to be reported via the FTSRestResponse object
156       // Arnaud added seqLength = (Long) ((Map<String, Object>) jsonObj.get("uniprot_entry")).get("sequence_length");
157
158       List<Object> structures = (List<Object>) jsonObj.get("structures");
159       result = new ArrayList<>();
160       
161       int numFound = 0;
162       for (Iterator<Object> strucIter = structures.iterator(); strucIter.hasNext();)
163       {
164         Map<String, Object> structure = (Map<String, Object>) strucIter.next();
165         result.add(getFTSData(structure, tdbRestRequest));
166         numFound++;
167       }
168       
169       searchResult.setNumberOfItemsFound(numFound); 
170       searchResult.setSearchSummary(result);
171         
172     } catch (ParseException e)
173     {
174       e.printStackTrace();
175     }
176     return searchResult;
177   }
178
179 private static FTSData getFTSData(Map<String, Object> tdbJsonStructure,
180           FTSRestRequest tdbRequest)
181   {
182     // TODO Auto-generated method stub
183     String primaryKey = null;
184     Object[] summaryRowData;
185     Collection<FTSDataColumnI> displayFields = tdbRequest.getWantedFields();
186     int colCounter = 0;
187     summaryRowData = new Object[displayFields.size()];
188     
189     for (FTSDataColumnI field : displayFields) {
190       String fieldData = (tdbJsonStructure.get(field.getCode()) == null) ? " " 
191               : tdbJsonStructure.get(field.getCode()).toString();
192       // System.out.println("Field : " + field + "  Data : " + fieldData);
193       if (field.isPrimaryKeyColumn())
194       {
195         primaryKey = fieldData;
196         summaryRowData[colCounter++] = primaryKey;
197       }
198       else if (fieldData == null || fieldData.trim().isEmpty())
199       {
200         summaryRowData[colCounter++] = null;
201       }
202       else 
203       {
204         try
205         {
206           summaryRowData[colCounter++] = (field.getDataType()
207                   .getDataTypeClass() == Integer.class)
208                           ? Integer.valueOf(fieldData)
209                           : (field.getDataType()
210                                   .getDataTypeClass() == Double.class)
211                                           ? Double.valueOf(fieldData)
212                                           : fieldData;
213         } catch (Exception e)
214         {
215           //e.printStackTrace();
216           System.out.println("offending value:" + fieldData + fieldData);
217         }
218       }
219     }
220     final String primaryKey1 = primaryKey;
221     final Object[] summaryRowData1 = summaryRowData;
222     
223     return new FTSData()
224     {
225
226       @Override
227       public Object[] getSummaryData()
228       {
229         return summaryRowData1;
230       }
231
232       @Override
233       public Object getPrimaryKey()
234       {
235         return primaryKey1;
236       }
237       
238       /**
239        * Returns a string representation of this object;
240        */
241       @Override
242       public String toString()
243       {
244         StringBuilder summaryFieldValues = new StringBuilder();
245         for (Object summaryField : summaryRowData1)
246         {
247           summaryFieldValues.append(
248                   summaryField == null ? " " : summaryField.toString())
249                   .append("\t");
250         }
251         return summaryFieldValues.toString();
252       }
253       
254       /**
255        * Returns hash code value for this object
256        */
257       @Override
258       public int hashCode()
259       {
260         return Objects.hash(primaryKey1, this.toString());
261       }
262
263       @Override
264       public boolean equals(Object that)
265       {
266         return this.toString().equals(that.toString());
267       }
268     };
269   }
270
271 //  private static FTSData getFTSData(Map<String, Object> doc,
272 //          FTSRestRequest tdbRestRequest)
273 //  {
274 //    String primaryKey = null;
275 //
276 //    Object[] summaryRowData;
277 //
278 //    Collection<FTSDataColumnI> displayFields = tdbRestRequest.getWantedFields();
279 //    int colCounter = 0;
280 //    summaryRowData = new Object[displayFields.size() + 1];
281 // 
282 //    return null;
283 //  }
284
285   private String parseJsonExceptionString(String jsonErrorString)
286   {
287     // TODO Auto-generated method stub
288     return null;
289   }
290
291   @Override
292   public String getColumnDataConfigFileName()
293   {
294     return "/fts/tdbeacons_data_columns.txt";
295   }
296   
297   public static FTSRestClientI getInstance()
298   {
299     if (instance == null)
300     {
301       instance = new TDBeaconsFTSRestClient();
302     }
303     return instance;
304   }
305   
306   private Collection<FTSDataColumnI> allDefaultDisplayedStructureDataColumns;
307
308   public Collection<FTSDataColumnI> getAllDefaultDisplayedStructureDataColumns()
309   {
310     if (allDefaultDisplayedStructureDataColumns == null
311             || allDefaultDisplayedStructureDataColumns.isEmpty())
312     {
313       allDefaultDisplayedStructureDataColumns = new ArrayList<>();
314       allDefaultDisplayedStructureDataColumns
315               .addAll(super.getAllDefaultDisplayedFTSDataColumns());
316     }
317     return allDefaultDisplayedStructureDataColumns;
318   }
319   
320 }