2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
21 package jalview.fts.service.threedbeacons;
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.Iterator;
27 import java.util.List;
30 import javax.ws.rs.core.MediaType;
32 import org.json.simple.parser.ParseException;
34 import com.sun.jersey.api.client.Client;
35 import com.sun.jersey.api.client.ClientResponse;
36 import com.sun.jersey.api.client.WebResource;
37 import com.sun.jersey.api.client.config.DefaultClientConfig;
39 import jalview.bin.Console;
40 import jalview.datamodel.SequenceI;
41 import jalview.fts.api.FTSData;
42 import jalview.fts.api.FTSDataColumnI;
43 import jalview.fts.api.FTSRestClientI;
44 import jalview.fts.api.StructureFTSRestClientI;
45 import jalview.fts.core.FTSDataColumnPreferences.PreferenceSource;
46 import jalview.fts.core.FTSRestClient;
47 import jalview.fts.core.FTSRestRequest;
48 import jalview.fts.core.FTSRestResponse;
49 import jalview.util.JSONUtils;
50 import jalview.util.MessageManager;
51 import jalview.util.Platform;
53 public class TDBeaconsFTSRestClient extends FTSRestClient
54 implements StructureFTSRestClientI
57 * production server URI
59 private static String TDB_PROD_API = "https://www.ebi.ac.uk/pdbe/pdbe-kb/3dbeacons/api/uniprot/summary/";
64 private static String TDB_DEV_API = "https://wwwdev.ebi.ac.uk/pdbe/pdbe-kb/3dbeacons/api/uniprot/summary/";
66 private static String DEFAULT_THREEDBEACONS_DOMAIN = TDB_PROD_API;
68 public static FTSRestClientI instance = null;
72 Platform.addJ2SDirectDatabaseCall(DEFAULT_THREEDBEACONS_DOMAIN);
75 protected TDBeaconsFTSRestClient()
79 @SuppressWarnings("unchecked")
81 public FTSRestResponse executeRequest(FTSRestRequest tdbRestRequest)
86 String query = tdbRestRequest.getSearchTerm();
88 Class<ClientResponse> clientResponseClass;
92 client = (Client) (Object) new jalview.javascript.web.Client();
93 clientResponseClass = (Class<ClientResponse>) (Object) jalview.javascript.web.ClientResponse.class;
102 client = Client.create(new DefaultClientConfig());
103 clientResponseClass = ClientResponse.class;
106 WebResource webResource;
107 webResource = client.resource(DEFAULT_THREEDBEACONS_DOMAIN + query);
109 URI uri = webResource.getURI();
110 Console.info("3DBeacons URL: " + uri.toString());
112 // Execute the REST request
113 ClientResponse clientResponse;
116 clientResponse = null;
120 clientResponse = webResource.accept(MediaType.APPLICATION_JSON)
121 .get(clientResponseClass);
124 // Get the JSON string from the response object or directly from the
125 // client (JavaScript)
126 Map<String, Object> jsonObj = null;
127 String responseString = null;
129 // Check the response status and report exception if one occurs
130 int responseStatus = isMocked()
131 ? (mockQueries.containsKey(query) ? 200 : 404)
132 : clientResponse.getStatus();
133 switch (responseStatus)
139 jsonObj = clientResponse.getEntity(Map.class);
143 responseString = isMocked() ? mockQueries.get(query)
144 : clientResponse.getEntity(String.class);
148 throw new Exception(parseJsonExceptionString(responseString));
150 return emptyTDBeaconsJsonResponse();
153 getMessageByHTTPStatusCode(responseStatus, "3DBeacons"));
155 // Process the response and return the result to the caller.
156 return parseTDBeaconsJsonResponse(responseString, jsonObj,
158 } catch (Exception e)
160 String exceptionMsg = e.getMessage();
161 if (exceptionMsg != null)
163 if (exceptionMsg.contains("SocketException"))
165 // No internet connection
166 throw new Exception(MessageManager.getString(
167 "exception.unable_to_detect_internet_connection"));
169 else if (exceptionMsg.contains("UnknownHostException"))
171 // The server is unreachable
172 throw new Exception(MessageManager.formatMessage(
173 "exception.fts_server_unreachable", "3DB Hub"));
183 * returns response for when the 3D-Beacons service doesn't have a record for
184 * the given query - in 2.11.2 this triggers a failover to the PDBe FTS
188 private FTSRestResponse emptyTDBeaconsJsonResponse()
193 public String setSearchTerm(String term)
198 public static FTSRestResponse parseTDBeaconsJsonResponse(
199 String tdbJsonResponseString, FTSRestRequest tdbRestRequest)
201 return parseTDBeaconsJsonResponse(tdbJsonResponseString,
202 (Map<String, Object>) null, tdbRestRequest);
205 @SuppressWarnings("unchecked")
206 public static FTSRestResponse parseTDBeaconsJsonResponse(
207 String tdbJsonResponseString, Map<String, Object> jsonObj,
208 FTSRestRequest tdbRestRequest)
210 FTSRestResponse searchResult = new FTSRestResponse();
211 List<FTSData> result = null;
217 jsonObj = (Map<String, Object>) JSONUtils
218 .parse(tdbJsonResponseString);
221 Object uniprot_entry = jsonObj.get("uniprot_entry");
222 // TODO: decide if anything from uniprot_entry needs to be reported via
223 // the FTSRestResponse object
224 // Arnaud added seqLength = (Long) ((Map<String, Object>)
225 // jsonObj.get("uniprot_entry")).get("sequence_length");
227 List<Object> structures = (List<Object>) jsonObj.get("structures");
228 result = new ArrayList<>();
231 for (Iterator<Object> strucIter = structures.iterator(); strucIter
234 Map<String, Object> structure = (Map<String, Object>) strucIter
236 result.add(getFTSData(structure, tdbRestRequest));
240 searchResult.setNumberOfItemsFound(numFound);
241 searchResult.setSearchSummary(result);
243 } catch (ParseException e)
250 private static FTSData getFTSData(
251 Map<String, Object> tdbJsonStructureSummary,
252 FTSRestRequest tdbRequest)
254 String primaryKey = null;
255 Object[] summaryRowData;
257 SequenceI associatedSequence;
259 Collection<FTSDataColumnI> displayFields = tdbRequest.getWantedFields();
260 SequenceI associatedSeq = tdbRequest.getAssociatedSequence();
262 summaryRowData = new Object[(associatedSeq != null)
263 ? displayFields.size() + 1
264 : displayFields.size()];
265 if (associatedSeq != null)
267 associatedSequence = associatedSeq;
268 summaryRowData[0] = associatedSequence;
271 Map<String, Object> tdbJsonStructure = (Map<String, Object>) tdbJsonStructureSummary
273 for (FTSDataColumnI field : displayFields)
275 String fieldData = (tdbJsonStructure.get(field.getCode()) == null)
277 : tdbJsonStructure.get(field.getCode()).toString();
278 // Console.outPrintln("Field : " + field + " Data : " + fieldData);
279 if (field.isPrimaryKeyColumn())
281 primaryKey = fieldData;
282 summaryRowData[colCounter++] = primaryKey;
284 else if (fieldData == null || fieldData.trim().isEmpty())
286 summaryRowData[colCounter++] = null;
292 summaryRowData[colCounter++] = (field.getDataType()
293 .getDataTypeClass() == Integer.class)
294 ? Integer.valueOf(fieldData)
295 : (field.getDataType()
296 .getDataTypeClass() == Double.class)
297 ? Double.valueOf(fieldData)
299 } catch (Exception e)
301 // e.printStackTrace();
302 Console.warn("offending value:" + fieldData + fieldData);
306 final String primaryKey1 = primaryKey;
307 final Object[] summaryRowData1 = summaryRowData;
309 return new TDB_FTSData(primaryKey, tdbJsonStructure, summaryRowData1);
312 // private static FTSData getFTSData(Map<String, Object> doc,
313 // FTSRestRequest tdbRestRequest)
315 // String primaryKey = null;
317 // Object[] summaryRowData;
319 // Collection<FTSDataColumnI> displayFields =
320 // tdbRestRequest.getWantedFields();
321 // int colCounter = 0;
322 // summaryRowData = new Object[displayFields.size() + 1];
327 private String parseJsonExceptionString(String jsonErrorString)
329 // TODO Auto-generated method stub
334 public String getColumnDataConfigFileName()
336 return "/fts/tdbeacons_data_columns.txt";
339 public static FTSRestClientI getInstance()
341 if (instance == null)
343 instance = new TDBeaconsFTSRestClient();
348 private Collection<FTSDataColumnI> allDefaultDisplayedStructureDataColumns;
351 public Collection<FTSDataColumnI> getAllDefaultDisplayedStructureDataColumns()
353 if (allDefaultDisplayedStructureDataColumns == null
354 || allDefaultDisplayedStructureDataColumns.isEmpty())
356 allDefaultDisplayedStructureDataColumns = new ArrayList<>();
357 allDefaultDisplayedStructureDataColumns
358 .addAll(super.getAllDefaultDisplayedFTSDataColumns());
360 return allDefaultDisplayedStructureDataColumns;
364 public String[] getPreferencesColumnsFor(PreferenceSource source)
366 String[] columnNames = null;
370 columnNames = new String[] { "", "Display", "Group" };
372 case STRUCTURE_CHOOSER:
373 columnNames = new String[] { "", "Display", "Group" };
376 columnNames = new String[] { "3DB Beacons Field",
377 "Show in search summary", "Show in structure summary" };