Project

General

Profile

Download (14.1 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
    @Override
110
    public EnumSet<SearchMode> getSearchModes() {
111
        return SEARCH_MODES;
112
    }
113

    
114
    /**
115
     * @param pesins
116
     * @return
117
     * @throws DRFChecklistException
118
     */
119
    private PESINameServicePortType getPESINameService(PESINameServiceLocator pesins) throws DRFChecklistException {
120
        PESINameServicePortType pesinspt;
121
        try {
122
            pesinspt = pesins.getPESINameServicePort();
123
        } catch (ServiceException e) {
124
            logger.error("Error in accessing PESINameService", e);
125
            throw new DRFChecklistException("Error in accessing PESINameService");
126
        }
127
        return pesinspt;
128
    }
129

    
130
    /**
131
     * @param sourceString
132
     * @return
133
     */
134
    private ParsedCitation parsePesiCitation(String sourceString) {
135

    
136
        ParsedCitation parsed = new ParsedCitation();
137

    
138
        Matcher m = citationPattern.matcher(sourceString);
139
        if (m.matches()) {
140

    
141
            if(!m.group(2).equals(PESISources.INDEX_FUNGORUM)){
142
                parsed.accordingTo = m.group(1);
143
            }
144
            parsed.sourceTaxonUrl = m.group(3);
145

    
146
        }
147
        return parsed;
148
    }
149

    
150
    private Taxon generateAccName(PESIRecord taxon) {
151

    
152

    
153
        Taxon accName = new Taxon();
154
        TaxonName taxonName = new TaxonName();
155

    
156
        String resName = taxon.getScientificname();
157
        taxonName.setFullName(resName + " " + taxon.getAuthority());
158

    
159
        taxonName.setCanonicalName(resName);
160

    
161
        taxonName.setRank(taxon.getRank());
162
        taxonName.setAuthorship(taxon.getAuthority());
163

    
164
        accName.setTaxonName(taxonName);
165
        accName.setTaxonomicStatus(taxon.getStatus());
166
        accName.setUrl(taxon.getUrl());
167

    
168
        String lsid = taxon.getValid_guid();
169
        accName.setIdentifier(lsid);
170

    
171
        String sourceString = taxon.getCitation(); // concatenation of sec. reference and url
172
        ParsedCitation parsed = parsePesiCitation(sourceString);
173
        accName.setAccordingTo(parsed.accordingTo);
174

    
175

    
176
        // TODO ask VLIZ for adding all the the sourceFKs to the service and fill additional the data in here
177
        if(parsed.sourceTaxonUrl != null){
178
            Source source = new Source();
179
            source.setUrl(parsed.sourceTaxonUrl);
180
            source.setTitle(parsed.accordingTo);
181
            source.setIdentifier(lsid);
182
            accName.getSources().add(source);
183
        }
184

    
185
        Classification c = new Classification();
186
        c.setKingdom(taxon.getKingdom());
187
        c.setPhylum(taxon.getPhylum());
188
        c.setClazz("");
189
        c.setOrder(taxon.getOrder());
190
        c.setFamily(taxon.getFamily());
191
        c.setGenus(taxon.getGenus());
192
        accName.setClassification(c);
193

    
194
        return accName;
195
    }
196

    
197
    private void generateSynonyms(PESIRecord[] synonyms, Response tnrResponse) {
198

    
199
        for(PESIRecord synRecord : synonyms) {
200

    
201
            Synonym synonym = new Synonym();
202

    
203
            TaxonName taxonName = new TaxonName();
204

    
205
            String resName = synRecord.getScientificname();
206
            taxonName.setFullName(resName + " " + synRecord.getAuthority());
207

    
208
            taxonName.setCanonicalName(resName);
209

    
210
            String sourceString = synRecord.getCitation(); // concatenation of sec. reference and url
211
            ParsedCitation parsed = parsePesiCitation(sourceString);
212
            synonym.setAccordingTo(parsed.accordingTo);
213

    
214
            if(parsed.sourceTaxonUrl != null){
215
                Source source = new Source();
216
                source.setUrl(parsed.sourceTaxonUrl);
217
                source.setTitle(parsed.accordingTo);
218
                synonym.getSources().add(source);
219
            }
220

    
221
            taxonName.setRank(synRecord.getRank());
222
            taxonName.setAuthorship(synRecord.getAuthority());
223

    
224
            synonym.setTaxonName(taxonName);
225
            synonym.setTaxonomicStatus(synRecord.getStatus());
226

    
227
            synonym.setUrl(synRecord.getUrl());
228

    
229
            tnrResponse.getSynonym().add(synonym);
230
        }
231
    }
232

    
233
    @Override
234
    public void resolveScientificNamesExact(TnrMsg tnrMsg) throws DRFChecklistException {
235

    
236
        Query query = singleQueryFrom(tnrMsg);
237
        String name = query.getRequest().getQueryString();
238

    
239
        PESINameServiceLocator pesins = new PESINameServiceLocator();
240
        PESINameServicePortType pesinspt = getPESINameService(pesins);
241

    
242
        try {
243
            PESIRecord[] records = pesinspt.getPESIRecords(name, false);
244
            if(records != null){
245
                for (PESIRecord record : records) {
246
                    Response tnrResponse = tnrResponseFromRecord(pesinspt, record, query.getRequest());
247
                    query.getResponse().add(tnrResponse);
248
                }
249
            }
250

    
251
        }  catch (RemoteException e) {
252
            logger.error("Error in getPESIRecords method in PESINameService", e);
253
            throw new DRFChecklistException("Error in getPESIRecords method in PESINameService");
254
        }
255

    
256
    }
257

    
258
    @Override
259
    public void resolveScientificNamesLike(TnrMsg tnrMsg) throws DRFChecklistException {
260
        Query query = singleQueryFrom(tnrMsg);
261
        String name = query.getRequest().getQueryString();
262

    
263
        PESINameServiceLocator pesins = new PESINameServiceLocator();
264
        PESINameServicePortType pesinspt = getPESINameService(pesins);
265

    
266
        try {
267
            PESIRecord[] records = pesinspt.getPESIRecords(name, true);
268
            if(records != null){
269
                for (PESIRecord record : records) {
270
                    Response tnrResponse = tnrResponseFromRecord(pesinspt, record, query.getRequest());
271
                    query.getResponse().add(tnrResponse);
272
                }
273
            }
274
        }  catch (RemoteException e) {
275
            logger.error("Error in getPESIRecords method in PESINameService", e);
276
            throw new DRFChecklistException("Error in getPESIRecords method in PESINameService");
277
        }
278

    
279
    }
280

    
281
    @Override
282
    public void resolveVernacularNamesExact(TnrMsg tnrMsg) throws DRFChecklistException {
283

    
284
        Query query = singleQueryFrom(tnrMsg);
285
        String name = query.getRequest().getQueryString();
286
        PESINameServiceLocator pesins = new PESINameServiceLocator();
287

    
288
        PESINameServicePortType pesinspt = getPESINameService(pesins);
289

    
290
        try {
291
            PESIRecord[] records = pesinspt.getPESIRecordsByVernacular(name);
292
            if(records != null){
293
                for (PESIRecord record : records) {
294
                    Response tnrResponse = tnrResponseFromRecord(pesinspt, record, query.getRequest());
295
                    query.getResponse().add(tnrResponse);
296
                }
297
            }
298
        }  catch (RemoteException e) {
299
            logger.error("Error in getPESIRecordsByVernacular method in PESINameService", e);
300
            throw new DRFChecklistException("Error in getPESIRecordsByVernacular method in PESINameService");
301
        }
302

    
303
    }
304

    
305
    @Override
306
    public void resolveVernacularNamesLike(TnrMsg tnrMsg) throws DRFChecklistException {
307

    
308
        Query query = singleQueryFrom(tnrMsg);
309
        String name = query.getRequest().getQueryString();
310
        PESINameServiceLocator pesins = new PESINameServiceLocator();
311

    
312
        PESINameServicePortType pesinspt = getPESINameService(pesins);
313

    
314
        try {
315
            PESIRecord[] records = pesinspt.getPESIRecordsByVernacular("%" + name + "%");
316
            if(records != null){
317
                for (PESIRecord record : records) {
318
                    Response tnrResponse = tnrResponseFromRecord(pesinspt, record, query.getRequest());
319
                    query.getResponse().add(tnrResponse);
320
                }
321
            }
322
        }  catch (RemoteException e) {
323
            logger.error("Error in getPESIRecordsByVernacular method in PESINameService", e);
324
            throw new DRFChecklistException("Error in getPESIRecordsByVernacular method in PESINameService");
325
        }
326

    
327
    }
328

    
329
    @Override
330
    public void findByIdentifier(TnrMsg tnrMsg) throws DRFChecklistException {
331
        Query query = singleQueryFrom(tnrMsg);
332
        String name = query.getRequest().getQueryString();
333
        PESINameServiceLocator pesins = new PESINameServiceLocator();
334

    
335
        PESINameServicePortType pesinspt = getPESINameService(pesins);
336

    
337
        try {
338
            PESIRecord record = pesinspt.getPESIRecordByGUID(name);
339
            if(record != null){
340
                Response tnrResponse = tnrResponseFromRecord(pesinspt, record, query.getRequest());
341
                query.getResponse().add(tnrResponse);
342
            }
343

    
344
        }  catch (RemoteException e) {
345
            logger.error("Error in getPESIRecordByGUID method in PESINameService", e);
346
            throw new DRFChecklistException("Error in getPESIRecordByGUID method in PESINameService");
347
        }
348

    
349

    
350
    }
351

    
352
    /**
353
     * @param pesinspt
354
     * @param record
355
     * @param searchMode TODO
356
     * @throws RemoteException
357
     */
358
    private Response tnrResponseFromRecord(PESINameServicePortType pesinspt, PESIRecord record, Query.Request request) throws RemoteException {
359

    
360
        Response tnrResponse = TnrMsgUtils.tnrResponseFor(getServiceProviderInfo());
361

    
362
        SearchMode searchMode = SearchMode.valueOf(request.getSearchMode());
363

    
364
        String taxonGUID = record.getValid_guid();
365
        if(SCIENTIFICNAME_SEARCH_MODES.contains(searchMode)){
366
            tnrResponse.setMatchingNameString(record.getScientificname());
367
        }
368

    
369
        if(taxonGUID != null){
370

    
371
            // case when accepted name
372
            if(record.getGUID() != null && record.getGUID().equals(taxonGUID)) {
373
                Taxon taxon = generateAccName(record);
374
                tnrResponse.setTaxon(taxon);
375
                if(SCIENTIFICNAME_SEARCH_MODES.contains(searchMode)){
376
                    tnrResponse.setMatchingNameType(NameType.TAXON);
377
                }
378
            } else {
379
                // case when synonym
380
                PESIRecord taxonRecord = pesinspt.getPESIRecordByGUID(taxonGUID);
381
                Taxon taxon = generateAccName(taxonRecord);
382
                tnrResponse.setTaxon(taxon);
383
                if(SCIENTIFICNAME_SEARCH_MODES.contains(searchMode)){
384
                    tnrResponse.setMatchingNameType(NameType.SYNONYM);
385
                }
386
            }
387

    
388
            // FIXME check for isAddSynonymy prior doing the request
389
            PESIRecord[] records = pesinspt.getPESISynonymsByGUID(taxonGUID);
390
            if(request.isAddSynonymy() &&  records != null && records.length > 0) {
391
                generateSynonyms(records,tnrResponse);
392
            }
393
        }
394

    
395
        return tnrResponse;
396
    }
397

    
398
    class ParsedCitation {
399

    
400
        String accordingTo = null;
401
        String sourceTaxonUrl = null;
402
    }
403

    
404
    @Override
405
    public boolean isSupportedIdentifier(String value) {
406
        return IdentifierUtils.checkLSID(value) || IdentifierUtils.checkUUID(value);
407
    }
408

    
409
}
410

    
411

    
(8-8/12)