1 |
|
|
2 |
|
|
3 |
|
|
4 |
|
|
5 |
|
|
6 |
|
|
7 |
|
|
8 |
|
|
9 |
|
|
10 |
|
|
11 |
|
|
12 |
|
|
13 |
|
|
14 |
|
|
15 |
|
|
16 |
|
|
17 |
|
|
18 |
|
|
19 |
|
|
20 |
|
|
21 |
|
package jalview.fts.service.pdb; |
22 |
|
|
23 |
|
import java.net.URI; |
24 |
|
import java.util.ArrayList; |
25 |
|
import java.util.Collection; |
26 |
|
import java.util.Iterator; |
27 |
|
import java.util.List; |
28 |
|
import java.util.Map; |
29 |
|
import java.util.Objects; |
30 |
|
|
31 |
|
import javax.ws.rs.core.MediaType; |
32 |
|
|
33 |
|
import org.json.simple.parser.ParseException; |
34 |
|
|
35 |
|
import com.sun.jersey.api.client.Client; |
36 |
|
import com.sun.jersey.api.client.ClientResponse; |
37 |
|
import com.sun.jersey.api.client.WebResource; |
38 |
|
import com.sun.jersey.api.client.config.DefaultClientConfig; |
39 |
|
|
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.core.FTSRestClient; |
45 |
|
import jalview.fts.core.FTSRestRequest; |
46 |
|
import jalview.fts.core.FTSRestResponse; |
47 |
|
import jalview.util.JSONUtils; |
48 |
|
import jalview.util.MessageManager; |
49 |
|
import jalview.util.Platform; |
50 |
|
|
51 |
|
|
52 |
|
|
53 |
|
|
54 |
|
@author |
55 |
|
|
|
|
| 30.2% |
Uncovered Elements: 134 (192) |
Complexity: 51 |
Complexity Density: 0.41 |
|
56 |
|
public class PDBFTSRestClient extends FTSRestClient |
57 |
|
{ |
58 |
|
|
59 |
|
private static FTSRestClientI instance = null; |
60 |
|
|
61 |
|
public static final String PDB_SEARCH_ENDPOINT = "https://www.ebi.ac.uk/pdbe/search/pdb/select?"; |
62 |
|
|
|
|
| - |
Uncovered Elements: 0 (0) |
Complexity: 1 |
Complexity Density: - |
|
63 |
1 |
protected PDBFTSRestClient()... |
64 |
|
{ |
65 |
|
} |
66 |
|
|
67 |
|
|
68 |
|
|
69 |
|
|
70 |
|
@param |
71 |
|
|
72 |
|
@return |
73 |
|
@throws |
74 |
|
|
|
|
| 52.8% |
Uncovered Elements: 34 (72) |
Complexity: 19 |
Complexity Density: 0.41 |
|
75 |
1 |
@SuppressWarnings({ "unused", "unchecked" })... |
76 |
|
@Override |
77 |
|
public FTSRestResponse executeRequest(FTSRestRequest pdbRestRequest) |
78 |
|
throws Exception |
79 |
|
{ |
80 |
1 |
try |
81 |
|
{ |
82 |
1 |
String wantedFields = getDataColumnsFieldsAsCommaDelimitedString( |
83 |
|
pdbRestRequest.getWantedFields()); |
84 |
1 |
int responseSize = (pdbRestRequest.getResponseSize() == 0) |
85 |
|
? getDefaultResponsePageSize() |
86 |
|
: pdbRestRequest.getResponseSize(); |
87 |
1 |
int offSet = pdbRestRequest.getOffSet(); |
88 |
1 |
String sortParam = null; |
89 |
1 |
if (pdbRestRequest.getFieldToSortBy() == null |
90 |
|
|| pdbRestRequest.getFieldToSortBy().trim().isEmpty()) |
91 |
|
{ |
92 |
0 |
sortParam = ""; |
93 |
|
} |
94 |
|
else |
95 |
|
{ |
96 |
1 |
if (pdbRestRequest.getFieldToSortBy() |
97 |
|
.equalsIgnoreCase("Resolution")) |
98 |
|
{ |
99 |
0 |
sortParam = pdbRestRequest.getFieldToSortBy() |
100 |
0 |
+ (pdbRestRequest.isAscending() ? " asc" : " desc"); |
101 |
|
} |
102 |
|
else |
103 |
|
{ |
104 |
1 |
sortParam = pdbRestRequest.getFieldToSortBy() |
105 |
1 |
+ (pdbRestRequest.isAscending() ? " desc" : " asc"); |
106 |
|
} |
107 |
|
} |
108 |
|
|
109 |
1 |
String facetPivot = (pdbRestRequest.getFacetPivot() == null |
110 |
|
|| pdbRestRequest.getFacetPivot().isEmpty()) ? "" |
111 |
|
: pdbRestRequest.getFacetPivot(); |
112 |
1 |
String facetPivotMinCount = String |
113 |
|
.valueOf(pdbRestRequest.getFacetPivotMinCount()); |
114 |
|
|
115 |
1 |
String query = pdbRestRequest.getFieldToSearchBy() |
116 |
|
+ pdbRestRequest.getSearchTerm() |
117 |
1 |
+ (pdbRestRequest.isAllowEmptySeq() ? "" |
118 |
|
: " AND molecule_sequence:['' TO *]") |
119 |
1 |
+ (pdbRestRequest.isAllowUnpublishedEntries() ? "" |
120 |
|
: " AND status:REL"); |
121 |
|
|
122 |
|
|
123 |
|
|
124 |
|
|
125 |
|
|
126 |
1 |
Client client; |
127 |
1 |
Class<ClientResponse> clientResponseClass; |
128 |
1 |
if (Platform.isJS()) |
129 |
|
{ |
130 |
|
|
131 |
0 |
client = (Client) (Object) new jalview.javascript.web.Client(); |
132 |
0 |
clientResponseClass = (Class<ClientResponse>) (Object) jalview.javascript.web.ClientResponse.class; |
133 |
|
} |
134 |
|
else |
135 |
|
|
136 |
|
|
137 |
|
|
138 |
|
|
139 |
|
|
140 |
|
{ |
141 |
1 |
client = Client.create(new DefaultClientConfig()); |
142 |
1 |
clientResponseClass = ClientResponse.class; |
143 |
|
} |
144 |
|
|
145 |
1 |
WebResource webResource; |
146 |
1 |
if (pdbRestRequest.isFacet()) |
147 |
|
{ |
148 |
0 |
webResource = client.resource(PDB_SEARCH_ENDPOINT) |
149 |
|
.queryParam("wt", "json").queryParam("fl", wantedFields) |
150 |
|
.queryParam("rows", String.valueOf(responseSize)) |
151 |
|
.queryParam("q", query) |
152 |
|
.queryParam("start", String.valueOf(offSet)) |
153 |
|
.queryParam("sort", sortParam).queryParam("facet", "true") |
154 |
|
.queryParam("facet.pivot", facetPivot) |
155 |
|
.queryParam("facet.pivot.mincount", facetPivotMinCount); |
156 |
|
} |
157 |
|
else |
158 |
|
{ |
159 |
1 |
webResource = client.resource(PDB_SEARCH_ENDPOINT) |
160 |
|
.queryParam("wt", "json").queryParam("fl", wantedFields) |
161 |
|
.queryParam("rows", String.valueOf(responseSize)) |
162 |
|
.queryParam("start", String.valueOf(offSet)) |
163 |
|
.queryParam("q", query).queryParam("sort", sortParam); |
164 |
|
} |
165 |
|
|
166 |
1 |
URI uri = webResource.getURI(); |
167 |
|
|
168 |
|
|
169 |
|
|
170 |
|
|
171 |
1 |
ClientResponse clientResponse = webResource |
172 |
|
.accept(MediaType.APPLICATION_JSON).get(clientResponseClass ); |
173 |
|
|
174 |
|
|
175 |
|
|
176 |
1 |
Map<String, Object> jsonObj = null; |
177 |
1 |
String responseString = null; |
178 |
|
|
179 |
|
|
180 |
|
|
181 |
|
|
182 |
1 |
int responseStatus = clientResponse.getStatus(); |
183 |
1 |
switch (responseStatus) |
184 |
|
{ |
185 |
0 |
case 200: |
186 |
0 |
if (Platform.isJS()) |
187 |
|
{ |
188 |
0 |
jsonObj = clientResponse.getEntity(Map.class); |
189 |
|
} |
190 |
|
else |
191 |
|
{ |
192 |
0 |
responseString = clientResponse.getEntity(String.class); |
193 |
|
} |
194 |
0 |
break; |
195 |
1 |
case 400: |
196 |
1 |
throw new Exception(parseJsonExceptionString(responseString)); |
197 |
0 |
default: |
198 |
0 |
throw new Exception( |
199 |
|
getMessageByHTTPStatusCode(responseStatus, "PDB")); |
200 |
|
} |
201 |
|
|
202 |
|
|
203 |
0 |
return parsePDBJsonResponse(responseString, jsonObj, pdbRestRequest); |
204 |
|
} catch (Exception e) |
205 |
|
{ |
206 |
1 |
String exceptionMsg = e.getMessage(); |
207 |
0 |
if (exceptionMsg.contains("SocketException")) |
208 |
|
{ |
209 |
|
|
210 |
0 |
throw new Exception(MessageManager.getString( |
211 |
|
"exception.unable_to_detect_internet_connection")); |
212 |
|
} |
213 |
0 |
else if (exceptionMsg.contains("UnknownHostException")) |
214 |
|
{ |
215 |
|
|
216 |
0 |
throw new Exception(MessageManager.formatMessage( |
217 |
|
"exception.fts_server_unreachable", "PDB Solr")); |
218 |
|
} |
219 |
|
else |
220 |
|
{ |
221 |
0 |
throw e; |
222 |
|
} |
223 |
|
} |
224 |
|
} |
225 |
|
|
226 |
|
|
227 |
|
|
228 |
|
|
229 |
|
@param |
230 |
|
|
231 |
|
@return |
232 |
|
|
|
|
| 18.8% |
Uncovered Elements: 13 (16) |
Complexity: 2 |
Complexity Density: 0.12 |
|
233 |
1 |
@SuppressWarnings("unchecked")... |
234 |
|
public static String parseJsonExceptionString(String jsonErrorResponse) |
235 |
|
{ |
236 |
1 |
StringBuilder errorMessage = new StringBuilder( |
237 |
|
"\n============= PDB Rest Client RunTime error =============\n"); |
238 |
|
|
239 |
|
|
240 |
|
|
241 |
|
|
242 |
|
|
243 |
|
|
244 |
|
|
245 |
|
|
246 |
|
|
247 |
|
|
248 |
|
|
249 |
|
|
250 |
|
|
251 |
|
|
252 |
|
|
253 |
|
|
254 |
|
|
255 |
|
|
256 |
|
|
257 |
|
|
258 |
|
|
259 |
1 |
try |
260 |
|
{ |
261 |
1 |
Map<String, Object> jsonObj = (Map<String, Object>) JSONUtils.parse(jsonErrorResponse); |
262 |
0 |
Map<String, Object> errorResponse = (Map<String, Object>) jsonObj.get("error"); |
263 |
|
|
264 |
0 |
Map<String, Object> responseHeader = (Map<String, Object>) jsonObj |
265 |
|
.get("responseHeader"); |
266 |
0 |
Map<String, Object> paramsObj = (Map<String, Object>) responseHeader.get("params"); |
267 |
0 |
String status = responseHeader.get("status").toString(); |
268 |
0 |
String message = errorResponse.get("msg").toString(); |
269 |
0 |
String query = paramsObj.get("q").toString(); |
270 |
0 |
String fl = paramsObj.get("fl").toString(); |
271 |
|
|
272 |
0 |
errorMessage.append("Status: ").append(status).append("\n"); |
273 |
0 |
errorMessage.append("Message: ").append(message).append("\n"); |
274 |
0 |
errorMessage.append("query: ").append(query).append("\n"); |
275 |
0 |
errorMessage.append("fl: ").append(fl).append("\n"); |
276 |
|
|
277 |
|
} catch (ParseException e) |
278 |
|
{ |
279 |
0 |
e.printStackTrace(); |
280 |
|
} |
281 |
0 |
return errorMessage.toString(); |
282 |
|
} |
283 |
|
|
284 |
|
|
285 |
|
|
286 |
|
|
287 |
|
|
288 |
|
|
289 |
|
@param |
290 |
|
|
291 |
|
@param |
292 |
|
|
293 |
|
|
294 |
|
@return |
295 |
|
|
|
|
| 0% |
Uncovered Elements: 1 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
296 |
0 |
public static FTSRestResponse parsePDBJsonResponse(... |
297 |
|
String pdbJsonResponseString, FTSRestRequest pdbRestRequest) |
298 |
|
{ |
299 |
0 |
return parsePDBJsonResponse(pdbJsonResponseString, |
300 |
|
(Map<String, Object>) null, pdbRestRequest); |
301 |
|
} |
302 |
|
|
|
|
| 0% |
Uncovered Elements: 25 (25) |
Complexity: 5 |
Complexity Density: 0.26 |
|
303 |
0 |
@SuppressWarnings("unchecked")... |
304 |
|
public static FTSRestResponse parsePDBJsonResponse( |
305 |
|
String pdbJsonResponseString, Map<String, Object> jsonObj, |
306 |
|
FTSRestRequest pdbRestRequest) |
307 |
|
{ |
308 |
0 |
FTSRestResponse searchResult = new FTSRestResponse(); |
309 |
0 |
List<FTSData> result = null; |
310 |
0 |
try |
311 |
|
{ |
312 |
0 |
if (jsonObj == null) |
313 |
|
{ |
314 |
0 |
jsonObj = (Map<String, Object>) JSONUtils.parse(pdbJsonResponseString); |
315 |
|
} |
316 |
0 |
Map<String, Object> pdbResponse = (Map<String, Object>) jsonObj.get("response"); |
317 |
0 |
String queryTime = ((Map<String, Object>) jsonObj.get("responseHeader")) |
318 |
|
.get("QTime").toString(); |
319 |
0 |
int numFound = Integer |
320 |
|
.valueOf(pdbResponse.get("numFound").toString()); |
321 |
0 |
if (numFound > 0) |
322 |
|
{ |
323 |
0 |
result = new ArrayList<>(); |
324 |
0 |
List<Object> docs = (List<Object>) pdbResponse.get("docs"); |
325 |
0 |
for (Iterator<Object> docIter = docs.iterator(); docIter |
326 |
|
.hasNext();) |
327 |
|
{ |
328 |
0 |
Map<String, Object> doc = (Map<String, Object>) docIter.next(); |
329 |
0 |
result.add(getFTSData(doc, pdbRestRequest)); |
330 |
|
} |
331 |
0 |
searchResult.setNumberOfItemsFound(numFound); |
332 |
0 |
searchResult.setResponseTime(queryTime); |
333 |
0 |
searchResult.setSearchSummary(result); |
334 |
|
} |
335 |
|
} catch (ParseException e) |
336 |
|
{ |
337 |
0 |
e.printStackTrace(); |
338 |
|
} |
339 |
0 |
return searchResult; |
340 |
|
} |
341 |
|
|
|
|
| 0% |
Uncovered Elements: 39 (39) |
Complexity: 10 |
Complexity Density: 0.4 |
|
342 |
0 |
public static FTSData getFTSData(Map<String, Object> pdbJsonDoc,... |
343 |
|
FTSRestRequest request) |
344 |
|
{ |
345 |
|
|
346 |
0 |
String primaryKey = null; |
347 |
|
|
348 |
0 |
Object[] summaryRowData; |
349 |
|
|
350 |
0 |
SequenceI associatedSequence; |
351 |
|
|
352 |
0 |
Collection<FTSDataColumnI> diplayFields = request.getWantedFields(); |
353 |
0 |
SequenceI associatedSeq = request.getAssociatedSequence(); |
354 |
0 |
int colCounter = 0; |
355 |
0 |
summaryRowData = new Object[(associatedSeq != null) |
356 |
|
? diplayFields.size() + 1 |
357 |
|
: diplayFields.size()]; |
358 |
0 |
if (associatedSeq != null) |
359 |
|
{ |
360 |
0 |
associatedSequence = associatedSeq; |
361 |
0 |
summaryRowData[0] = associatedSequence; |
362 |
0 |
colCounter = 1; |
363 |
|
} |
364 |
|
|
365 |
0 |
for (FTSDataColumnI field : diplayFields) |
366 |
|
{ |
367 |
0 |
String fieldData = (pdbJsonDoc.get(field.getCode()) == null) ? "" |
368 |
|
: pdbJsonDoc.get(field.getCode()).toString(); |
369 |
0 |
if (field.isPrimaryKeyColumn()) |
370 |
|
{ |
371 |
0 |
primaryKey = fieldData; |
372 |
0 |
summaryRowData[colCounter++] = primaryKey; |
373 |
|
} |
374 |
0 |
else if (fieldData == null || fieldData.isEmpty()) |
375 |
|
{ |
376 |
0 |
summaryRowData[colCounter++] = null; |
377 |
|
} |
378 |
|
else |
379 |
|
{ |
380 |
0 |
try |
381 |
|
{ |
382 |
0 |
summaryRowData[colCounter++] = (field.getDataType() |
383 |
|
.getDataTypeClass() == Integer.class) |
384 |
|
? Integer.valueOf(fieldData) |
385 |
0 |
: (field.getDataType() |
386 |
|
.getDataTypeClass() == Double.class) |
387 |
|
? Double.valueOf(fieldData) |
388 |
|
: sanitiseData(fieldData); |
389 |
|
} catch (Exception e) |
390 |
|
{ |
391 |
0 |
e.printStackTrace(); |
392 |
0 |
System.out.println("offending value:" + fieldData); |
393 |
|
} |
394 |
|
} |
395 |
|
} |
396 |
|
|
397 |
0 |
final String primaryKey1 = primaryKey; |
398 |
|
|
399 |
0 |
final Object[] summaryRowData1 = summaryRowData; |
400 |
0 |
return new FTSData() |
401 |
|
{ |
|
|
| 0% |
Uncovered Elements: 1 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
402 |
0 |
@Override... |
403 |
|
public Object[] getSummaryData() |
404 |
|
{ |
405 |
0 |
return summaryRowData1; |
406 |
|
} |
407 |
|
|
|
|
| 0% |
Uncovered Elements: 1 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
408 |
0 |
@Override... |
409 |
|
public Object getPrimaryKey() |
410 |
|
{ |
411 |
0 |
return primaryKey1; |
412 |
|
} |
413 |
|
|
414 |
|
|
415 |
|
|
416 |
|
|
|
|
| 0% |
Uncovered Elements: 6 (6) |
Complexity: 2 |
Complexity Density: 0.5 |
|
417 |
0 |
@Override... |
418 |
|
public String toString() |
419 |
|
{ |
420 |
0 |
StringBuilder summaryFieldValues = new StringBuilder(); |
421 |
0 |
for (Object summaryField : summaryRowData1) |
422 |
|
{ |
423 |
0 |
summaryFieldValues.append( |
424 |
0 |
summaryField == null ? " " : summaryField.toString()) |
425 |
|
.append("\t"); |
426 |
|
} |
427 |
0 |
return summaryFieldValues.toString(); |
428 |
|
} |
429 |
|
|
430 |
|
|
431 |
|
|
432 |
|
|
|
|
| 0% |
Uncovered Elements: 1 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
433 |
0 |
@Override... |
434 |
|
public int hashCode() |
435 |
|
{ |
436 |
0 |
return Objects.hash(primaryKey1, this.toString()); |
437 |
|
} |
438 |
|
|
|
|
| 0% |
Uncovered Elements: 1 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
439 |
0 |
@Override... |
440 |
|
public boolean equals(Object that) |
441 |
|
{ |
442 |
0 |
return this.toString().equals(that.toString()); |
443 |
|
} |
444 |
|
}; |
445 |
|
} |
446 |
|
|
|
|
| 0% |
Uncovered Elements: 2 (2) |
Complexity: 1 |
Complexity Density: 0.5 |
|
447 |
0 |
private static String sanitiseData(String data)... |
448 |
|
{ |
449 |
0 |
String cleanData = data.replaceAll("\\[\"", "").replaceAll("\\]\"", "") |
450 |
|
.replaceAll("\\[", "").replaceAll("\\]", "") |
451 |
|
.replaceAll("\",\"", ", ").replaceAll("\"", ""); |
452 |
0 |
return cleanData; |
453 |
|
} |
454 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
455 |
1 |
@Override... |
456 |
|
public String getColumnDataConfigFileName() |
457 |
|
{ |
458 |
1 |
return "/fts/pdb_data_columns.txt"; |
459 |
|
} |
460 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (5) |
Complexity: 2 |
Complexity Density: 0.67 |
|
461 |
19 |
public static FTSRestClientI getInstance()... |
462 |
|
{ |
463 |
19 |
if (instance == null) |
464 |
|
{ |
465 |
1 |
instance = new PDBFTSRestClient(); |
466 |
|
} |
467 |
19 |
return instance; |
468 |
|
} |
469 |
|
|
470 |
|
private Collection<FTSDataColumnI> allDefaultDisplayedStructureDataColumns; |
471 |
|
|
|
|
| 83.3% |
Uncovered Elements: 1 (6) |
Complexity: 3 |
Complexity Density: 0.75 |
|
472 |
1 |
public Collection<FTSDataColumnI> getAllDefaultDisplayedStructureDataColumns()... |
473 |
|
{ |
474 |
1 |
if (allDefaultDisplayedStructureDataColumns == null |
475 |
|
|| allDefaultDisplayedStructureDataColumns.isEmpty()) |
476 |
|
{ |
477 |
1 |
allDefaultDisplayedStructureDataColumns = new ArrayList<>(); |
478 |
1 |
allDefaultDisplayedStructureDataColumns |
479 |
|
.addAll(super.getAllDefaultDisplayedFTSDataColumns()); |
480 |
|
} |
481 |
1 |
return allDefaultDisplayedStructureDataColumns; |
482 |
|
} |
483 |
|
|
484 |
|
|
485 |
|
} |