1
|
package org.bgbm.biovel.drf.checklist;
|
2
|
|
3
|
|
4
|
import java.net.URI;
|
5
|
import java.net.URISyntaxException;
|
6
|
import java.util.EnumSet;
|
7
|
import java.util.HashMap;
|
8
|
import java.util.Iterator;
|
9
|
import java.util.Map;
|
10
|
|
11
|
import org.apache.http.HttpHost;
|
12
|
import org.apache.http.client.utils.URIBuilder;
|
13
|
import org.bgbm.biovel.drf.client.ServiceProviderInfo;
|
14
|
import org.bgbm.biovel.drf.query.RestClient;
|
15
|
import org.bgbm.biovel.drf.tnr.msg.Classification;
|
16
|
import org.bgbm.biovel.drf.tnr.msg.Query;
|
17
|
import org.bgbm.biovel.drf.tnr.msg.Response;
|
18
|
import org.bgbm.biovel.drf.tnr.msg.Source;
|
19
|
import org.bgbm.biovel.drf.tnr.msg.Synonym;
|
20
|
import org.bgbm.biovel.drf.tnr.msg.Taxon;
|
21
|
import org.bgbm.biovel.drf.tnr.msg.TaxonName;
|
22
|
import org.bgbm.biovel.drf.tnr.msg.TnrMsg;
|
23
|
import org.bgbm.biovel.drf.utils.JSONUtils;
|
24
|
import org.bgbm.biovel.drf.utils.TnrMsgUtils;
|
25
|
import org.json.simple.JSONArray;
|
26
|
import org.json.simple.JSONObject;
|
27
|
|
28
|
public class GBIFBackboneClient extends AggregateChecklistClient<RestClient> {
|
29
|
|
30
|
/**
|
31
|
*
|
32
|
*/
|
33
|
private static final HttpHost HTTP_HOST = new HttpHost("api.gbif.org",80);
|
34
|
public static final String ID = "gbif";
|
35
|
public static final String LABEL = "GBIF Checklist Bank";
|
36
|
public static final String URL = "http://uat.gbif.org/developer/species";
|
37
|
public static final String DATA_AGR_URL = "http://data.gbif.org/tutorial/datauseagreement";
|
38
|
private static final String MAX_PAGING_LIMIT = "1000";
|
39
|
private static final String VERSION = "v1";
|
40
|
public static final ServiceProviderInfo CINFO = new ServiceProviderInfo(ID,LABEL,ServiceProviderInfo.DEFAULT_SEARCH_MODE,URL,DATA_AGR_URL, VERSION);
|
41
|
|
42
|
public static final EnumSet<SearchMode> SEARCH_MODES = EnumSet.of(SearchMode.scientificNameExact);
|
43
|
|
44
|
public GBIFBackboneClient() {
|
45
|
super();
|
46
|
}
|
47
|
|
48
|
public GBIFBackboneClient(String checklistInfoJson) throws DRFChecklistException {
|
49
|
super(checklistInfoJson);
|
50
|
}
|
51
|
|
52
|
public GBIFBackboneClient(ServiceProviderInfo spInfo) throws DRFChecklistException {
|
53
|
super(spInfo);
|
54
|
}
|
55
|
|
56
|
@Override
|
57
|
public void initQueryClient() {
|
58
|
queryClient = new RestClient(HTTP_HOST);
|
59
|
}
|
60
|
|
61
|
|
62
|
@Override
|
63
|
public ServiceProviderInfo buildServiceProviderInfo() {
|
64
|
ServiceProviderInfo checklistInfo = CINFO;
|
65
|
int offset = 0;
|
66
|
|
67
|
URIBuilder uriBuilder = new URIBuilder();
|
68
|
uriBuilder.setScheme("http");
|
69
|
uriBuilder.setHost(HTTP_HOST.getHostName());
|
70
|
uriBuilder.setPath("/" + checklistInfo.getVersion() + "/dataset/search");
|
71
|
uriBuilder.setParameter("type", "CHECKLIST");
|
72
|
uriBuilder.setParameter("limit", MAX_PAGING_LIMIT);
|
73
|
uriBuilder.setParameter("offset", "0");
|
74
|
URI uri;
|
75
|
boolean endOfRecords = false;
|
76
|
try {
|
77
|
do {
|
78
|
uriBuilder.setParameter("offset", Integer.toString(offset));
|
79
|
uri = uriBuilder.build();
|
80
|
System.out.println("buildChecklistMap");
|
81
|
String responseBody = queryClient.processRESTService(uri);
|
82
|
|
83
|
JSONObject jsonResponse = JSONUtils.parseJsonToObject(responseBody);
|
84
|
JSONArray results = (JSONArray) jsonResponse.get("results");
|
85
|
Iterator<JSONObject> itrResults = results.iterator();
|
86
|
while(itrResults.hasNext()) {
|
87
|
JSONObject result = itrResults.next();
|
88
|
String key = (String)result.get("key");
|
89
|
String title = (String)result.get("title");
|
90
|
|
91
|
String url = "http://uat.gbif.org/dataset/" + key;
|
92
|
checklistInfo.addSubChecklist(new ServiceProviderInfo(key, title, url, DATA_AGR_URL, getSearchModes()));
|
93
|
}
|
94
|
|
95
|
endOfRecords = (Boolean) jsonResponse.get("endOfRecords");
|
96
|
|
97
|
offset = offset + Integer.parseInt(MAX_PAGING_LIMIT);
|
98
|
} while(!endOfRecords);
|
99
|
} catch (URISyntaxException e) {
|
100
|
// TODO Auto-generated catch block
|
101
|
e.printStackTrace();
|
102
|
// FIXME : We should process the exceptions and if we can't do nothing with them pass to the next level
|
103
|
} catch (DRFChecklistException e) {
|
104
|
// TODO Auto-generated catch block
|
105
|
e.printStackTrace();
|
106
|
// FIXME : We should process the exceptions and if we can't do nothing with them pass to the next level
|
107
|
}
|
108
|
|
109
|
return checklistInfo;
|
110
|
}
|
111
|
|
112
|
|
113
|
|
114
|
@Override
|
115
|
public void resolveScientificNamesExact(TnrMsg tnrMsg) throws DRFChecklistException {
|
116
|
|
117
|
Query query = singleQueryFrom(tnrMsg);
|
118
|
|
119
|
Iterator<ServiceProviderInfo> itrKeys = getServiceProviderInfo().getSubChecklists().iterator();
|
120
|
//http://api.gbif.org/name_usage?q=Abies%20alba&datasetKey=fab88965-e69d-4491-a04d-e3198b626e52
|
121
|
while(itrKeys.hasNext()) {
|
122
|
ServiceProviderInfo checklistInfo = itrKeys.next();
|
123
|
Map<String, String> paramMap = new HashMap<String, String>();
|
124
|
paramMap.put("datasetKey", checklistInfo.getId());
|
125
|
paramMap.put("limit", MAX_PAGING_LIMIT);
|
126
|
|
127
|
URI namesUri = queryClient.buildUriFromQuery(query, "/" + CINFO.getVersion() + "/species", "name", paramMap);
|
128
|
|
129
|
String responseBody = queryClient.processRESTService(namesUri);
|
130
|
|
131
|
updateQueryWithResponse(query,responseBody, paramMap, checklistInfo);
|
132
|
}
|
133
|
}
|
134
|
|
135
|
@Override
|
136
|
public int getMaxPageSize() {
|
137
|
return 10;
|
138
|
}
|
139
|
|
140
|
private void updateQueryWithResponse(Query query ,
|
141
|
String response,
|
142
|
Map<String, String> paramMap,
|
143
|
ServiceProviderInfo ci) throws DRFChecklistException {
|
144
|
|
145
|
JSONObject jsonResponse = JSONUtils.parseJsonToObject(response);
|
146
|
JSONArray results = (JSONArray) jsonResponse.get("results");
|
147
|
|
148
|
if(results != null) {
|
149
|
String accTaxonId = "";
|
150
|
Iterator<JSONObject> resIterator = results.iterator();
|
151
|
while (resIterator.hasNext()) {
|
152
|
JSONObject res = resIterator.next();
|
153
|
Number acceptedKey = (Number)res.get("acceptedKey");
|
154
|
boolean synonym = (Boolean)res.get("synonym");
|
155
|
|
156
|
Response tnrResponse = TnrMsgUtils.tnrResponseFor(ci);
|
157
|
|
158
|
// case when accepted name
|
159
|
if(!synonym && (acceptedKey == null)) {
|
160
|
Long key = (Long)res.get("key");
|
161
|
accTaxonId = key.toString();
|
162
|
|
163
|
Taxon accName = generateAccName(res);
|
164
|
tnrResponse.setTaxon(accName);
|
165
|
|
166
|
} else
|
167
|
// case when synonym
|
168
|
if(synonym && (acceptedKey != null)) {
|
169
|
Long key = (Long)res.get("acceptedKey");
|
170
|
accTaxonId = key.toString();
|
171
|
|
172
|
URI taxonUri = queryClient.buildUriFromQuery(query, "/" + CINFO.getVersion() + "/species/" + accTaxonId, null);
|
173
|
String responseBody = queryClient.processRESTService(taxonUri);
|
174
|
|
175
|
JSONObject taxon = JSONUtils.parseJsonToObject(responseBody);
|
176
|
Taxon accName = generateAccName(taxon);
|
177
|
tnrResponse.setTaxon(accName);
|
178
|
|
179
|
} else {
|
180
|
throw new DRFChecklistException("Name is neither accepted nor a synonym");
|
181
|
}
|
182
|
|
183
|
|
184
|
if(query != null) {
|
185
|
query.getResponse().add(tnrResponse);
|
186
|
}
|
187
|
int offset = 0;
|
188
|
paramMap.put("limit", MAX_PAGING_LIMIT);
|
189
|
|
190
|
boolean endOfRecords = false;
|
191
|
|
192
|
do {
|
193
|
paramMap.put("offset", Integer.toString(offset));
|
194
|
|
195
|
URI synonymsUri = queryClient.buildUriFromQuery(query, "/" + CINFO.getVersion() + "/species/" + accTaxonId + "/synonyms", paramMap);
|
196
|
String synResponse = queryClient.processRESTService(synonymsUri);
|
197
|
|
198
|
JSONObject pagedSynonyms = JSONUtils.parseJsonToObject(synResponse);
|
199
|
generateSynonyms(pagedSynonyms, tnrResponse);
|
200
|
|
201
|
endOfRecords = (Boolean) pagedSynonyms.get("endOfRecords");
|
202
|
|
203
|
offset = offset + Integer.parseInt(MAX_PAGING_LIMIT);
|
204
|
} while(!endOfRecords);
|
205
|
}
|
206
|
}
|
207
|
}
|
208
|
|
209
|
private Taxon generateAccName(JSONObject taxon) {
|
210
|
Taxon accTaxon = new Taxon();
|
211
|
TaxonName taxonName = new TaxonName();
|
212
|
|
213
|
String resName = (String) taxon.get("scientificName");
|
214
|
taxonName.setFullName(resName);
|
215
|
|
216
|
taxonName.setCanonicalName((String) taxon.get("canonicalName"));
|
217
|
|
218
|
taxonName.setRank((String) taxon.get("rank"));
|
219
|
|
220
|
taxonName.setAuthorship((String) taxon.get("authorship"));
|
221
|
|
222
|
accTaxon.setTaxonName(taxonName);
|
223
|
accTaxon.setTaxonomicStatus((String)taxon.get("taxonomicStatus"));
|
224
|
accTaxon.setAccordingTo((String) taxon.get("accordingTo"));
|
225
|
|
226
|
Long key = (Long)taxon.get("key");
|
227
|
String taxonId = key.toString();
|
228
|
accTaxon.setUrl("http://uat.gbif.org/species/" + taxonId);
|
229
|
|
230
|
|
231
|
//FIXME : To fill in
|
232
|
String sourceUrl = "http://uat.gbif.org/species/" + taxonId;
|
233
|
String sourceDatasetID = "";
|
234
|
String sourceDatasetName = "";
|
235
|
String sourceName = "";
|
236
|
|
237
|
Source source = new Source();
|
238
|
source.setIdentifier(sourceDatasetID);
|
239
|
source.setDatasetName(sourceDatasetName);
|
240
|
source.setName(sourceName);
|
241
|
source.setUrl(sourceUrl);
|
242
|
accTaxon.getSources().add(source);
|
243
|
|
244
|
Classification c = new Classification();
|
245
|
c.setKingdom((String) taxon.get("kingdom"));
|
246
|
c.setPhylum((String) taxon.get("phylum"));
|
247
|
c.setClazz((String) taxon.get("clazz"));
|
248
|
c.setOrder((String) taxon.get("order"));
|
249
|
c.setFamily((String) taxon.get("family"));
|
250
|
c.setGenus((String) taxon.get("genus"));
|
251
|
accTaxon.setClassification(c);
|
252
|
|
253
|
return accTaxon;
|
254
|
}
|
255
|
|
256
|
private void generateSynonyms(JSONObject pagedSynonyms, Response tnrResponse) {
|
257
|
|
258
|
|
259
|
JSONArray synonyms = (JSONArray)pagedSynonyms.get("results");
|
260
|
Iterator<JSONObject> itrSynonyms = synonyms.iterator();
|
261
|
while(itrSynonyms.hasNext()) {
|
262
|
Synonym synonym = new Synonym();
|
263
|
JSONObject synonymjs = itrSynonyms.next();
|
264
|
TaxonName taxonName = new TaxonName();
|
265
|
|
266
|
String resName = (String) synonymjs.get("scientificName");
|
267
|
taxonName.setFullName(resName);
|
268
|
|
269
|
taxonName.setCanonicalName((String) synonymjs.get("canonicalName"));
|
270
|
|
271
|
taxonName.setRank((String) synonymjs.get("rank"));
|
272
|
taxonName.setAuthorship((String) synonymjs.get("authorship"));
|
273
|
|
274
|
synonym.setTaxonName(taxonName);
|
275
|
synonym.setTaxonomicStatus((String)synonymjs.get("taxonomicStatus"));
|
276
|
synonym.setAccordingTo((String) synonymjs.get("accordingTo"));
|
277
|
|
278
|
Long key = (Long)synonymjs.get("key");
|
279
|
String synId = key.toString();
|
280
|
synonym.setUrl("http://uat.gbif.org/species/" + synId);
|
281
|
|
282
|
//FIXME : To fill in
|
283
|
String sourceUrl = "http://uat.gbif.org/species/" + synId;
|
284
|
String sourceDatasetID = "";
|
285
|
String sourceDatasetName = "";
|
286
|
String sourceName = "";
|
287
|
|
288
|
Source source = new Source();
|
289
|
source.setIdentifier(sourceDatasetID);
|
290
|
source.setDatasetName(sourceDatasetName);
|
291
|
source.setName(sourceName);
|
292
|
source.setUrl(sourceUrl);
|
293
|
synonym.getSources().add(source);
|
294
|
|
295
|
tnrResponse.getSynonym().add(synonym);
|
296
|
}
|
297
|
}
|
298
|
|
299
|
private String getDatasetNameById(String datasetKey) throws DRFChecklistException {
|
300
|
try{
|
301
|
//Add a comment to this line
|
302
|
URIBuilder uriBuilder = new URIBuilder();
|
303
|
uriBuilder.setScheme("http");
|
304
|
uriBuilder.setHost(HTTP_HOST.getHostName());
|
305
|
uriBuilder.setPath("/" + CINFO.getVersion() + "/dataset/" + datasetKey);
|
306
|
|
307
|
URI uri = uriBuilder.build();
|
308
|
String responseBody = queryClient.processRESTService(uri);
|
309
|
|
310
|
JSONObject datasetInfo = JSONUtils.parseJsonToObject(responseBody);
|
311
|
|
312
|
return (String) datasetInfo.get("title");
|
313
|
}
|
314
|
catch(URISyntaxException e){
|
315
|
throw new DRFChecklistException(e);
|
316
|
}
|
317
|
}
|
318
|
|
319
|
@Override
|
320
|
public void resolveScientificNamesLike(TnrMsg tnrMsg) throws DRFChecklistException {
|
321
|
// TODO Auto-generated method stub
|
322
|
|
323
|
}
|
324
|
|
325
|
@Override
|
326
|
public void resolveVernacularNamesExact(TnrMsg tnrMsg) throws DRFChecklistException {
|
327
|
// TODO Auto-generated method stub
|
328
|
|
329
|
}
|
330
|
|
331
|
@Override
|
332
|
public EnumSet<SearchMode> getSearchModes() {
|
333
|
return SEARCH_MODES;
|
334
|
}
|
335
|
|
336
|
@Override
|
337
|
public void resolveVernacularNamesLike(TnrMsg tnrMsg) throws DRFChecklistException {
|
338
|
// TODO Auto-generated method stub
|
339
|
|
340
|
}
|
341
|
|
342
|
@Override
|
343
|
public boolean isSupportedIdentifier(String value) {
|
344
|
return value != null;
|
345
|
}
|
346
|
|
347
|
@Override
|
348
|
public void findByIdentifier(TnrMsg tnrMsg) throws DRFChecklistException {
|
349
|
// TODO Auto-generated method stub
|
350
|
|
351
|
}
|
352
|
|
353
|
|
354
|
}
|