Project

General

Profile

Download (14 KB) Statistics
| Branch: | Tag: | Revision:
1
package org.bgbm.biovel.drf.checklist;
2

    
3

    
4
import java.rmi.RemoteException;
5
import java.util.EnumSet;
6
import java.util.regex.Matcher;
7
import java.util.regex.Pattern;
8

    
9
import javax.xml.rpc.ServiceException;
10

    
11
import org.apache.http.HttpHost;
12
import org.bgbm.biovel.drf.checklist.pesi.PESINameServiceLocator;
13
import org.bgbm.biovel.drf.checklist.pesi.PESINameServicePortType;
14
import org.bgbm.biovel.drf.checklist.pesi.PESIRecord;
15
import org.bgbm.biovel.drf.client.ServiceProviderInfo;
16
import org.bgbm.biovel.drf.query.SoapClient;
17
import org.bgbm.biovel.drf.tnr.msg.Classification;
18
import org.bgbm.biovel.drf.tnr.msg.NameType;
19
import org.bgbm.biovel.drf.tnr.msg.Query;
20
import org.bgbm.biovel.drf.tnr.msg.Response;
21
import org.bgbm.biovel.drf.tnr.msg.Source;
22
import org.bgbm.biovel.drf.tnr.msg.Synonym;
23
import org.bgbm.biovel.drf.tnr.msg.Taxon;
24
import org.bgbm.biovel.drf.tnr.msg.TaxonName;
25
import org.bgbm.biovel.drf.tnr.msg.TnrMsg;
26
import org.bgbm.biovel.drf.utils.IdentifierUtils;
27
import org.bgbm.biovel.drf.utils.TnrMsgUtils;
28

    
29

    
30
public class PESIClient extends BaseChecklistClient<SoapClient> {
31

    
32
    /**
33
     *
34
     */
35
    private static final HttpHost HTTP_HOST = new HttpHost("http://www.eu-nomen.eu",80);
36
    public static final String ID = "pesi";
37
    public static final String LABEL = "PESI";
38
    public static final String URL = "http://www.eu-nomen.eu/portal/index.php";
39
    public static final String DATA_AGR_URL = "";
40

    
41
    private static Pattern citationPattern = Pattern.compile("^(.*)\\p{Punct} [Aa]ccessed through\\p{Punct}? (PESI|Euro\\+Med PlantBase|Index Fungorum|Fauna Europaea|European Register of Marine Species) at (.*)$");
42

    
43
    // to match e.g.: http://www.eu-nomen.eu/portal/taxon.php?GUID=urn:lsid:marinespecies.org:taxname:140389
44
    private static Pattern Lsid_pattern = Pattern.compile(".*(urn:lsid:\\S*).*");
45

    
46
    // to match e.g.: http://www.eu-nomen.eu/portal/taxon.php?GUID=0EB6CA37-3365-4AF5-A800-8FC4B8C366FA
47
    private static Pattern uuid_pattern = Pattern.compile(".*GUID=([A-Z0-9\\-]{36}).*");
48

    
49
    public enum PESISources {
50
        EUROMED("Euro+Med Plantbase"),
51
        FAUNA_EUROPAEA ("Fauna Europaea"),
52
        ERMS ("European Register of Marine Species"),
53
        INDEX_FUNGORUM ("Index Fungorum");
54

    
55
        private String value;
56

    
57
        PESISources(String v) {
58
            value = v;
59
        }
60

    
61
        public String value() {
62
            return value;
63
        }
64

    
65
        public static PESISources fromValue(String v) {
66
            for (PESISources c: PESISources.values()) {
67
                if (c.value.equals(v)) {
68
                    return c;
69
                }
70
            }
71
            throw new IllegalArgumentException(v);
72
        }
73

    
74
    }
75

    
76
    public static final EnumSet<SearchMode> SEARCH_MODES = EnumSet.of(
77
            SearchMode.scientificNameExact,
78
            SearchMode.scientificNameLike,
79
            SearchMode.vernacularNameExact,
80
            SearchMode.vernacularNameLike,
81
            SearchMode.findByIdentifier
82
            );
83

    
84
    public static final EnumSet<SearchMode> SCIENTIFICNAME_SEARCH_MODES = EnumSet.of(
85
            SearchMode.scientificNameExact,
86
            SearchMode.scientificNameLike
87
            );
88

    
89

    
90
    public PESIClient() {
91
        super();
92

    
93
    }
94

    
95
    /**
96
     * {@inheritDoc}
97
     */
98
    @Override
99
    public void initQueryClient() {
100
        queryClient = new SoapClient();
101
    }
102

    
103
    @Override
104
    public ServiceProviderInfo buildServiceProviderInfo() {
105
        ServiceProviderInfo checklistInfo = new ServiceProviderInfo(ID,LABEL,URL,DATA_AGR_URL, getSearchModes());
106
        return checklistInfo;
107
    }
108

    
109

    
110
    @Override
111
    public int getMaxPageSize() {
112
        return 10;
113
    }
114

    
115

    
116

    
117
    @Override
118
    public EnumSet<SearchMode> getSearchModes() {
119
        return SEARCH_MODES;
120
    }
121

    
122
    /**
123
     * @param pesins
124
     * @return
125
     * @throws DRFChecklistException
126
     */
127
    private PESINameServicePortType getPESINameService(PESINameServiceLocator pesins) throws DRFChecklistException {
128
        PESINameServicePortType pesinspt;
129
        try {
130
            pesinspt = pesins.getPESINameServicePort();
131
        } catch (ServiceException e) {
132
            logger.error("Error in accessing PESINameService", e);
133
            throw new DRFChecklistException("Error in accessing PESINameService");
134
        }
135
        return pesinspt;
136
    }
137

    
138
    /**
139
     * @param sourceString
140
     * @return
141
     */
142
    private ParsedCitation parsePesiCitation(String sourceString) {
143

    
144
        ParsedCitation parsed = new ParsedCitation();
145

    
146
        Matcher m = citationPattern.matcher(sourceString);
147
        if (m.matches()) {
148

    
149
            if(!m.group(2).equals(PESISources.INDEX_FUNGORUM)){
150
                parsed.accordingTo = m.group(1);
151
            }
152
            parsed.sourceTaxonUrl = m.group(3);
153

    
154
        }
155
        return parsed;
156
    }
157

    
158
    private Taxon generateAccName(PESIRecord taxon) {
159

    
160

    
161
        Taxon accName = new Taxon();
162
        TaxonName taxonName = new TaxonName();
163

    
164
        String resName = taxon.getScientificname();
165
        taxonName.setFullName(resName + " " + taxon.getAuthority());
166

    
167
        taxonName.setCanonicalName(resName);
168

    
169
        taxonName.setRank(taxon.getRank());
170
        taxonName.setAuthorship(taxon.getAuthority());
171

    
172
        accName.setTaxonName(taxonName);
173
        accName.setTaxonomicStatus(taxon.getStatus());
174
        accName.setUrl(taxon.getUrl());
175

    
176
        String lsid = taxon.getValid_guid();
177
        accName.setIdentifier(lsid);
178

    
179
        String sourceString = taxon.getCitation(); // concatenation of sec. reference and url
180
        ParsedCitation parsed = parsePesiCitation(sourceString);
181
        accName.setAccordingTo(parsed.accordingTo);
182

    
183

    
184
        // TODO ask VLIZ for adding all the the sourceFKs to the service and fill additional the data in here
185
        if(parsed.sourceTaxonUrl != null){
186
            Source source = new Source();
187
            source.setUrl(parsed.sourceTaxonUrl);
188
            source.setTitle(parsed.accordingTo);
189
            source.setIdentifier(lsid);
190
            accName.getSources().add(source);
191
        }
192

    
193
        Classification c = new Classification();
194
        c.setKingdom(taxon.getKingdom());
195
        c.setPhylum(taxon.getPhylum());
196
        c.setClazz("");
197
        c.setOrder(taxon.getOrder());
198
        c.setFamily(taxon.getFamily());
199
        c.setGenus(taxon.getGenus());
200
        accName.setClassification(c);
201

    
202
        return accName;
203
    }
204

    
205
    private void generateSynonyms(PESIRecord[] synonyms, Response tnrResponse) {
206

    
207
        for(PESIRecord synRecord : synonyms) {
208

    
209
            Synonym synonym = new Synonym();
210

    
211
            TaxonName taxonName = new TaxonName();
212

    
213
            String resName = synRecord.getScientificname();
214
            taxonName.setFullName(resName + " " + synRecord.getAuthority());
215

    
216
            taxonName.setCanonicalName(resName);
217

    
218
            String sourceString = synRecord.getCitation(); // concatenation of sec. reference and url
219
            ParsedCitation parsed = parsePesiCitation(sourceString);
220
            synonym.setAccordingTo(parsed.accordingTo);
221

    
222
            if(parsed.sourceTaxonUrl != null){
223
                Source source = new Source();
224
                source.setUrl(parsed.sourceTaxonUrl);
225
                source.setTitle(parsed.accordingTo);
226
                synonym.getSources().add(source);
227
            }
228

    
229
            taxonName.setRank(synRecord.getRank());
230
            taxonName.setAuthorship(synRecord.getAuthority());
231

    
232
            synonym.setTaxonName(taxonName);
233
            synonym.setTaxonomicStatus(synRecord.getStatus());
234

    
235
            synonym.setUrl(synRecord.getUrl());
236

    
237
            tnrResponse.getSynonym().add(synonym);
238
        }
239
    }
240

    
241
    @Override
242
    public void resolveScientificNamesExact(TnrMsg tnrMsg) throws DRFChecklistException {
243

    
244
        Query query = singleQueryFrom(tnrMsg);
245
        String name = query.getRequest().getQueryString();
246
        PESINameServiceLocator pesins = new PESINameServiceLocator();
247

    
248
        PESINameServicePortType pesinspt = getPESINameService(pesins);
249

    
250
        try {
251
            PESIRecord[] records = pesinspt.getPESIRecords(name, false);
252
            if(records != null){
253
                for (PESIRecord record : records) {
254
                    Response tnrResponse = tnrResponseFromRecord(pesinspt, record, query.getRequest());
255
                    query.getResponse().add(tnrResponse);
256
                }
257
            }
258

    
259
        }  catch (RemoteException e) {
260
            logger.error("Error in getGUID method in PESINameService", e);
261
            throw new DRFChecklistException("Error in getGUID method in PESINameService");
262
        }
263

    
264
    }
265

    
266
    @Override
267
    public void resolveScientificNamesLike(TnrMsg tnrMsg) throws DRFChecklistException {
268
        Query query = singleQueryFrom(tnrMsg);
269
        String name = query.getRequest().getQueryString();
270
        PESINameServiceLocator pesins = new PESINameServiceLocator();
271

    
272
        PESINameServicePortType pesinspt = getPESINameService(pesins);
273

    
274
        try {
275
            PESIRecord[] records = pesinspt.getPESIRecords(name, true);
276
            if(records != null){
277
                for (PESIRecord record : records) {
278
                    Response tnrResponse = tnrResponseFromRecord(pesinspt, record, query.getRequest());
279
                    query.getResponse().add(tnrResponse);
280
                }
281
            }
282
        }  catch (RemoteException e) {
283
            logger.error("Error in getPESIRecords method in PESINameService", e);
284
            throw new DRFChecklistException("Error in getPESIRecords method in PESINameService");
285
        }
286

    
287
    }
288

    
289
    @Override
290
    public void resolveVernacularNamesExact(TnrMsg tnrMsg) throws DRFChecklistException {
291

    
292
        Query query = singleQueryFrom(tnrMsg);
293
        String name = query.getRequest().getQueryString();
294
        PESINameServiceLocator pesins = new PESINameServiceLocator();
295

    
296
        PESINameServicePortType pesinspt = getPESINameService(pesins);
297

    
298
        try {
299
            PESIRecord[] records = pesinspt.getPESIRecordsByVernacular(name);
300
            if(records != null){
301
                for (PESIRecord record : records) {
302
                    Response tnrResponse = tnrResponseFromRecord(pesinspt, record, query.getRequest());
303
                    query.getResponse().add(tnrResponse);
304
                }
305
            }
306
        }  catch (RemoteException e) {
307
            logger.error("Error in getPESIRecords method in PESINameService", e);
308
            throw new DRFChecklistException("Error in getPESIRecords method in PESINameService");
309
        }
310

    
311
    }
312

    
313
    @Override
314
    public void resolveVernacularNamesLike(TnrMsg tnrMsg) throws DRFChecklistException {
315

    
316
        Query query = singleQueryFrom(tnrMsg);
317
        String name = query.getRequest().getQueryString();
318
        PESINameServiceLocator pesins = new PESINameServiceLocator();
319

    
320
        PESINameServicePortType pesinspt = getPESINameService(pesins);
321

    
322
        try {
323
            PESIRecord[] records = pesinspt.getPESIRecordsByVernacular("%" + name + "%");
324
            if(records != null){
325
                for (PESIRecord record : records) {
326
                    Response tnrResponse = tnrResponseFromRecord(pesinspt, record, query.getRequest());
327
                    query.getResponse().add(tnrResponse);
328
                }
329
            }
330
        }  catch (RemoteException e) {
331
            logger.error("Error in getPESIRecords method in PESINameService", e);
332
            throw new DRFChecklistException("Error in getPESIRecords method in PESINameService");
333
        }
334

    
335
    }
336

    
337
    @Override
338
    public void findByIdentifier(TnrMsg tnrMsg) throws DRFChecklistException {
339
        Query query = singleQueryFrom(tnrMsg);
340
        String name = query.getRequest().getQueryString();
341
        PESINameServiceLocator pesins = new PESINameServiceLocator();
342

    
343
        PESINameServicePortType pesinspt = getPESINameService(pesins);
344

    
345
        try {
346
            PESIRecord record = pesinspt.getPESIRecordByGUID(name);
347
            if(record != null){
348
                Response tnrResponse = tnrResponseFromRecord(pesinspt, record, query.getRequest());
349
                query.getResponse().add(tnrResponse);
350
            }
351

    
352
        }  catch (RemoteException e) {
353
            logger.error("Error in getGUID method in PESINameService", e);
354
            throw new DRFChecklistException("Error in getGUID method in PESINameService");
355
        }
356

    
357

    
358
    }
359

    
360
    /**
361
     * @param pesinspt
362
     * @param record
363
     * @param searchMode TODO
364
     * @throws RemoteException
365
     */
366
    private Response tnrResponseFromRecord(PESINameServicePortType pesinspt, PESIRecord record, Query.Request request) throws RemoteException {
367

    
368
        Response tnrResponse = TnrMsgUtils.tnrResponseFor(getServiceProviderInfo());
369

    
370
        SearchMode searchMode = SearchMode.valueOf(request.getSearchMode());
371

    
372
        String accNameGUID = record.getValid_guid();
373
        if(SCIENTIFICNAME_SEARCH_MODES.contains(searchMode)){
374
            tnrResponse.setMatchingNameString(record.getScientificname());
375
        }
376

    
377
        if(accNameGUID != null){
378

    
379
            // case when accepted name
380
            if(record.getGUID() != null && record.getGUID().equals(accNameGUID)) {
381
                Taxon accName = generateAccName(record);
382
                tnrResponse.setTaxon(accName);
383
                if(SCIENTIFICNAME_SEARCH_MODES.contains(searchMode)){
384
                    tnrResponse.setMatchingNameType(NameType.TAXON);
385
                }
386
            } else {
387
                // case when synonym
388
                PESIRecord accNameRecord = pesinspt.getPESIRecordByGUID(accNameGUID);
389
                Taxon accName = generateAccName(accNameRecord);
390
                tnrResponse.setTaxon(accName);
391
                if(SCIENTIFICNAME_SEARCH_MODES.contains(searchMode)){
392
                    tnrResponse.setMatchingNameType(NameType.SYNONYM);
393
                }
394
            }
395

    
396
            PESIRecord[] records = pesinspt.getPESISynonymsByGUID(accNameGUID);
397
            if(request.isAddSynonymy() &&  records != null && records.length > 0) {
398
                generateSynonyms(records,tnrResponse);
399
            }
400
        }
401

    
402
        return tnrResponse;
403
    }
404

    
405
    class ParsedCitation {
406

    
407
        String accordingTo = null;
408
        String sourceTaxonUrl = null;
409
    }
410

    
411
    @Override
412
    public boolean isSupportedIdentifier(String value) {
413
        return IdentifierUtils.checkLSID(value) || IdentifierUtils.checkUUID(value);
414
    }
415

    
416
}
417

    
418

    
(7-7/12)