Project

General

Profile

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

    
3
import java.io.PrintStream;
4
import java.net.URI;
5
import java.util.ArrayList;
6
import java.util.EnumSet;
7
import java.util.Iterator;
8
import java.util.List;
9

    
10
import org.apache.jena.rdf.model.Model;
11
import org.apache.jena.rdf.model.Resource;
12
import org.bgbm.biovel.drf.client.ServiceProviderInfo;
13
import org.bgbm.biovel.drf.query.IQueryClient;
14
import org.bgbm.biovel.drf.query.SparqlClient;
15
import org.bgbm.biovel.drf.query.TinkerPopClient;
16
import org.bgbm.biovel.drf.store.Neo4jStore;
17
import org.bgbm.biovel.drf.store.Store;
18
import org.bgbm.biovel.drf.store.TDBStore;
19
import org.bgbm.biovel.drf.tnr.msg.NameType;
20
import org.bgbm.biovel.drf.tnr.msg.Query;
21
import org.bgbm.biovel.drf.tnr.msg.Query.Request;
22
import org.bgbm.biovel.drf.tnr.msg.Response;
23
import org.bgbm.biovel.drf.tnr.msg.Source;
24
import org.bgbm.biovel.drf.tnr.msg.Synonym;
25
import org.bgbm.biovel.drf.tnr.msg.Taxon;
26
import org.bgbm.biovel.drf.tnr.msg.TaxonBase;
27
import org.bgbm.biovel.drf.tnr.msg.TaxonName;
28
import org.bgbm.biovel.drf.tnr.msg.TnrMsg;
29
import org.bgbm.biovel.drf.utils.IdentifierUtils;
30
import org.bgbm.biovel.drf.utils.Profiler;
31
import org.bgbm.biovel.drf.utils.TnrMsgUtils;
32
import org.neo4j.graphdb.Relationship;
33
import org.openrdf.query.MalformedQueryException;
34
import org.openrdf.query.QueryEvaluationException;
35
import org.openrdf.query.QueryLanguage;
36
import org.openrdf.query.TupleQuery;
37
import org.openrdf.query.TupleQueryResult;
38
import org.openrdf.repository.RepositoryException;
39
import org.openrdf.repository.sail.SailRepositoryConnection;
40

    
41
import com.tinkerpop.blueprints.Direction;
42
import com.tinkerpop.blueprints.Graph;
43
import com.tinkerpop.blueprints.Vertex;
44
import com.tinkerpop.blueprints.impls.neo4j.Neo4jGraph;
45
import com.tinkerpop.blueprints.impls.neo4j.Neo4jVertex;
46
import com.tinkerpop.blueprints.oupls.sail.GraphSail;
47
import com.tinkerpop.gremlin.java.GremlinPipeline;
48
import com.tinkerpop.pipes.PipeFunction;
49
import com.tinkerpop.pipes.util.FastNoSuchElementException;
50

    
51
public class EEA_BDC_Client extends AggregateChecklistClient<TinkerPopClient> {
52

    
53
    /**
54
     *
55
     */
56
    public static final String ID = "eea_bdc";
57
    public static final String LABEL = "European Environment Agency (EEA) Biodiversity data centre (BDC)";
58
    public static final String DOC_URL = "http://semantic.eea.europa.eu/documentation";
59
    public static final String COPYRIGHT_URL = "http://www.eea.europa.eu/legal/eea-data-policy";
60

    
61
    private static final String SPARQL_ENDPOINT_URL = "http://semantic.eea.europa.eu/sparql";
62
    private static final boolean USE_REMOTE_SERVICE = false;
63

    
64
    private static final String SPECIES_RDF_FILE_URL = "http://localhost/download/species.rdf.gz"; // http://eunis.eea.europa.eu/rdf/species.rdf.gz
65
    private static final String LEGALREFS_RDF_FILE_URL = "http://localhost/download/legalrefs.rdf.gz"; // http://eunis.eea.europa.eu/rdf/legalrefs.rdf.gz
66
    private static final String REFERENCES_RDF_FILE_URL = "http://localhost/download/references.rdf.gz"; // http://eunis.eea.europa.eu/rdf/references.rdf.gz
67
    private static final boolean REFRESH_TDB = false;
68

    
69
    private static final Class<? extends IQueryClient> clientClass = TinkerPopClient.class;
70

    
71
    private static final int MAX_PAGING_LIMIT = 50;
72

    
73
    public static final EnumSet<SearchMode> SEARCH_MODES = EnumSet.of(
74
            SearchMode.scientificNameExact,
75
            SearchMode.scientificNameLike,
76
            SearchMode.vernacularNameExact,
77
            SearchMode.vernacularNameLike,
78
            SearchMode.findByIdentifier);
79

    
80
    public static enum RdfSchema {
81

    
82
        /*
83
         *     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
84
    xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
85
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
86
    xmlns:dcterms="http://purl.org/dc/terms/"
87
    xmlns:dc="http://purl.org/dc/elements/1.1/"
88
    xmlns:dwc="http://rs.tdwg.org/dwc/terms/"
89
    xmlns:owl="http://www.w3.org/2002/07/owl#"
90
    xmlns="http://eunis.eea.europa.eu/rdf/species-schema.rdf#"
91
    xmlns:sioc="http://rdfs.org/sioc/ns#"
92
    xmlns:skos="http://www.w3.org/2004/02/skos/core#"
93
    xmlns:bibo="http://purl.org/ontology/bibo/"
94
    xmlns:cc="http://creativecommons.org/ns#"
95
    xmlns:foaf="http://xmlns.com/foaf/0.1/"
96
         */
97
        EUNIS_SPECIES("es","http://eunis.eea.europa.eu/rdf/species-schema.rdf#"),
98
        EUNIS_TAXONOMY("et", "http://eunis.eea.europa.eu/rdf/taxonomies-schema.rdf#"),
99
        DWC("dwc", "http://rs.tdwg.org/dwc/terms/"),
100
        RDF("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#"),
101
        RDFS("rdfs", "http://www.w3.org/2000/01/rdf-schema#"),
102
        SKOS_CORE("scos_core", "http://www.w3.org/2004/02/skos/core#"),
103
        DC("dc", "http://purl.org/dc/terms/source"),
104
        DCTERMS("dcterms", "http://purl.org/dc/terms/");
105

    
106
        private String schemaUri;
107
        private String abbreviation;
108
        RdfSchema(String abbreviation, String schemaUri) {
109
            this.abbreviation = abbreviation;
110
            this.schemaUri = schemaUri;
111
        }
112

    
113
        public String schemaUri() {
114

    
115
            return schemaUri;
116
        }
117

    
118
        public String abbreviation() {
119

    
120
            return abbreviation;
121
        }
122

    
123
        public String propertyURI(String name) {
124
            return schemaUri + name;
125
        }
126

    
127
    }
128

    
129
    public enum SubCheckListId {
130

    
131
        eunis, natura_2000;
132
    }
133

    
134
    private enum RankLevel{
135

    
136
        Kingdom, Phylum, Clazz, Order, Family, Genus;
137
    }
138

    
139
    public EEA_BDC_Client() {
140

    
141
        super();
142
    }
143

    
144
    public EEA_BDC_Client(String checklistInfoJson) throws DRFChecklistException {
145

    
146
        super(checklistInfoJson);
147
    }
148

    
149
    @Override
150
    public void initQueryClient() {
151

    
152
        if(SparqlClient.class.isAssignableFrom(clientClass)) {
153
            if(USE_REMOTE_SERVICE) {
154
                // use SPARQL end point
155
                //FIXME queryClient = new SparqlClient(SPARQL_ENDPOINT_URL);
156
            } else {
157
                TDBStore tripleStore;
158
                try {
159
                    tripleStore = new TDBStore();
160
                } catch (Exception e1) {
161
                    throw new RuntimeException("Creation of TripleStore failed",  e1);
162
                }
163
                if(REFRESH_TDB) {
164
                    updateStore(tripleStore);
165
                }
166
              //FIXME queryClient = new SparqlClient(tripleStore);
167

    
168
            }
169
        } else if(TinkerPopClient.class.isAssignableFrom(clientClass)) {
170
            if(USE_REMOTE_SERVICE) {
171
                throw new RuntimeException("USE_REMOTE_SERVICE not suported by QueryClient class "+ clientClass);
172
            } else {
173
                Neo4jStore neo4jStore;
174
                try {
175
                    neo4jStore = new Neo4jStore();
176
                } catch (Exception e1) {
177
                    throw new RuntimeException("Creation of Neo4jStore failed",  e1);
178
                }
179
                if(REFRESH_TDB) {
180
                    updateStore(neo4jStore);
181
                }
182
                queryClient = new TinkerPopClient(neo4jStore);
183

    
184
            }
185

    
186
        } else {
187
            throw new RuntimeException("Unsuported QueryClient class "+ clientClass);
188
        }
189
    }
190

    
191
    /**
192
     * @param neo4jStore
193
     */
194
    private void updateStore(Store neo4jStore) {
195
        try {
196
            neo4jStore.loadIntoStore(
197
                    //SPECIES_RDF_FILE_URL,
198
                    LEGALREFS_RDF_FILE_URL,
199
                    REFERENCES_RDF_FILE_URL
200
                    );
201
        } catch (Exception e) {
202
            throw new RuntimeException("Loading "
203
                    + SPECIES_RDF_FILE_URL + ", "
204
                    + LEGALREFS_RDF_FILE_URL + ", "
205
                    + REFERENCES_RDF_FILE_URL +
206
                    " into Neo4jStore failed",  e);
207
        }
208
    }
209

    
210
    @Override
211
    public ServiceProviderInfo buildServiceProviderInfo() {
212

    
213
        ServiceProviderInfo checklistInfo = new ServiceProviderInfo(ID, LABEL, DOC_URL, COPYRIGHT_URL, getSearchModes());
214
        checklistInfo.addSubChecklist(new ServiceProviderInfo(SubCheckListId.eunis.name(), "EUNIS",
215
                "http://www.eea.europa.eu/themes/biodiversity/eunis/eunis-db#tab-metadata",
216
                "http://www.eea.europa.eu/legal/copyright", SEARCH_MODES));
217
        return checklistInfo;
218
    }
219

    
220

    
221
    /**
222
     * @param queryString
223
     * @throws DRFChecklistException
224
     */
225
    private void addPrexfixes(StringBuilder queryString) throws DRFChecklistException {
226

    
227
        for(RdfSchema schema : RdfSchema.values()) {
228
            queryString.append(String.format("PREFIX %s: <%s>\n", schema.abbreviation(), schema.schemaUri()));
229
        }
230
    }
231

    
232
    /**
233
     * @param checklistInfo
234
     * @return
235
     * @throws DRFChecklistException
236
     */
237
    private StringBuilder prepareQueryString() throws DRFChecklistException {
238

    
239
        StringBuilder queryString = new StringBuilder();
240
        addPrexfixes(queryString);
241
        return queryString;
242
    }
243

    
244
    private Taxon createTaxon(Vertex v) {
245

    
246
        Taxon taxon = new Taxon();
247

    
248
        TaxonName taxonName = createTaxonName(v);
249

    
250
        // Taxon
251
        taxon.setTaxonName(taxonName);
252
        taxon.setIdentifier(v.getId().toString());
253
        taxon.setAccordingTo(queryClient.relatedVertexValue(v, RdfSchema.DWC, "nameAccordingToID"));
254
        URI typeUri = queryClient.relatedVertexURI(v, RdfSchema.RDF, "type");
255
        taxon.setTaxonomicStatus(typeUri.getFragment());
256

    
257
        createSources(v, taxon);
258

    
259
        /*
260

    
261
        // classification
262
        Classification c = null;
263
        Resource parentR = queryClient.objectAsResource(taxonR, RdfSchema.EUNIS_SPECIES, "taxonomy");
264
        while (parentR != null) {
265

    
266
            String level = queryClient.objectAsString(parentR, RdfSchema.EUNIS_TAXONOMY, "level");
267
            String parentTaxonName = queryClient.objectAsString(parentR, RdfSchema.EUNIS_TAXONOMY, "name");
268

    
269
            RankLevel rankLevel = null;
270
            try {
271
                rankLevel = RankLevel.valueOf(level);
272
            } catch (Exception e) {
273
                // IGNORE
274
            }
275
            if(rankLevel != null) {
276
                if(c == null) {
277
                 c = new Classification();
278
                }
279
                switch(rankLevel) {
280
                case Clazz:
281
                    c.setClazz(parentTaxonName);
282
                    break;
283
                case Family:
284
                    c.setFamily(parentTaxonName);
285
                    break;
286
                case Genus:
287
                    c.setGenus(parentTaxonName);
288
                    break;
289
                case Kingdom:
290
                    c.setKingdom(parentTaxonName);
291
                    break;
292
                case Order:
293
                    c.setOrder(parentTaxonName);
294
                    break;
295
                case Phylum:
296
                    c.setPhylum(parentTaxonName);
297
                    break;
298
                default:
299
                    break;
300
                }
301
            }
302
            Resource lastParentR = parentR;
303
            parentR = queryClient.objectAsResource(parentR, RdfSchema.EUNIS_TAXONOMY, "parent");
304
            if(lastParentR.equals(parentR)) {
305
                // avoid endless looping when data is not correct
306
                break;
307
            }
308
        }
309
        if(c != null) {
310
            taxon.setClassification(c);
311
        }
312
        */
313
        return taxon;
314
    }
315

    
316
    /**
317
     * @param model
318
     * @param taxonR
319
     * @param taxonBase
320
     */
321
    private void createSources(Vertex v, TaxonBase taxonBase) {
322

    
323
        // Sources are source references, re there others like data bases?
324

    
325
        GremlinPipeline<Graph, Vertex> taxonPipe = new GremlinPipeline<Graph, Vertex>(v);
326

    
327
        try {
328
            List<Vertex> titleVs = taxonPipe
329
                    .outE(RdfSchema.EUNIS_SPECIES.propertyURI("hasLegalReference")).inV()
330
                    .outE(RdfSchema.DCTERMS.propertyURI("source")).inV().dedup()
331
                    .outE(RdfSchema.DCTERMS.propertyURI("title")).inV()
332
                    .toList();
333
            for(Vertex tv : titleVs) {
334
                Source source = new Source();
335
                logger.error(tv.toString());
336
                source.setName(tv.getProperty(GraphSail.VALUE).toString());
337
                taxonBase.getSources().add(source);
338
            }
339
        } catch (FastNoSuchElementException e) {
340
            logger.debug("No sources found");
341
        }
342
    }
343

    
344
    /**
345
     * @param taxonR
346
     * @return
347
     */
348
    private TaxonName createTaxonName(Vertex v) {
349

    
350
        TaxonName taxonName = new TaxonName();
351
        // TaxonName
352
        taxonName.setFullName(queryClient.relatedVertexValue(v, RdfSchema.RDFS, "label"));
353
        // TODO rename CanonicalName to scientificName? compare with dwc:scientificName
354
        taxonName.setCanonicalName(queryClient.relatedVertexValue(v, RdfSchema.EUNIS_SPECIES, "binomialName"));
355
        taxonName.setRank(queryClient.relatedVertexValue(v, RdfSchema.EUNIS_SPECIES, "taxonomicRank"));
356
        return taxonName;
357
    }
358

    
359

    
360
    private void createSynonyms(Vertex taxonV, Response tnrResponse) {
361

    
362

    
363
        GremlinPipeline<Graph, Vertex> taxonPipe = new GremlinPipeline<Graph, Vertex>(taxonV);
364

    
365
        try {
366
            List<Vertex> synonymVs = taxonPipe
367
                    .inE(RdfSchema.EUNIS_SPECIES.propertyURI("eunisPrimaryName")).outV().dedup()
368
                    .toList();
369
            for(Vertex synonymV : synonymVs) {
370
                String typeUri = queryClient.relatedVertexValue(synonymV, RdfSchema.RDF, "type");
371
                String status = null;
372
                try {
373
                    status = URI.create(typeUri).getFragment();
374
                } catch (Exception e) {
375

    
376
                }
377

    
378
                if (status != null && status.equals("SpeciesSynonym")) {
379

    
380
                    Synonym synonym = new Synonym();
381

    
382
                    TaxonName taxonName = createTaxonName(synonymV);
383
                    synonym.setTaxonomicStatus(status);
384
                    synonym.setTaxonName(taxonName);
385
                    synonym.setAccordingTo(queryClient.relatedVertexValue(synonymV, RdfSchema.DWC, "nameAccordingToID"));
386

    
387
                    createSources(synonymV, synonym);
388

    
389
                    tnrResponse.getSynonym().add(synonym);
390
                }
391
            }
392
        } catch (FastNoSuchElementException e) {
393
            logger.debug("No sources found");
394
        }
395

    
396
    }
397

    
398
    /**
399
     * Returns all subjects that are related to the taxonR
400
     * via the es:eunisPrimaryName property.
401
     *
402
     * @param taxonR
403
     * @return
404
     */
405
    private List<Resource> queryForSynonyms(Resource taxonR) {
406
 /* FIXME
407
        List<Resource> synonymRList = null;
408

    
409
        try {
410
            StringBuilder queryString = prepareQueryString();
411

    
412
            queryString.append("DESCRIBE ?synonym es:eunisPrimaryName <" + taxonR.getURI() + ">");
413
            logger.debug("\n" + queryString.toString());
414

    
415
            Model model = queryClient.describe(queryString.toString());
416
            synonymRList = listSynonymResources(model, taxonR);
417

    
418
        } catch (DRFChecklistException e) {
419
            logger.error("SPARQL query error in queryForSynonyms()", e);
420
        } finally {
421
            if(synonymRList == null) {
422
                synonymRList = new ArrayList<Resource>(0);
423
            }
424
        }
425

    
426
        return synonymRList;
427
*/ return null;
428
    }
429

    
430
    /**
431
     * @param model
432
     * @return
433
     */
434
    private List<Resource> listSynonymResources(Model model, Resource taxonR) {
435
        List<Resource> synonymRList;
436
        /*
437
        Property filterProperty = model.createProperty(RdfSchema.EUNIS_SPECIES.schemaUri, "eunisPrimaryName");
438
        synonymRList = queryClient.listResources(model, filterProperty, null, taxonR);
439
        return synonymRList;
440
         */
441
        return null;
442
    }
443

    
444
    @Override
445
    public void resolveScientificNamesExact(TnrMsg tnrMsg) throws DRFChecklistException {
446

    
447
        List<Query> queryList = tnrMsg.getQuery();
448

    
449
        // selecting one request as representative, only
450
        // the search mode and addSynonmy flag are important
451
        // for the further usage of the request object
452

    
453
        for (ServiceProviderInfo checklistInfo : getServiceProviderInfo().getSubChecklists()) {
454

    
455
            Query query = singleQueryFrom(tnrMsg);
456

    
457
            boolean  TUPLEQUERY = false;
458
            boolean Neo4jINDEX = true;
459

    
460
            String filter;
461
            String queryString = query.getRequest().getQueryString();
462
            logger.debug("original queryString: "+ queryString);
463
            PipeFunction<Vertex, Boolean> matchFilter;
464
            if(query.getRequest().getSearchMode().equals(SearchMode.scientificNameLike.name())) {
465
                filter = "(regex(?name, \"^" + queryString + "\"))";
466
                matchFilter = queryClient.createStarttWithFilter(queryString);
467
                queryString = "\"" + queryString + "*\"";
468
            } else {
469
                filter = "(?name = \"" + queryString + "\")";
470
                matchFilter = queryClient.createEqualsFilter(queryString);
471
            }
472

    
473
            logger.debug("prepared queryString: "+ queryString);
474

    
475
            if(TUPLEQUERY) {
476
                StringBuilder sparql = prepareQueryString();
477
                sparql.append(
478
                        "SELECT ?eunisurl \n"
479
                        + "WHERE {\n"
480
                        + "     ?eunisurl es:binomialName ?name . \n"
481
                        + "     FILTER " + filter  + " \n"
482
                        + "}"
483
                        );
484

    
485
                Neo4jGraph neo4jGraph = (Neo4jGraph)queryClient.graph();
486
                Vertex v = neo4jGraph.getVertex(2);
487

    
488
                SailRepositoryConnection connection = null;
489
                try {
490

    
491
                    Profiler profiler = Profiler.newCpuProfiler(true);
492

    
493
                    connection = queryClient.connection();
494
                    TupleQuery tquery = connection.prepareTupleQuery(QueryLanguage.SPARQL, sparql.toString());
495
                    TupleQueryResult tqresult = tquery.evaluate();
496
                    queryClient.showResults(tqresult);
497

    
498
                    profiler.end(System.err);
499

    
500
                } catch (MalformedQueryException | RepositoryException | QueryEvaluationException e1) {
501
                    // TODO Auto-generated catch block
502
                    e1.printStackTrace();
503
                } catch (Exception e1) {
504
                    // yourkit
505
                    e1.printStackTrace();
506
                } finally {
507
                    try {
508
                        connection.close();
509
                    } catch (RepositoryException e1) {
510
                        // IGNORE //
511
                    }
512
                    connection = null;
513
                }
514

    
515
            }
516
            GremlinPipeline<Graph, Vertex> pipe = null;
517

    
518
            if(Neo4jINDEX) {
519

    
520
                Profiler profiler = Profiler.newCpuProfiler(false);
521

    
522
                logger.debug("Neo4jINDEX");
523

    
524
                Graph graph = queryClient.graph();
525
                pipe = new GremlinPipeline<Graph, Vertex>(
526
                        graph.getVertices("value", queryString)
527
                );
528

    
529

    
530
                // using the Neo4j index directly
531
//                Neo4jGraph graph = (Neo4jGraph)queryClient.graph();
532
//                Index<Neo4jVertex> vertexAutoIndex = graph.getIndex("node_auto_index", Neo4jVertex.class);
533
//                CloseableIterable<Neo4jVertex> nodes = vertexAutoIndex.query("value", "\"" + queryString + "\"");
534
//                pipe = new GremlinPipeline<Graph, Vertex>(nodes);
535

    
536
                List<Vertex> vertices = new ArrayList<Vertex>();
537
                pipe.in("http://eunis.eea.europa.eu/rdf/species-schema.rdf#binomialName").fill(vertices);
538

    
539
                for(Vertex v : vertices) {
540
                    logger.debug("  " + v.toString());
541
                }
542

    
543
                profiler.end(System.err);
544
                updateQueriesWithResponse(vertices, checklistInfo, query);
545
            }
546
        }
547
    }
548

    
549
    @Override
550
    public void resolveScientificNamesLike(TnrMsg tnrMsg) throws DRFChecklistException {
551
        // delegate to resolveScientificNamesExact,
552
        resolveScientificNamesExact(tnrMsg);
553

    
554
    }
555

    
556
    @Override
557
    public void resolveVernacularNamesExact(TnrMsg tnrMsg) throws DRFChecklistException {
558
        /*
559
        List<Query> queryList = tnrMsg.getQuery();
560

    
561
        // selecting one request as representative, only
562
        // the search mode and addSynonmy flag are important
563
        // for the further usage of the request object
564

    
565
        for (ServiceProviderInfo checklistInfo : getServiceProviderInfo().getSubChecklists()) {
566

    
567
            Query query = singleQueryFrom(tnrMsg);
568
            StringBuilder queryString = prepareQueryString();
569

    
570
            String filter;
571
            if(query.getRequest().getSearchMode().equals(SearchMode.vernacularNameLike.name())) {
572
                filter = "(regex(?name, \"" + query.getRequest().getQueryString() + "\"))";
573
            } else {
574
                // STR returns the lexical form of a literal so this matches literals in any language
575
                filter = "(STR(?name)='" + query.getRequest().getQueryString() + "')";
576
            }
577

    
578
            queryString.append(
579
                    "DESCRIBE ?eunisurl \n"
580
                    + "WHERE {\n"
581
                    + "     ?eunisurl dwc:vernacularName ?name . \n"
582
                    + "     FILTER " + filter  + " \n"
583
                    + "} \n"
584
                    + "LIMIT " + MAX_PAGING_LIMIT + " OFFSET 0"
585
                    );
586

    
587
            logger.debug("\n" + queryString.toString());
588
         */
589
 /* FIXME
590
            Model model = queryClient.describe(queryString.toString());
591
            updateQueriesWithResponse(model, checklistInfo, query); */
592
//        }
593
    }
594

    
595
    @Override
596
    public void resolveVernacularNamesLike(TnrMsg tnrMsg) throws DRFChecklistException {
597
        resolveVernacularNamesExact(tnrMsg);
598
    }
599

    
600
    @Override
601
    public void findByIdentifier(TnrMsg tnrMsg) throws DRFChecklistException {
602
        /*for (ServiceProviderInfo checklistInfo : getServiceProviderInfo().getSubChecklists()) {
603

    
604
            Query query = singleQueryFrom(tnrMsg);
605
            Resource taxonR = queryClient.getFromUri(query.getRequest().getQueryString());
606

    
607
            Response response = tnrResponseFromResource(taxonR.getModel(), taxonR, query.getRequest());
608
            query.getResponse().add(response);
609
        }
610
        */
611
    }
612

    
613
    private void updateQueriesWithResponse(List<Vertex> nodes, ServiceProviderInfo ci, Query query){
614

    
615
        if (nodes == null) {
616
            return;
617
        }
618

    
619
        logger.debug("matching nodes:");
620
        for (Vertex v : nodes) {
621
            logger.debug("  " + v.toString());
622
            printPropertyKeys(v, System.err);
623
            if(v.getProperty("kind").equals("url")) {
624
                logger.error("vertex of type 'url' expected, but was " + v.getProperty("type").equals("url"));
625
                continue;
626
            }
627
            Response tnrResponse = tnrResponseFromResource(v, query.getRequest());
628
            if(tnrResponse != null) {
629
                query.getResponse().add(tnrResponse);
630
            }
631
        }
632
    }
633

    
634
    /**
635
     * @param model
636
     * @param taxonR
637
     * @param request
638
     * @return
639
     */
640
    @SuppressWarnings("unused")
641
    private Response tnrResponseFromResource(Vertex taxonV, Request request) {
642

    
643
        Response tnrResponse = TnrMsgUtils.tnrResponseFor(getServiceProviderInfo());
644

    
645
        SearchMode searchMode = SearchMode.valueOf(request.getSearchMode());
646

    
647
        GremlinPipeline<Graph, Vertex> pipe = new GremlinPipeline<Graph, Vertex>(taxonV);
648

    
649
        String validName = queryClient.relatedVertexValue(taxonV, RdfSchema.EUNIS_SPECIES, "validName");
650

    
651
        boolean isAccepted = validName != null && validName.equals("true");
652
        boolean skipThis = false;
653

    
654
        logger.debug("processing " + (isAccepted ? "accepted taxon" : "synonym or other")  + " " + taxonV.getId());
655

    
656
        // case when accepted name
657
        if(isAccepted) {
658
            Taxon taxon = createTaxon(taxonV);
659
            tnrResponse.setTaxon(taxon);
660
            tnrResponse.setMatchingNameType(NameType.TAXON);
661
            String matchingName = taxon.getTaxonName().getCanonicalName();
662
            tnrResponse.setMatchingNameString(matchingName);
663

    
664
        }
665
        else {
666
            // case when synonym
667
            Vertex synonymV = taxonV;
668
            taxonV = null;
669
            try {
670
                taxonV = synonymV.getEdges(Direction.OUT, RdfSchema.EUNIS_SPECIES.propertyURI("eunisPrimaryName")).iterator().next().getVertex(Direction.IN);
671
            } catch(Exception e) {
672
                logger.error("No accepted taxon found for " + synonymV.toString() + " (" + synonymV.getProperty(GraphSail.VALUE) + ")");
673
            }
674

    
675
            if(taxonV != null) {
676
                Taxon taxon = createTaxon(taxonV);
677
                tnrResponse.setTaxon(taxon);
678
            } else {
679
            }
680
            tnrResponse.setMatchingNameType(NameType.SYNONYM);
681
            String matchingName = queryClient.relatedVertexValue(synonymV, RdfSchema.EUNIS_SPECIES, "binomialName");
682
            tnrResponse.setMatchingNameString(matchingName);
683
        }
684

    
685
        if(!skipThis && request.isAddSynonymy()) {
686
            createSynonyms(taxonV, tnrResponse);
687
        }
688

    
689
        logger.debug("processing " + (isAccepted ? "accepted taxon" : "synonym or other")  + " " + taxonV.getId() + " DONE");
690
        return tnrResponse;
691
    }
692

    
693
    /**
694
     * @param vertex
695
     */
696
    private void printEdges(Neo4jVertex vertex) {
697
        Iterable<Relationship> rels = vertex.getRawVertex().getRelationships();
698
        Iterator<Relationship> iterator = rels.iterator();
699
        if(iterator.hasNext()) {
700
            Relationship rel = iterator.next();
701
            System.err.println(rel.toString() + ": " + rel.getStartNode().toString() + "-[" +  rel.getType() + "]-" + rel.getEndNode().toString());
702
        }
703
    }
704

    
705
    private void printPropertyKeys(Vertex v, PrintStream ps) {
706
        StringBuilder out = new StringBuilder();
707
        out.append(v.toString());
708
        for(String key : v.getPropertyKeys()) {
709
            out.append(key).append(": ").append(v.getProperty(key)).append(" ");
710
        }
711
        ps.println(out.toString());
712
    }
713

    
714
    @Override
715
    public EnumSet<SearchMode> getSearchModes() {
716
        return SEARCH_MODES;
717
    }
718

    
719
    @Override
720
    public boolean isSupportedIdentifier(String value) {
721
        return IdentifierUtils.checkURI(value);
722
    }
723

    
724
}
(5-5/12)