Revision 48a7f02a
Added by Andreas Kohlbecker over 8 years ago
README-DEVELOPER.md | ||
---|---|---|
3 | 3 |
|
4 | 4 |
### compiling the schema: |
5 | 5 |
|
6 |
mvn jaxb2:generate |
|
6 |
mvn jaxb2:generate
|
|
7 | 7 |
|
8 |
the xml schema file contains ```<annox:annotate>``` elements
|
|
8 |
the xml schema file contains ``<annox:annotate>`` elements
|
|
9 | 9 |
for the xjc Annotate Plugin which will compile them into java annotations. |
10 | 10 |
See https://github.com/highsource/jaxb2-annotate-plugin for more information. |
11 | 11 |
|
... | ... | |
14 | 14 |
re-enable the disabled dependencies in the pom.xml by un-commenting them. The according section is |
15 | 15 |
between: |
16 | 16 |
|
17 |
``` |
|
18 |
<!-- ======================================================================= --> |
|
19 |
<!-- Dependencies needed for Apache Axix WSDL2Java (only during development) --> |
|
20 |
... |
|
21 |
<!-- ======================================================================= --> |
|
22 |
``` |
|
17 |
<!-- ======================================================================= --> |
|
18 |
<!-- Dependencies needed for Apache Axix WSDL2Java (only during development) --> |
|
19 |
... |
|
20 |
<!-- ======================================================================= --> |
|
21 |
|
|
23 | 22 |
then compile the java classes |
24 | 23 |
|
25 |
``` |
|
26 |
java -cp $(mvn3 dependency:build-classpath | grep -v "\[") org.apache.axis.wsdl.WSDL2Java <url-to-wsdl-file> |
|
27 |
``` |
|
24 |
|
|
25 |
java -cp $(mvn3 dependency:build-classpath | grep -v "\[") org.apache.axis.wsdl.WSDL2Java <url-to-wsdl-file> |
README.md | ||
---|---|---|
1 | 1 |
|
2 | 2 |
Synopsis |
3 | 3 |
======== |
4 |
This project contains all the components required to run the [BioVeL Data Refinement Workflow](https://wiki.biovel.eu/display/doc/Data+Refinement+Workflow)
|
|
4 |
This project contains all the core libraries for the **Unified Taxonomic Information Service (UTIS)**. UTIS has been developed as taxonomic backbone for the EU BON project (http://eubon.eu/).
|
|
5 | 5 |
|
6 |
For more details regarding BioVeL, please visit [www.biovel.eu](www.biovel.eu) |
|
6 |
The main objective of EU BON is to build a substantial part of the Group on Earth Observation’s Biodiversity Observation Network (GEO BON). |
|
7 |
|
|
8 |
This project has received funding from the European Union’s Seventh Programme for research, technological development and demonstration under grant agreement No 308454. |
|
7 | 9 |
|
8 |
BioVeL is funded by the European Commission 7th Framework Programme (FP7), through the grant agreement number 283359. |
|
9 | 10 |
|
10 | 11 |
Installation |
11 | 12 |
============ |
12 | 13 |
|
13 | 14 |
|
14 | 15 |
|
15 |
Third-Party Dependencies |
|
16 |
======================== |
|
16 |
Acknowledgement |
|
17 |
=============== |
|
18 |
|
|
19 |
This work is based on a development for the BioVeL project, the [BioVeL Data Refinement Workflow](https://wiki.biovel.eu/display/doc/Data+Refinement+Workflow) |
|
17 | 20 |
|
18 |
Libraries |
|
19 |
--------- |
|
21 |
The original sources of the drf-workflow library are hosted at [https://github.com/BioVeL/drf-workflow.git](https://github.com/BioVeL/drf-workflow.git) |
|
20 | 22 |
|
21 |
Services |
|
22 |
------- |
|
23 |
For more details regarding BioVeL, please visit [www.biovel.eu](www.biovel.eu) |
|
24 |
|
|
25 |
BioVeL is funded by the European Commission 7th Framework Programme (FP7), through the grant agreement number 283359. |
|
23 | 26 |
|
24 | 27 |
License |
25 | 28 |
======= |
pom.xml | ||
---|---|---|
1 | 1 |
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
2 | 2 |
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> |
3 | 3 |
<modelVersion>4.0.0</modelVersion> |
4 |
<groupId>biovel.drf</groupId>
|
|
5 |
<artifactId>drf-workflow</artifactId>
|
|
4 |
<groupId>org.cybertaxonomy</groupId>
|
|
5 |
<artifactId>utis-core</artifactId>
|
|
6 | 6 |
<packaging>jar</packaging> |
7 | 7 |
<version>1.1.0-SNAPSHOT</version> |
8 |
<name>drf-workflow</name> |
|
8 |
<name>UTIS-Core</name> |
|
9 |
<description>Unified Taxonomic Information Service core libraries</description> |
|
9 | 10 |
<url>http://maven.apache.org</url> |
10 | 11 |
<repositories> |
11 | 12 |
<repository> |
... | ... | |
287 | 288 |
</execution> |
288 | 289 |
</executions> |
289 | 290 |
<configuration> |
290 |
<schemaDirectory>src/main/resources/org/bgbm/biovel/drf/tnr</schemaDirectory>
|
|
291 |
<schemaDirectory>src/main/resources/org/cybertaxonomy/utis/tnr</schemaDirectory>
|
|
291 | 292 |
<generateDirectory>src/main/java</generateDirectory> |
292 | 293 |
<!-- removeOldOutput>false</removeOldOutput> --> |
293 | 294 |
<cleanPackageDirectories>true</cleanPackageDirectories> |
src/main/java/org/bgbm/biovel/drf/checklist/AggregateChecklistClient.java | ||
---|---|---|
1 |
package org.bgbm.biovel.drf.checklist; |
|
2 |
|
|
3 |
import org.bgbm.biovel.drf.client.ServiceProviderInfo; |
|
4 |
import org.bgbm.biovel.drf.query.IQueryClient; |
|
5 |
|
|
6 |
|
|
7 |
public abstract class AggregateChecklistClient<QC extends IQueryClient> extends BaseChecklistClient<QC> { |
|
8 |
|
|
9 |
public AggregateChecklistClient() { |
|
10 |
super(); |
|
11 |
} |
|
12 |
|
|
13 |
public AggregateChecklistClient(String checklistInfoJson) throws DRFChecklistException { |
|
14 |
super(checklistInfoJson); |
|
15 |
} |
|
16 |
|
|
17 |
public AggregateChecklistClient(ServiceProviderInfo spiInfo) throws DRFChecklistException { |
|
18 |
super(spiInfo); |
|
19 |
} |
|
20 |
|
|
21 |
} |
src/main/java/org/bgbm/biovel/drf/checklist/BaseChecklistClient.java | ||
---|---|---|
1 |
package org.bgbm.biovel.drf.checklist; |
|
2 |
|
|
3 |
import java.util.EnumSet; |
|
4 |
import java.util.Iterator; |
|
5 |
import java.util.List; |
|
6 |
|
|
7 |
import org.bgbm.biovel.drf.client.AbstractClient; |
|
8 |
import org.bgbm.biovel.drf.client.ServiceProviderInfo; |
|
9 |
import org.bgbm.biovel.drf.query.IQueryClient; |
|
10 |
import org.bgbm.biovel.drf.tnr.msg.Query; |
|
11 |
import org.bgbm.biovel.drf.tnr.msg.TnrMsg; |
|
12 |
import org.bgbm.biovel.drf.utils.TnrMsgUtils; |
|
13 |
import org.slf4j.Logger; |
|
14 |
import org.slf4j.LoggerFactory; |
|
15 |
|
|
16 |
public abstract class BaseChecklistClient<QC extends IQueryClient> extends AbstractClient<QC> { |
|
17 |
|
|
18 |
protected Logger logger = LoggerFactory.getLogger(BaseChecklistClient.class); |
|
19 |
|
|
20 |
protected final static String CHECKLIST_KEY = "checklist"; |
|
21 |
protected final static String CHECKLIST_URL_KEY = "checklist_url"; |
|
22 |
protected final static String COPYRIGHT_URL_KEY = "copyright_url"; |
|
23 |
protected final static String CHECKLIST_LIST = "checklist_list"; |
|
24 |
|
|
25 |
public BaseChecklistClient() { |
|
26 |
super(); |
|
27 |
} |
|
28 |
|
|
29 |
public BaseChecklistClient(String checklistInfoJson) throws DRFChecklistException { |
|
30 |
super(checklistInfoJson); |
|
31 |
} |
|
32 |
|
|
33 |
public BaseChecklistClient(ServiceProviderInfo spInfo) throws DRFChecklistException { |
|
34 |
super(spInfo); |
|
35 |
} |
|
36 |
|
|
37 |
|
|
38 |
/** |
|
39 |
* @param tnrMsg |
|
40 |
* @return |
|
41 |
* @throws DRFChecklistException |
|
42 |
*/ |
|
43 |
protected Query singleQueryFrom(TnrMsg tnrMsg) throws DRFChecklistException { |
|
44 |
List<Query> queryList = tnrMsg.getQuery(); |
|
45 |
if(queryList.size() == 0) { |
|
46 |
throw new DRFChecklistException("query list is empty"); |
|
47 |
} |
|
48 |
|
|
49 |
if(queryList.size() > 1) { |
|
50 |
throw new DRFChecklistException("query list has more than one query"); |
|
51 |
} |
|
52 |
Query query = queryList.get(0); |
|
53 |
return query; |
|
54 |
} |
|
55 |
|
|
56 |
public void queryChecklist(List<TnrMsg> tnrMsgs) throws DRFChecklistException { |
|
57 |
|
|
58 |
TnrMsg finalTnrMsg = new TnrMsg(); |
|
59 |
Iterator<TnrMsg> itrTnrMsg = tnrMsgs.iterator(); |
|
60 |
while(itrTnrMsg.hasNext()) { |
|
61 |
Iterator<Query> itrQuery = itrTnrMsg.next().getQuery().iterator(); |
|
62 |
while(itrQuery.hasNext()) { |
|
63 |
finalTnrMsg.getQuery().add(itrQuery.next()); |
|
64 |
} |
|
65 |
} |
|
66 |
|
|
67 |
queryChecklist(finalTnrMsg); |
|
68 |
} |
|
69 |
|
|
70 |
/** |
|
71 |
* |
|
72 |
* @param tnrMsg |
|
73 |
* @throws DRFChecklistException |
|
74 |
*/ |
|
75 |
public void queryChecklist(TnrMsg tnrMsg) throws DRFChecklistException { |
|
76 |
|
|
77 |
TnrMsgUtils.assertSearchModeSet(tnrMsg, true); |
|
78 |
|
|
79 |
SearchMode mode = TnrMsgUtils.getSearchMode(tnrMsg); |
|
80 |
|
|
81 |
preExcuteQuery(tnrMsg); |
|
82 |
|
|
83 |
if(!getSearchModes().contains(mode)){ |
|
84 |
throw new DRFChecklistException("Unsupported SearchMode"); |
|
85 |
} |
|
86 |
if (getSearchModes().contains(mode)){ |
|
87 |
switch(mode){ |
|
88 |
case scientificNameExact: |
|
89 |
resolveScientificNamesExact(tnrMsg); |
|
90 |
break; |
|
91 |
case scientificNameLike: |
|
92 |
resolveScientificNamesLike(tnrMsg); |
|
93 |
break; |
|
94 |
case vernacularNameExact: |
|
95 |
resolveVernacularNamesExact(tnrMsg); |
|
96 |
break; |
|
97 |
case vernacularNameLike: |
|
98 |
resolveVernacularNamesLike(tnrMsg); |
|
99 |
break; |
|
100 |
case findByIdentifier: |
|
101 |
if(checkSupportedIdentifieres(tnrMsg)){ |
|
102 |
findByIdentifier(tnrMsg); |
|
103 |
} else { |
|
104 |
logger.info("The queries contain unsupported identifier strings"); |
|
105 |
throw new UnsupportedIdentifierException("Queries contain unsupported identifier strings"); |
|
106 |
} |
|
107 |
break; |
|
108 |
default: |
|
109 |
throw new DRFChecklistException("Unimplemented SearchMode"); |
|
110 |
} |
|
111 |
} else { |
|
112 |
logger.info("Search mode " + mode + " not supported by this ChecklistClient implementation"); |
|
113 |
} |
|
114 |
|
|
115 |
postExcuteQuery(tnrMsg); |
|
116 |
} |
|
117 |
|
|
118 |
/** |
|
119 |
* @param tnrMsg |
|
120 |
*/ |
|
121 |
private void postExcuteQuery(TnrMsg tnrMsg) { |
|
122 |
// empty stub, to be implemented by subclasses if necessary |
|
123 |
} |
|
124 |
|
|
125 |
/** |
|
126 |
* @param tnrMsg |
|
127 |
*/ |
|
128 |
private void preExcuteQuery(TnrMsg tnrMsg) { |
|
129 |
// empty stub, to be implemented by subclasses if necessary |
|
130 |
} |
|
131 |
|
|
132 |
/** |
|
133 |
* Checks all the queries of the <code>tnrMsg</code> of they |
|
134 |
* contain a query string which is supported as identifier by the |
|
135 |
* implementing checklist client. |
|
136 |
* <p> |
|
137 |
* Fails if only one of the query string is not supported! |
|
138 |
* |
|
139 |
* @param tnrMsg |
|
140 |
* @return |
|
141 |
*/ |
|
142 |
private boolean checkSupportedIdentifieres(TnrMsg tnrMsg) { |
|
143 |
for (Query q : tnrMsg.getQuery()){ |
|
144 |
if(! isSupportedIdentifier(q.getRequest().getQueryString())){ |
|
145 |
return false; |
|
146 |
} |
|
147 |
} |
|
148 |
return true; |
|
149 |
} |
|
150 |
|
|
151 |
/** |
|
152 |
* Searches for scientific names which exactly match the given query string. |
|
153 |
* |
|
154 |
* @param tnrMsg |
|
155 |
* @throws DRFChecklistException |
|
156 |
*/ |
|
157 |
public abstract void resolveScientificNamesExact(TnrMsg tnrMsg) throws DRFChecklistException; |
|
158 |
|
|
159 |
/** |
|
160 |
* Searches for scientific names which start with the given query string. |
|
161 |
* |
|
162 |
* @param tnrMsg |
|
163 |
* @throws DRFChecklistException |
|
164 |
*/ |
|
165 |
public abstract void resolveScientificNamesLike(TnrMsg tnrMsg) throws DRFChecklistException; |
|
166 |
|
|
167 |
/** |
|
168 |
* Searches for taxa with an vernacular name that exactly match the given query string. |
|
169 |
* |
|
170 |
* @param tnrMsg |
|
171 |
* @throws DRFChecklistException |
|
172 |
*/ |
|
173 |
public abstract void resolveVernacularNamesExact(TnrMsg tnrMsg) throws DRFChecklistException; |
|
174 |
|
|
175 |
/** |
|
176 |
* Searches for taxa with an vernacular name that contains the given query string. |
|
177 |
* |
|
178 |
* @param tnrMsg |
|
179 |
* @throws DRFChecklistException |
|
180 |
*/ |
|
181 |
public abstract void resolveVernacularNamesLike(TnrMsg tnrMsg) throws DRFChecklistException; |
|
182 |
|
|
183 |
/** |
|
184 |
* Searches taxa having a specific identifier |
|
185 |
* |
|
186 |
* @param tnrMsg |
|
187 |
* @throws DRFChecklistException |
|
188 |
*/ |
|
189 |
public abstract void findByIdentifier(TnrMsg tnrMsg) throws DRFChecklistException; |
|
190 |
|
|
191 |
public abstract EnumSet<SearchMode> getSearchModes(); |
|
192 |
|
|
193 |
public abstract boolean isSupportedIdentifier(String value); |
|
194 |
|
|
195 |
} |
src/main/java/org/bgbm/biovel/drf/checklist/BgbmEditClient.java | ||
---|---|---|
1 |
package org.bgbm.biovel.drf.checklist; |
|
2 |
|
|
3 |
|
|
4 |
import java.net.URI; |
|
5 |
import java.util.ArrayList; |
|
6 |
import java.util.EnumSet; |
|
7 |
import java.util.HashMap; |
|
8 |
import java.util.Iterator; |
|
9 |
import java.util.List; |
|
10 |
import java.util.Map; |
|
11 |
|
|
12 |
import org.apache.http.HttpHost; |
|
13 |
import org.apache.http.ParseException; |
|
14 |
import org.bgbm.biovel.drf.client.ServiceProviderInfo; |
|
15 |
import org.bgbm.biovel.drf.query.RestClient; |
|
16 |
import org.bgbm.biovel.drf.tnr.msg.Classification; |
|
17 |
import org.bgbm.biovel.drf.tnr.msg.NameType; |
|
18 |
import org.bgbm.biovel.drf.tnr.msg.Query; |
|
19 |
import org.bgbm.biovel.drf.tnr.msg.Response; |
|
20 |
import org.bgbm.biovel.drf.tnr.msg.Source; |
|
21 |
import org.bgbm.biovel.drf.tnr.msg.Synonym; |
|
22 |
import org.bgbm.biovel.drf.tnr.msg.Taxon; |
|
23 |
import org.bgbm.biovel.drf.tnr.msg.TaxonName; |
|
24 |
import org.bgbm.biovel.drf.tnr.msg.TnrMsg; |
|
25 |
import org.bgbm.biovel.drf.utils.IdentifierUtils; |
|
26 |
import org.bgbm.biovel.drf.utils.TnrMsgUtils; |
|
27 |
import org.gbif.nameparser.NameParser; |
|
28 |
import org.json.simple.JSONArray; |
|
29 |
import org.json.simple.JSONAware; |
|
30 |
import org.json.simple.JSONObject; |
|
31 |
import org.json.simple.parser.JSONParser; |
|
32 |
|
|
33 |
public class BgbmEditClient extends AggregateChecklistClient<RestClient> { |
|
34 |
|
|
35 |
/** |
|
36 |
* |
|
37 |
*/ |
|
38 |
public static final String ID = "bgbm-cdm-server"; |
|
39 |
public static final String LABEL = "Name catalogues served by the BGBM CDM Server"; |
|
40 |
public static final String DOC_URL = "http://wp5.e-taxonomy.eu/cdmlib/rest-api-name-catalogue.html"; |
|
41 |
public static final String COPYRIGHT_URL = "http://wp5.e-taxonomy.eu/cdmlib/license.html"; |
|
42 |
private static final String SERVER_PATH_PREFIX = "/"; |
|
43 |
private static final HttpHost HTTP_HOST = new HttpHost("api.cybertaxonomy.org", 80); // new HttpHost("test.e-taxonomy.eu", 80); |
|
44 |
|
|
45 |
|
|
46 |
private final Map<String,Query> taxonIdQueryMap = new HashMap<String,Query>(); |
|
47 |
|
|
48 |
private final Map<String,String> taxonIdMatchStringMap = new HashMap<String, String>(); |
|
49 |
|
|
50 |
public static final EnumSet<SearchMode> SEARCH_MODES = EnumSet.of( |
|
51 |
SearchMode.scientificNameExact, |
|
52 |
SearchMode.scientificNameLike, |
|
53 |
SearchMode.findByIdentifier |
|
54 |
); |
|
55 |
|
|
56 |
public BgbmEditClient() { |
|
57 |
super(); |
|
58 |
} |
|
59 |
|
|
60 |
public BgbmEditClient(String checklistInfoJson) throws DRFChecklistException { |
|
61 |
super(checklistInfoJson); |
|
62 |
} |
|
63 |
|
|
64 |
@Override |
|
65 |
public void initQueryClient() { |
|
66 |
queryClient = new RestClient(HTTP_HOST); |
|
67 |
} |
|
68 |
|
|
69 |
|
|
70 |
@Override |
|
71 |
public ServiceProviderInfo buildServiceProviderInfo() { |
|
72 |
ServiceProviderInfo checklistInfo = new ServiceProviderInfo(ID,LABEL,DOC_URL,COPYRIGHT_URL, getSearchModes()); |
|
73 |
checklistInfo.addSubChecklist(new ServiceProviderInfo("col", |
|
74 |
"Catalogue Of Life (EDIT - name catalogue end point)", |
|
75 |
"http://wp5.e-taxonomy.eu/cdmlib/rest-api-name-catalogue.html", |
|
76 |
"http://www.catalogueoflife.org/col/info/copyright", ServiceProviderInfo.DEFAULT_SEARCH_MODE)); |
|
77 |
return checklistInfo; |
|
78 |
} |
|
79 |
|
|
80 |
/** |
|
81 |
* Adds the acceptedTaxonUuids found in the <code>responseBody</code> to the |
|
82 |
* private field <code>taxonIdQueryMap</code> |
|
83 |
* and populates the <code>taxonIdMatchStringMap</code> |
|
84 |
* |
|
85 |
* @param queryList |
|
86 |
* @param responseBodyJson |
|
87 |
* @throws DRFChecklistException |
|
88 |
*/ |
|
89 |
private void buildTaxonIdMapsFromCatalogueServiceResponse(List<Query> queryList , String responseBody) throws DRFChecklistException { |
|
90 |
|
|
91 |
JSONArray responseBodyJson = parseResponseBody(responseBody, JSONArray.class); |
|
92 |
|
|
93 |
if(responseBodyJson.size() != queryList.size()){ |
|
94 |
throw new DRFChecklistException("Query and Response lists have different lengths"); |
|
95 |
} |
|
96 |
|
|
97 |
Iterator<JSONObject> itrNameMsgs = responseBodyJson.iterator(); |
|
98 |
|
|
99 |
for (Query query : queryList) { |
|
100 |
JSONArray responseArray = (JSONArray) itrNameMsgs.next().get("response"); |
|
101 |
if(responseArray != null) { |
|
102 |
Iterator<JSONObject> resIterator = responseArray.iterator(); |
|
103 |
while (resIterator.hasNext()) { |
|
104 |
JSONObject res = resIterator.next(); |
|
105 |
JSONArray accTaxonUuidArray = (JSONArray) res.get("acceptedTaxonUuids"); |
|
106 |
String matchingName = res.get("title").toString(); |
|
107 |
Iterator<String> atIterator = accTaxonUuidArray.iterator(); |
|
108 |
while (atIterator.hasNext()) { |
|
109 |
String acceptedTaxonId = atIterator.next(); |
|
110 |
boolean isAcceptedTaxonMatch = res.get("taxonConceptUuids").toString().contains(acceptedTaxonId); |
|
111 |
if(!taxonIdQueryMap.containsKey(acceptedTaxonId) || isAcceptedTaxonMatch){ |
|
112 |
// matches for accepted taxa should be preferred here |
|
113 |
// matches for synomymy or other types should never overwrite |
|
114 |
// accepted taxon matches |
|
115 |
taxonIdQueryMap.put(acceptedTaxonId, query); |
|
116 |
taxonIdMatchStringMap.put(acceptedTaxonId, matchingName); |
|
117 |
} |
|
118 |
//System.out.println("Found accepted taxon id : " + accTaxonId); |
|
119 |
} |
|
120 |
} |
|
121 |
} |
|
122 |
} |
|
123 |
} |
|
124 |
|
|
125 |
/** |
|
126 |
* Adds the acceptedTaxonUuids found in the <code>responseBody</code> to the |
|
127 |
* private field <code>taxonIdQueryMap</code> |
|
128 |
* and populates the <code>taxonIdMatchStringMap</code> |
|
129 |
* |
|
130 |
* @param queryList |
|
131 |
* @param responseBodyJson |
|
132 |
* @throws DRFChecklistException |
|
133 |
*/ |
|
134 |
private void addTaxaToTaxonIdMapFromIdentifierServiceResponse(List<Query> queryList , String responseBody) throws DRFChecklistException { |
|
135 |
|
|
136 |
/* |
|
137 |
* {"class":"DefaultPagerImpl","count":8,"currentIndex":0,"firstRecord":1,"indices":[0],"lastRecord":8,"nextIndex":0,"pageSize":30,"pagesAvailable":1,"prevIndex":0, |
|
138 |
"records":[ |
|
139 |
{ |
|
140 |
"cdmEntity":{ |
|
141 |
"cdmUuid":"0cf5a6fe-b1df-4f4f-85a8-31fef4be2a68", |
|
142 |
"class":"CdmEntity", |
|
143 |
"titleCache":"Abies alba Mill. sec. SCHMEIL-FITSCHEN, Flora von Deutschland und angrenzenden Ländern, 89. Aufl"}, |
|
144 |
"class":"FindByIdentifierDTO", |
|
145 |
"identifier":{"class":"AlternativeIdentifier","identifier":"1","typeLabel":"Florein Identifier","typeUuid":"8b67291e-96e0-4556-8d6a-c94e8750b301"}},{"cdmEntity":{"cdmUuid":"3d256539-d7f7-4dd1-ad7f-cd6e4c141f24","class":"CdmEntity","titleCache":"Abies alba Mill. sec. OBERDORFER, Pflanzensoziologische Exkursionsflora, ed. 7"},"class":"FindByIdentifierDTO","identifier":{"class":"AlternativeIdentifier","identifier":"1","typeLabel":"Florein Identifier","typeUuid":"8b67291e-96e0-4556-8d6a-c94e8750b301"}},{"cdmEntity":{"cdmUuid":"61c2bc4f-a23d-4160-8f14-625b4484fc2f","class":"CdmEntity","titleCache":"Abies alba Mill. sec. HEGI, Illustrierte Flora von Mitteleuropa, Aufl. 2 u. 3"},"class":"FindByIdentifierDTO","identifier":{"class":"AlternativeIdentifier","identifier":"1","typeLabel":"Florein Identifier","typeUuid":"8b67291e-96e0-4556-8d6a-c94e8750b301"}},{"cdmEntity":{"cdmUuid":"7a63f215-0a41-4b7e-9394-bda4521d6ad1","class":"CdmEntity","titleCache":"Abies alba Mill. sec. GREUTER et. al., Med-Checklist bisher Bde. 1, 3 und 4"},"class":"FindByIdentifierDTO","identifier":{"class":"AlternativeIdentifier","identifier":"1","typeLabel":"Florein Identifier","typeUuid":"8b67291e-96e0-4556-8d6a-c94e8750b301"}},{"cdmEntity":{"cdmUuid":"872088a4-95f4-472c-ae79-a29028bb3fbf","class":"CdmEntity","titleCache":"Abies alba Mill. sec. Wisskirchen & Haeupler, 1998"},"class":"FindByIdentifierDTO","identifier":{"class":"AlternativeIdentifier","identifier":"1","typeLabel":"Florein Identifier","typeUuid":"8b67291e-96e0-4556-8d6a-c94e8750b301"}},{"cdmEntity":{"cdmUuid":"90ee17be-d455-4564-949d-9c53e27a6a6f","class":"CdmEntity","titleCache":"Abies alba Mill. sec. TUTIN et al., Flora Europaea"},"class":"FindByIdentifierDTO","identifier":{"class":"AlternativeIdentifier","identifier":"1","typeLabel":"Florein Identifier","typeUuid":"8b67291e-96e0-4556-8d6a-c94e8750b301"}},{"cdmEntity":{"cdmUuid":"b0d35335-63e6-41ab-bdb0-d01851134e9c","class":"CdmEntity","titleCache":"Abies alba Mill. sec. EHRENDORFER, Liste der Gefäßpflanzen Mitteleuropas, 2. Aufl"},"class":"FindByIdentifierDTO","identifier":{"class":"AlternativeIdentifier","identifier":"1","typeLabel":"Florein Identifier","typeUuid":"8b67291e-96e0-4556-8d6a-c94e8750b301"}},{"cdmEntity":{"cdmUuid":"b7a352aa-1f73-41f3-a4e3-b24fc1c2cd5f","class":"CdmEntity","titleCache":"Abies alba Mill. sec. ROTHMALER, 1990"},"class":"FindByIdentifierDTO","identifier":{"class":"AlternativeIdentifier","identifier":"1","typeLabel":"Florein Identifier","typeUuid":"8b67291e-96e0-4556-8d6a-c94e8750b301"}}],"suggestion":""} |
|
146 |
*/ |
|
147 |
|
|
148 |
if(queryList.size() > 1){ |
|
149 |
throw new DRFChecklistException("Only single Querys are supported"); |
|
150 |
} |
|
151 |
|
|
152 |
Query query = queryList.get(0); |
|
153 |
|
|
154 |
JSONObject jsonPager = parseResponseBody(responseBody, JSONObject.class); |
|
155 |
|
|
156 |
JSONArray jsonRecords = (JSONArray) jsonPager.get("records"); |
|
157 |
|
|
158 |
|
|
159 |
Iterator<JSONObject> resIterator = jsonRecords.iterator(); |
|
160 |
while (resIterator.hasNext()) { |
|
161 |
JSONObject record = resIterator.next(); |
|
162 |
JSONObject cdmEntity = (JSONObject) record.get("cdmEntity"); |
|
163 |
String uuid = cdmEntity.get("cdmUuid").toString(); |
|
164 |
taxonIdQueryMap.put(uuid, query); |
|
165 |
} |
|
166 |
|
|
167 |
} |
|
168 |
|
|
169 |
private void addTaxonToTaxonIdMap(List<Query> queryList , String responseBody) throws DRFChecklistException { |
|
170 |
|
|
171 |
|
|
172 |
if(queryList.size() > 1){ |
|
173 |
throw new DRFChecklistException("Only single Querys are supported"); |
|
174 |
} |
|
175 |
|
|
176 |
Query query = queryList.get(0); |
|
177 |
|
|
178 |
JSONObject cdmEntity = parseResponseBody(responseBody, JSONObject.class); |
|
179 |
String uuid = cdmEntity.get("uuid").toString(); |
|
180 |
taxonIdQueryMap.put(uuid, query); |
|
181 |
|
|
182 |
} |
|
183 |
|
|
184 |
/** |
|
185 |
* @param responseBody |
|
186 |
* @return |
|
187 |
* @throws DRFChecklistException |
|
188 |
*/ |
|
189 |
private <T extends JSONAware> T parseResponseBody(String responseBody, Class<T> jsonType) throws DRFChecklistException { |
|
190 |
// TODO use Jackson instead? it is much faster! |
|
191 |
JSONParser parser = new JSONParser(); |
|
192 |
Object obj; |
|
193 |
try { |
|
194 |
obj = parser.parse(responseBody); |
|
195 |
} catch (ParseException e) { |
|
196 |
logger.error("parseResponseBody() - ", e); |
|
197 |
throw new DRFChecklistException(e); |
|
198 |
} catch (org.json.simple.parser.ParseException e) { |
|
199 |
|
|
200 |
logger.error("parseResponseBody() - ", e); |
|
201 |
throw new DRFChecklistException(e); |
|
202 |
} |
|
203 |
|
|
204 |
if(jsonType.isAssignableFrom(obj.getClass())){ |
|
205 |
return jsonType.cast(obj); |
|
206 |
} else { |
|
207 |
throw new DRFChecklistException("parseResponseBody() - deserialized responseBody is not of type " + jsonType ) ; |
|
208 |
} |
|
209 |
|
|
210 |
} |
|
211 |
|
|
212 |
private Taxon generateAccName(JSONObject taxon) { |
|
213 |
Taxon accTaxon = new Taxon(); |
|
214 |
TaxonName taxonName = new TaxonName(); |
|
215 |
|
|
216 |
String resName = (String) taxon.get("name"); |
|
217 |
taxonName.setFullName(resName); |
|
218 |
NameParser ecatParser = new NameParser(); |
|
219 |
String nameCanonical = ecatParser.parseToCanonical(resName); |
|
220 |
taxonName.setCanonicalName(nameCanonical); |
|
221 |
|
|
222 |
taxonName.setRank((String) taxon.get("rank")); |
|
223 |
String lsid = (String) taxon.get("lsid"); |
|
224 |
|
|
225 |
JSONObject scrutinyjs = (JSONObject)taxon.get("taxonomicScrutiny"); |
|
226 |
String accordingTo = (String) scrutinyjs.get("accordingTo"); |
|
227 |
String modified = (String) scrutinyjs.get("modified"); |
|
228 |
|
|
229 |
accTaxon.setTaxonName(taxonName); |
|
230 |
accTaxon.setTaxonomicStatus((String)taxon.get("taxonStatus")); |
|
231 |
accTaxon.setAccordingTo(accordingTo); |
|
232 |
accTaxon.setIdentifier(lsid); |
|
233 |
|
|
234 |
JSONObject sourcejs = (JSONObject)taxon.get("source"); |
|
235 |
String sourceUrl = (String) sourcejs.get("url"); |
|
236 |
String sourceDatasetID = (String) sourcejs.get("datasetID"); |
|
237 |
String sourceDatasetName = (String) sourcejs.get("datasetName"); |
|
238 |
String sourceName = ""; |
|
239 |
|
|
240 |
Source source = new Source(); |
|
241 |
source.setIdentifier(sourceDatasetID); |
|
242 |
source.setDatasetName(sourceDatasetName); |
|
243 |
source.setName(sourceName); |
|
244 |
source.setUrl(sourceUrl); |
|
245 |
accTaxon.getSources().add(source); |
|
246 |
|
|
247 |
JSONObject classification =(JSONObject)taxon.get("classification"); |
|
248 |
if(classification != null) { |
|
249 |
Classification c = new Classification(); |
|
250 |
c.setKingdom((String) classification.get("Kingdom")); |
|
251 |
c.setPhylum((String) classification.get("Phylum")); |
|
252 |
c.setClazz((String) classification.get("Class")); |
|
253 |
c.setOrder((String) classification.get("Order")); |
|
254 |
c.setFamily((String) classification.get("Family")); |
|
255 |
c.setGenus((String) classification.get("Genus")); |
|
256 |
accTaxon.setClassification(c); |
|
257 |
} |
|
258 |
return accTaxon; |
|
259 |
} |
|
260 |
|
|
261 |
private void generateSynonyms(JSONArray relatedTaxa, Response tnrResponse) { |
|
262 |
|
|
263 |
|
|
264 |
Iterator<JSONObject> itrSynonyms = relatedTaxa.iterator(); |
|
265 |
while(itrSynonyms.hasNext()) { |
|
266 |
|
|
267 |
JSONObject synonymjs = itrSynonyms.next(); |
|
268 |
String status = (String) synonymjs.get("taxonStatus"); |
|
269 |
if(status != null && status.equals("synonym")) { |
|
270 |
Synonym synonym = new Synonym(); |
|
271 |
TaxonName taxonName = new TaxonName(); |
|
272 |
|
|
273 |
String resName = (String) synonymjs.get("name"); |
|
274 |
taxonName.setFullName(resName); |
|
275 |
NameParser ecatParser = new NameParser(); |
|
276 |
String nameCanonical = ecatParser.parseToCanonical(resName); |
|
277 |
taxonName.setCanonicalName(nameCanonical); |
|
278 |
synonym.setTaxonomicStatus((String)synonymjs.get("taxonStatus")); |
|
279 |
|
|
280 |
taxonName.setRank((String) synonymjs.get("rank")); |
|
281 |
|
|
282 |
synonym.setTaxonName(taxonName); |
|
283 |
|
|
284 |
JSONObject scrutinyjs = (JSONObject)synonymjs.get("taxonomicScrutiny"); // TODO this will change in future releases of the service |
|
285 |
synonym.setAccordingTo((String) scrutinyjs.get("accordingTo")); |
|
286 |
|
|
287 |
JSONObject sourcejs = (JSONObject)synonymjs.get("source"); |
|
288 |
String sourceUrl = (String) sourcejs.get("url"); |
|
289 |
String sourceDatasetID = (String) sourcejs.get("datasetID"); |
|
290 |
String sourceDatasetName = (String) sourcejs.get("datasetName"); |
|
291 |
String sourceName = ""; |
|
292 |
|
|
293 |
Source source = new Source(); |
|
294 |
source.setIdentifier(sourceDatasetID); |
|
295 |
source.setDatasetName(sourceDatasetName); |
|
296 |
source.setName(sourceName); |
|
297 |
source.setUrl(sourceUrl); |
|
298 |
synonym.getSources().add(source); |
|
299 |
|
|
300 |
tnrResponse.getSynonym().add(synonym); |
|
301 |
} |
|
302 |
} |
|
303 |
} |
|
304 |
|
|
305 |
@Override |
|
306 |
public void resolveScientificNamesExact(TnrMsg tnrMsg) throws DRFChecklistException { |
|
307 |
|
|
308 |
List<Query> queryList = tnrMsg.getQuery(); |
|
309 |
|
|
310 |
// selecting one request as representative, only |
|
311 |
// the search mode and addSynonmy flag are important |
|
312 |
// for the further usage of the request object |
|
313 |
Query.Request request = queryList.get(0).getRequest(); |
|
314 |
|
|
315 |
for (ServiceProviderInfo checklistInfo : getServiceProviderInfo().getSubChecklists()) { |
|
316 |
URI namesUri = queryClient.buildUriFromQueryList(queryList, |
|
317 |
SERVER_PATH_PREFIX + checklistInfo.getId() + "/name_catalogue.json", |
|
318 |
"query", |
|
319 |
"*", null); |
|
320 |
|
|
321 |
String searchResponseBody = queryClient.get(namesUri); |
|
322 |
|
|
323 |
buildTaxonIdMapsFromCatalogueServiceResponse(queryList, searchResponseBody); |
|
324 |
|
|
325 |
List<String> taxonIdList = new ArrayList<String>(taxonIdQueryMap.keySet()); |
|
326 |
|
|
327 |
if(taxonIdList.size() > 0) { |
|
328 |
URI taxonUri = queryClient.buildUriFromQueryStringList(taxonIdList, |
|
329 |
SERVER_PATH_PREFIX + checklistInfo.getId() + "/name_catalogue/taxon.json", |
|
330 |
"taxonUuid", |
|
331 |
null); |
|
332 |
String taxonResponseBody = queryClient.get(taxonUri); |
|
333 |
updateQueriesWithResponse(taxonResponseBody, checklistInfo, request); |
|
334 |
} |
|
335 |
} |
|
336 |
} |
|
337 |
|
|
338 |
@Override |
|
339 |
public void resolveScientificNamesLike(TnrMsg tnrMsg) throws DRFChecklistException { |
|
340 |
// delegate to resolveScientificNamesExact, since the like search mode is handled in buildUriFromQueryList |
|
341 |
resolveScientificNamesExact(tnrMsg); |
|
342 |
|
|
343 |
} |
|
344 |
|
|
345 |
@Override |
|
346 |
public void resolveVernacularNamesExact(TnrMsg tnrMsg) throws DRFChecklistException { |
|
347 |
// TODO Auto-generated method stub |
|
348 |
|
|
349 |
} |
|
350 |
|
|
351 |
@Override |
|
352 |
public void resolveVernacularNamesLike(TnrMsg tnrMsg) throws DRFChecklistException { |
|
353 |
// TODO Auto-generated method stub |
|
354 |
|
|
355 |
} |
|
356 |
|
|
357 |
@Override |
|
358 |
public void findByIdentifier(TnrMsg tnrMsg) throws DRFChecklistException { |
|
359 |
|
|
360 |
List<Query> queryList = tnrMsg.getQuery(); |
|
361 |
|
|
362 |
if(queryList.size() > 1){ |
|
363 |
throw new DRFChecklistException("Only single Querys are supported"); |
|
364 |
} |
|
365 |
|
|
366 |
Query.Request request = queryList.get(0).getRequest(); |
|
367 |
Map<String, String> findByIdentifierParameters = new HashMap<String,String>(); |
|
368 |
findByIdentifierParameters.put("includeEntity", "1"); |
|
369 |
|
|
370 |
String identifier = request.getQueryString(); |
|
371 |
|
|
372 |
|
|
373 |
for (ServiceProviderInfo checklistInfo : getServiceProviderInfo().getSubChecklists()) { |
|
374 |
// taxon/findByIdentifier.json?identifier=1&includeEntity=1 |
|
375 |
if(IdentifierUtils.checkLSID(identifier)){ |
|
376 |
URI namesUri = queryClient.buildUriFromQueryList(queryList, |
|
377 |
SERVER_PATH_PREFIX + checklistInfo.getId() + "/authority/metadata.do", |
|
378 |
"lsid", |
|
379 |
null, |
|
380 |
null ); |
|
381 |
|
|
382 |
String responseBody = queryClient.get(namesUri); |
|
383 |
addTaxonToTaxonIdMap(queryList, responseBody); |
|
384 |
} else { |
|
385 |
URI namesUri = queryClient.buildUriFromQueryList(queryList, |
|
386 |
SERVER_PATH_PREFIX + checklistInfo.getId() + "/taxon/findByIdentifier.json", |
|
387 |
"identifier", |
|
388 |
null, // like search for identifiers not supported by this client |
|
389 |
findByIdentifierParameters ); |
|
390 |
|
|
391 |
String responseBody = queryClient.get(namesUri); |
|
392 |
addTaxaToTaxonIdMapFromIdentifierServiceResponse(queryList, responseBody); |
|
393 |
} |
|
394 |
|
|
395 |
List<String> taxonIdList = new ArrayList<String>(taxonIdQueryMap.keySet()); |
|
396 |
|
|
397 |
if(taxonIdList.size() > 0) { |
|
398 |
URI taxonUri = queryClient.buildUriFromQueryStringList(taxonIdList, |
|
399 |
SERVER_PATH_PREFIX + checklistInfo.getId() + "/name_catalogue/taxon.json", |
|
400 |
"taxonUuid", |
|
401 |
null); |
|
402 |
String taxonResponseBody = queryClient.get(taxonUri); |
|
403 |
updateQueriesWithResponse(taxonResponseBody, checklistInfo, request); |
|
404 |
} |
|
405 |
} |
|
406 |
|
|
407 |
} |
|
408 |
|
|
409 |
private void updateQueriesWithResponse(String responseBody, ServiceProviderInfo ci, Query.Request request) throws DRFChecklistException { |
|
410 |
|
|
411 |
if(responseBody == null || responseBody.isEmpty()){ |
|
412 |
return; |
|
413 |
} |
|
414 |
|
|
415 |
JSONArray responseBodyJson = parseResponseBody(responseBody, JSONArray.class); |
|
416 |
|
|
417 |
Iterator<JSONObject> itrTaxonMsgs = responseBodyJson.iterator(); |
|
418 |
|
|
419 |
int i = -1; |
|
420 |
while(itrTaxonMsgs.hasNext()) { |
|
421 |
i++; |
|
422 |
JSONObject taxonInfo = itrTaxonMsgs.next(); |
|
423 |
JSONObject taxonResponse = (JSONObject) taxonInfo.get("response"); |
|
424 |
JSONObject taxon = (JSONObject) taxonResponse.get("taxon"); |
|
425 |
JSONArray relatedTaxa = (JSONArray) taxonResponse.get("relatedTaxa"); |
|
426 |
|
|
427 |
JSONObject taxonRequest = (JSONObject) taxonInfo.get("request"); |
|
428 |
String taxonUuid = (String) taxonRequest.get("taxonUuid"); |
|
429 |
|
|
430 |
if(taxon != null) { |
|
431 |
Response tnrResponse = TnrMsgUtils.tnrResponseFor(ci); |
|
432 |
|
|
433 |
String matchingName = taxonIdMatchStringMap.get(taxonUuid); |
|
434 |
if(matchingName != null){ |
|
435 |
tnrResponse.setMatchingNameString(matchingName); |
|
436 |
tnrResponse.setMatchingNameType(matchingName.equals(taxon.get("name").toString()) ? NameType.TAXON : NameType.SYNONYM); |
|
437 |
} |
|
438 |
|
|
439 |
Taxon accName = generateAccName(taxon); |
|
440 |
tnrResponse.setTaxon(accName); |
|
441 |
|
|
442 |
if(request.isAddSynonymy()){ |
|
443 |
generateSynonyms(relatedTaxa, tnrResponse); |
|
444 |
} |
|
445 |
|
|
446 |
Query query = taxonIdQueryMap.get(taxonUuid); |
|
447 |
if(query != null) { |
|
448 |
query.getResponse().add(tnrResponse); |
|
449 |
} |
|
450 |
} |
|
451 |
} |
|
452 |
} |
|
453 |
|
|
454 |
@Override |
|
455 |
public EnumSet<SearchMode> getSearchModes() { |
|
456 |
return SEARCH_MODES ; |
|
457 |
} |
|
458 |
|
|
459 |
@Override |
|
460 |
public boolean isSupportedIdentifier(String value) { |
|
461 |
// return IdentifierUtils.checkLSID(value) || IdentifierUtils.checkUUID(value); |
|
462 |
return value != null; |
|
463 |
} |
|
464 |
|
|
465 |
|
|
466 |
|
|
467 |
} |
src/main/java/org/bgbm/biovel/drf/checklist/DRFChecklistException.java | ||
---|---|---|
1 |
package org.bgbm.biovel.drf.checklist; |
|
2 |
|
|
3 |
|
|
4 |
public class DRFChecklistException extends Exception { |
|
5 |
|
|
6 |
public DRFChecklistException(Throwable cause) { |
|
7 |
super(cause); |
|
8 |
} |
|
9 |
|
|
10 |
public DRFChecklistException(String message) { |
|
11 |
super(message); |
|
12 |
} |
|
13 |
|
|
14 |
public DRFChecklistException(String message, Throwable cause) { |
|
15 |
super(message , cause); |
|
16 |
} |
|
17 |
|
|
18 |
} |
src/main/java/org/bgbm/biovel/drf/checklist/EEA_BDC_Client.java | ||
---|---|---|
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.lucene.queryParser.QueryParser; |
|
11 |
import org.bgbm.biovel.drf.client.ServiceProviderInfo; |
|
12 |
import org.bgbm.biovel.drf.query.TinkerPopClient; |
|
13 |
import org.bgbm.biovel.drf.store.Neo4jStore; |
|
14 |
import org.bgbm.biovel.drf.store.Store; |
|
15 |
import org.bgbm.biovel.drf.tnr.msg.Classification; |
|
16 |
import org.bgbm.biovel.drf.tnr.msg.NameType; |
|
17 |
import org.bgbm.biovel.drf.tnr.msg.Query; |
|
18 |
import org.bgbm.biovel.drf.tnr.msg.Query.Request; |
|
19 |
import org.bgbm.biovel.drf.tnr.msg.Response; |
|
20 |
import org.bgbm.biovel.drf.tnr.msg.Source; |
|
21 |
import org.bgbm.biovel.drf.tnr.msg.Synonym; |
|
22 |
import org.bgbm.biovel.drf.tnr.msg.Taxon; |
|
23 |
import org.bgbm.biovel.drf.tnr.msg.TaxonBase; |
|
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.Profiler; |
|
28 |
import org.bgbm.biovel.drf.utils.TnrMsgUtils; |
|
29 |
import org.neo4j.graphdb.Relationship; |
|
30 |
|
|
31 |
import com.tinkerpop.blueprints.Graph; |
|
32 |
import com.tinkerpop.blueprints.Vertex; |
|
33 |
import com.tinkerpop.blueprints.impls.neo4j2.Neo4j2Vertex; |
|
34 |
import com.tinkerpop.blueprints.oupls.sail.GraphSail; |
|
35 |
import com.tinkerpop.gremlin.java.GremlinPipeline; |
|
36 |
import com.tinkerpop.pipes.util.FastNoSuchElementException; |
|
37 |
import com.tinkerpop.pipes.util.structures.Table; |
|
38 |
|
|
39 |
public class EEA_BDC_Client extends AggregateChecklistClient<TinkerPopClient> { |
|
40 |
|
|
41 |
/** |
|
42 |
* |
|
43 |
*/ |
|
44 |
public static final String ID = "eea_bdc"; |
|
45 |
public static final String LABEL = "European Environment Agency (EEA) Biodiversity data centre (BDC)"; |
|
46 |
public static final String DOC_URL = "http://semantic.eea.europa.eu/documentation"; |
|
47 |
public static final String COPYRIGHT_URL = "http://www.eea.europa.eu/legal/eea-data-policy"; |
|
48 |
|
|
49 |
private static final String SPECIES_RDF_FILE_URL = "http://localhost/download/species.rdf.gz"; // http://eunis.eea.europa.eu/rdf/species.rdf.gz |
|
50 |
private static final String TAXONOMY_RDF_FILE_URL = "http://localhost/download/taxonomy.rdf.gz"; // http://eunis.eea.europa.eu/rdf/taxonomy.rdf.gz |
|
51 |
private static final String LEGALREFS_RDF_FILE_URL = "http://localhost/download/legalrefs.rdf.gz"; // http://eunis.eea.europa.eu/rdf/legalrefs.rdf.gz |
|
52 |
private static final String REFERENCES_RDF_FILE_URL = "http://localhost/download/references.rdf.gz"; // http://eunis.eea.europa.eu/rdf/references.rdf.gz |
|
53 |
|
|
54 |
private static final boolean REFRESH_TDB = false; |
|
55 |
|
|
56 |
public static final EnumSet<SearchMode> SEARCH_MODES = EnumSet.of( |
|
57 |
SearchMode.scientificNameExact, |
|
58 |
SearchMode.scientificNameLike, |
|
59 |
SearchMode.vernacularNameExact, |
|
60 |
SearchMode.vernacularNameLike, |
|
61 |
SearchMode.findByIdentifier); |
|
62 |
|
|
63 |
public static enum RdfSchema { |
|
64 |
|
|
65 |
/* |
|
66 |
* xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |
|
67 |
xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" |
|
68 |
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" |
|
69 |
xmlns:dcterms="http://purl.org/dc/terms/" |
|
70 |
xmlns:dc="http://purl.org/dc/elements/1.1/" |
|
71 |
xmlns:dwc="http://rs.tdwg.org/dwc/terms/" |
|
72 |
xmlns:owl="http://www.w3.org/2002/07/owl#" |
|
73 |
xmlns="http://eunis.eea.europa.eu/rdf/species-schema.rdf#" |
|
74 |
xmlns:sioc="http://rdfs.org/sioc/ns#" |
|
75 |
xmlns:skos="http://www.w3.org/2004/02/skos/core#" |
|
76 |
xmlns:bibo="http://purl.org/ontology/bibo/" |
|
77 |
xmlns:cc="http://creativecommons.org/ns#" |
|
78 |
xmlns:foaf="http://xmlns.com/foaf/0.1/" |
|
79 |
*/ |
|
80 |
EUNIS_SPECIES("es","http://eunis.eea.europa.eu/rdf/species-schema.rdf#"), |
|
81 |
EUNIS_TAXONOMY("et", "http://eunis.eea.europa.eu/rdf/taxonomies-schema.rdf#"), |
|
82 |
DWC("dwc", "http://rs.tdwg.org/dwc/terms/"), |
|
83 |
RDF("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#"), |
|
84 |
RDFS("rdfs", "http://www.w3.org/2000/01/rdf-schema#"), |
|
85 |
SKOS_CORE("scos_core", "http://www.w3.org/2004/02/skos/core#"), |
|
86 |
DC("dc", "http://purl.org/dc/terms/source"), |
|
87 |
DCTERMS("dcterms", "http://purl.org/dc/terms/"); |
|
88 |
|
|
89 |
private String schemaUri; |
|
90 |
private String abbreviation; |
|
91 |
RdfSchema(String abbreviation, String schemaUri) { |
|
92 |
this.abbreviation = abbreviation; |
|
93 |
this.schemaUri = schemaUri; |
|
94 |
} |
|
95 |
|
|
96 |
public String schemaUri() { |
|
97 |
|
|
98 |
return schemaUri; |
|
99 |
} |
|
100 |
|
|
101 |
public String abbreviation() { |
|
102 |
|
|
103 |
return abbreviation; |
|
104 |
} |
|
105 |
|
|
106 |
public String property(String name) { |
|
107 |
return schemaUri + name; |
|
108 |
} |
|
109 |
|
|
110 |
} |
|
111 |
|
|
112 |
public enum SubCheckListId { |
|
113 |
|
|
114 |
eunis, natura_2000; |
|
115 |
} |
|
116 |
|
|
117 |
private enum RankLevel{ |
|
118 |
|
|
119 |
Kingdom, Phylum, Clazz, Order, Family, Genus; |
|
120 |
} |
|
121 |
|
|
122 |
public EEA_BDC_Client() { |
|
123 |
|
|
124 |
super(); |
|
125 |
} |
|
126 |
|
|
127 |
public EEA_BDC_Client(String checklistInfoJson) throws DRFChecklistException { |
|
128 |
|
|
129 |
super(checklistInfoJson); |
|
130 |
} |
|
131 |
|
|
132 |
@Override |
|
133 |
public void initQueryClient() { |
|
134 |
|
|
135 |
Neo4jStore neo4jStore; |
|
136 |
try { |
|
137 |
neo4jStore = new Neo4jStore(); |
|
138 |
} catch (Exception e1) { |
|
139 |
throw new RuntimeException("Creation of Neo4jStore failed", e1); |
|
140 |
} |
|
141 |
if(REFRESH_TDB) { |
|
142 |
updateStore(neo4jStore); |
|
143 |
} |
|
144 |
queryClient = new TinkerPopClient(neo4jStore); |
|
145 |
} |
|
146 |
|
|
147 |
/** |
|
148 |
* @param neo4jStore |
|
149 |
*/ |
|
150 |
private void updateStore(Store neo4jStore) { |
|
151 |
try { |
|
152 |
neo4jStore.loadIntoStore( |
|
153 |
// SPECIES_RDF_FILE_URL, |
|
154 |
TAXONOMY_RDF_FILE_URL |
|
155 |
// LEGALREFS_RDF_FILE_URL, |
|
156 |
// REFERENCES_RDF_FILE_URL |
|
157 |
); |
|
158 |
} catch (Exception e) { |
|
159 |
throw new RuntimeException("Loading " |
|
160 |
+ SPECIES_RDF_FILE_URL + ", " |
|
161 |
+ TAXONOMY_RDF_FILE_URL + ", " |
|
162 |
+ LEGALREFS_RDF_FILE_URL + ", " |
|
163 |
+ REFERENCES_RDF_FILE_URL + |
|
164 |
" into Neo4jStore failed", e); |
|
165 |
} |
|
166 |
} |
|
167 |
|
|
168 |
@Override |
|
169 |
public ServiceProviderInfo buildServiceProviderInfo() { |
|
170 |
|
|
171 |
ServiceProviderInfo checklistInfo = new ServiceProviderInfo(ID, LABEL, DOC_URL, COPYRIGHT_URL, getSearchModes()); |
|
172 |
checklistInfo.addSubChecklist(new ServiceProviderInfo(SubCheckListId.eunis.name(), "EUNIS", |
|
173 |
"http://www.eea.europa.eu/themes/biodiversity/eunis/eunis-db#tab-metadata", |
|
174 |
"http://www.eea.europa.eu/legal/copyright", SEARCH_MODES)); |
|
175 |
return checklistInfo; |
|
176 |
} |
|
177 |
|
|
178 |
|
|
179 |
/** |
|
180 |
* @param queryString |
|
181 |
* @throws DRFChecklistException |
|
182 |
*/ |
|
183 |
private void addPrexfixes(StringBuilder queryString) throws DRFChecklistException { |
|
184 |
|
|
185 |
for(RdfSchema schema : RdfSchema.values()) { |
|
186 |
queryString.append(String.format("PREFIX %s: <%s>\n", schema.abbreviation(), schema.schemaUri())); |
|
187 |
} |
|
188 |
} |
|
189 |
|
|
190 |
/** |
|
191 |
* @param checklistInfo |
|
192 |
* @return |
|
193 |
* @throws DRFChecklistException |
|
194 |
*/ |
|
195 |
private StringBuilder prepareQueryString() throws DRFChecklistException { |
|
196 |
|
|
197 |
StringBuilder queryString = new StringBuilder(); |
|
198 |
addPrexfixes(queryString); |
|
199 |
return queryString; |
|
200 |
} |
|
201 |
|
|
202 |
private Taxon createTaxon(Vertex v) { |
|
203 |
|
|
204 |
Taxon taxon = new Taxon(); |
|
205 |
|
|
206 |
TaxonName taxonName = createTaxonName(v); |
|
207 |
|
|
208 |
// Taxon |
|
209 |
taxon.setTaxonName(taxonName); |
|
210 |
taxon.setIdentifier(v.getId().toString()); |
|
211 |
taxon.setAccordingTo(queryClient.relatedVertexValue(v, RdfSchema.DWC, "nameAccordingToID")); |
|
212 |
URI typeUri = queryClient.vertexURI(v, RdfSchema.RDF, "type"); |
|
213 |
taxon.setTaxonomicStatus(typeUri.getFragment()); |
|
214 |
|
|
215 |
createSources(v, taxon); |
|
216 |
|
|
217 |
// classification |
|
218 |
Classification c = null; |
|
219 |
Vertex parentV= null; |
|
220 |
try { |
|
221 |
parentV = queryClient.relatedVertex(v, RdfSchema.EUNIS_SPECIES, "taxonomy"); |
|
222 |
} catch (Exception e) { |
|
223 |
logger.error("No taxonomy information for " + v.toString()); |
|
224 |
} |
|
225 |
|
|
226 |
while (parentV != null) { |
|
227 |
logger.debug("parent taxon: " + parentV.toString()); |
|
228 |
String level = queryClient.relatedVertexValue(parentV, RdfSchema.EUNIS_TAXONOMY, "level"); |
|
229 |
String parentTaxonName = queryClient.relatedVertexValue(parentV, RdfSchema.EUNIS_TAXONOMY, "name"); |
|
230 |
|
|
231 |
RankLevel rankLevel = null; |
|
232 |
try { |
|
233 |
rankLevel = RankLevel.valueOf(level); |
|
234 |
} catch (Exception e) { |
|
235 |
// IGNORE |
|
236 |
} |
|
237 |
if(rankLevel != null) { |
|
238 |
if(c == null) { |
|
239 |
c = new Classification(); |
|
240 |
} |
|
241 |
switch(rankLevel) { |
|
242 |
case Clazz: |
|
243 |
c.setClazz(parentTaxonName); |
|
244 |
break; |
|
245 |
case Family: |
|
246 |
c.setFamily(parentTaxonName); |
|
247 |
break; |
|
248 |
case Genus: |
|
249 |
c.setGenus(parentTaxonName); |
|
250 |
break; |
|
251 |
case Kingdom: |
|
252 |
c.setKingdom(parentTaxonName); |
|
253 |
break; |
|
254 |
case Order: |
|
255 |
c.setOrder(parentTaxonName); |
|
256 |
break; |
|
257 |
case Phylum: |
|
258 |
c.setPhylum(parentTaxonName); |
|
259 |
break; |
|
260 |
default: |
|
261 |
break; |
|
262 |
} |
|
263 |
} |
|
264 |
Vertex lastParentV = parentV; |
|
265 |
parentV = queryClient.relatedVertex(parentV, RdfSchema.EUNIS_TAXONOMY, "parent"); |
|
266 |
if(lastParentV.equals(parentV)) { |
|
267 |
// avoid endless looping when data is not correct |
|
268 |
break; |
|
269 |
} |
|
270 |
} |
|
271 |
if(c != null) { |
|
272 |
taxon.setClassification(c); |
|
273 |
} |
|
274 |
return taxon; |
|
275 |
} |
|
276 |
|
|
277 |
/** |
|
278 |
* @param model |
|
279 |
* @param taxonR |
|
280 |
* @param taxonBase |
|
281 |
*/ |
|
282 |
private void createSources(Vertex v, TaxonBase taxonBase) { |
|
283 |
|
|
284 |
// Sources are source references, re there others like data bases? |
|
285 |
|
|
286 |
GremlinPipeline<Graph, Vertex> taxonPipe = new GremlinPipeline<Graph, Vertex>(v); |
|
287 |
|
|
288 |
try { |
|
289 |
List<Vertex> titleVs = taxonPipe |
|
290 |
.outE(RdfSchema.EUNIS_SPECIES.property("hasLegalReference")).inV() |
|
291 |
.outE(RdfSchema.DCTERMS.property("source")).inV().dedup() |
|
292 |
.outE(RdfSchema.DCTERMS.property("title")).inV() |
|
293 |
.toList(); |
|
294 |
for(Vertex tv : titleVs) { |
|
295 |
Source source = new Source(); |
|
296 |
logger.error(tv.toString()); |
|
297 |
source.setName(tv.getProperty(GraphSail.VALUE).toString()); |
|
298 |
taxonBase.getSources().add(source); |
|
299 |
} |
|
300 |
} catch (FastNoSuchElementException e) { |
|
301 |
logger.debug("No sources found"); |
|
302 |
} |
|
303 |
} |
|
304 |
|
|
305 |
/** |
|
306 |
* @param taxonR |
|
307 |
* @return |
|
308 |
*/ |
|
309 |
private TaxonName createTaxonName(Vertex v) { |
|
310 |
|
|
311 |
TaxonName taxonName = new TaxonName(); |
|
312 |
// TaxonName |
|
313 |
taxonName.setFullName(queryClient.relatedVertexValue(v, RdfSchema.RDFS, "label")); |
|
314 |
taxonName.setCanonicalName(queryClient.relatedVertexValue(v, RdfSchema.EUNIS_SPECIES, "binomialName")); |
|
315 |
taxonName.setRank(queryClient.relatedVertexValue(v, RdfSchema.EUNIS_SPECIES, "taxonomicRank")); |
|
316 |
return taxonName; |
|
317 |
} |
|
318 |
|
|
319 |
|
|
320 |
private void createSynonyms(Vertex taxonV, Response tnrResponse) { |
|
321 |
|
|
322 |
|
|
323 |
GremlinPipeline<Graph, Vertex> taxonPipe = new GremlinPipeline<Graph, Vertex>(taxonV); |
|
324 |
|
|
325 |
try { |
|
326 |
List<Vertex> synonymVs = taxonPipe |
|
327 |
.inE(RdfSchema.EUNIS_SPECIES.property("eunisPrimaryName")).outV().dedup() |
|
328 |
.toList(); |
|
329 |
for(Vertex synonymV : synonymVs) { |
|
330 |
String typeUri = queryClient.relatedVertexValue(synonymV, RdfSchema.RDF, "type"); |
|
331 |
String status = null; |
|
332 |
try { |
|
333 |
status = URI.create(typeUri).getFragment(); |
|
334 |
} catch (Exception e) { |
|
335 |
|
|
336 |
} |
|
337 |
|
|
338 |
if (status != null && status.equals("SpeciesSynonym")) { |
|
339 |
|
|
340 |
Synonym synonym = new Synonym(); |
|
341 |
|
|
342 |
TaxonName taxonName = createTaxonName(synonymV); |
|
343 |
synonym.setTaxonomicStatus(status); |
|
344 |
synonym.setTaxonName(taxonName); |
|
345 |
synonym.setAccordingTo(queryClient.relatedVertexValue(synonymV, RdfSchema.DWC, "nameAccordingToID")); |
|
346 |
|
|
347 |
createSources(synonymV, synonym); |
|
348 |
|
|
349 |
tnrResponse.getSynonym().add(synonym); |
|
350 |
} |
|
351 |
} |
|
352 |
} catch (FastNoSuchElementException e) { |
|
353 |
logger.debug("No sources found"); |
|
354 |
} |
|
355 |
|
|
356 |
} |
|
357 |
|
|
358 |
@Override |
|
359 |
public void resolveScientificNamesExact(TnrMsg tnrMsg) throws DRFChecklistException { |
|
360 |
|
|
361 |
for (ServiceProviderInfo checklistInfo : getServiceProviderInfo().getSubChecklists()) { |
|
362 |
|
|
363 |
// FIXME query specific subchecklist |
|
364 |
|
|
365 |
// selecting one request as representative, only |
|
366 |
// the search mode and addSynonmy flag are important |
|
367 |
// for the further usage of the request object |
|
368 |
Query query = singleQueryFrom(tnrMsg); |
|
369 |
|
|
370 |
String queryString = query.getRequest().getQueryString(); |
|
371 |
logger.debug("original queryString: "+ queryString); |
|
372 |
queryString = QueryParser.escape(queryString); |
|
373 |
queryString = queryString.replace(" ", "\\ "); |
|
374 |
if(query.getRequest().getSearchMode().equals(SearchMode.scientificNameLike.name())) { |
|
375 |
queryString += "*"; |
|
376 |
} |
|
377 |
logger.debug("prepared queryString: "+ queryString); |
|
378 |
|
|
379 |
GremlinPipeline<Graph, Vertex> pipe = null; |
|
380 |
|
|
381 |
Profiler profiler = Profiler.newCpuProfiler(false); |
|
382 |
|
|
383 |
logger.debug("Neo4jINDEX"); |
|
384 |
|
|
385 |
ArrayList<Vertex> hitVs = queryClient.vertexIndexQuery("value:" + queryString); |
|
386 |
pipe = new GremlinPipeline<Graph, Vertex>(hitVs); |
|
387 |
|
|
388 |
List<Vertex> vertices = new ArrayList<Vertex>(); |
|
389 |
pipe.in(RdfSchema.EUNIS_SPECIES.property("binomialName")).fill(vertices); |
|
390 |
|
|
391 |
updateQueriesWithResponse(vertices, null, null, checklistInfo, query); |
|
392 |
profiler.end(System.err); |
|
393 |
} |
|
394 |
} |
|
395 |
|
|
396 |
@Override |
|
397 |
public void resolveScientificNamesLike(TnrMsg tnrMsg) throws DRFChecklistException { |
|
398 |
// delegate to resolveScientificNamesExact, |
|
399 |
resolveScientificNamesExact(tnrMsg); |
|
400 |
|
|
401 |
} |
|
402 |
|
|
403 |
@Override |
|
404 |
public void resolveVernacularNamesExact(TnrMsg tnrMsg) throws DRFChecklistException { |
|
405 |
List<Query> queryList = tnrMsg.getQuery(); |
|
406 |
|
|
407 |
for (ServiceProviderInfo checklistInfo : getServiceProviderInfo().getSubChecklists()) { |
|
408 |
|
|
409 |
// FIXME query specific subchecklist |
|
410 |
|
|
411 |
// selecting one request as representative, only |
|
412 |
// the search mode and addSynonmy flag are important |
|
413 |
// for the further usage of the request object |
|
414 |
Query query = singleQueryFrom(tnrMsg); |
|
415 |
|
|
416 |
String queryString = query.getRequest().getQueryString(); |
|
417 |
logger.debug("original queryString: "+ queryString); |
|
418 |
queryString = QueryParser.escape(queryString); |
|
419 |
queryString = queryString.replace(" ", "\\ "); |
|
420 |
if(query.getRequest().getSearchMode().equals(SearchMode.vernacularNameLike.name())) { |
|
421 |
queryString = "*" + queryString + "*"; |
|
422 |
} |
|
423 |
|
|
424 |
logger.debug("prepared queryString: "+ queryString); |
|
425 |
|
|
426 |
GremlinPipeline<Graph, Vertex> pipe = null; |
|
427 |
|
|
428 |
Profiler profiler = Profiler.newCpuProfiler(false); |
|
429 |
|
|
430 |
// by using the Neo4j index directly it is possible to |
|
431 |
// take full advantage of the underlying Lucene search engine |
|
432 |
ArrayList<Vertex> hitVs = queryClient.vertexIndexQuery("value:" + queryString); |
|
433 |
|
|
434 |
// List<String> matchingNames = new ArrayList<String>(hitVs.size()); |
|
435 |
// for(Vertex v : hitVs) { |
|
436 |
// String matchValue = v.getProperty(GraphSail.VALUE).toString(); |
|
437 |
// matchingNames.add(matchValue); |
|
438 |
// logger.debug("matchingName " + matchValue); |
|
439 |
// } |
|
440 |
|
|
441 |
List<Vertex> vertices = new ArrayList<Vertex>(); |
|
442 |
pipe = new GremlinPipeline<Graph, Vertex>(hitVs); |
|
443 |
Table table = new Table(); |
|
444 |
pipe.as("match").in(RdfSchema.DWC.property("vernacularName")).as("taxon").table(table).iterate(); |
|
445 |
|
|
446 |
updateQueriesWithResponse( |
|
447 |
table.getColumn("taxon"), table.getColumn("match"), |
|
448 |
NameType.VERNACULAR_NAME, checklistInfo, query); |
|
449 |
profiler.end(System.err); |
|
450 |
} |
|
451 |
} |
|
452 |
|
|
453 |
@Override |
|
454 |
public void resolveVernacularNamesLike(TnrMsg tnrMsg) throws DRFChecklistException { |
|
455 |
resolveVernacularNamesExact(tnrMsg); |
|
456 |
} |
|
457 |
|
|
458 |
@Override |
|
459 |
public void findByIdentifier(TnrMsg tnrMsg) throws DRFChecklistException { |
|
460 |
|
|
461 |
for (ServiceProviderInfo checklistInfo : getServiceProviderInfo().getSubChecklists()) { |
|
462 |
|
|
463 |
// FIXME query specific subchecklist |
|
464 |
Query query = singleQueryFrom(tnrMsg); |
|
465 |
String queryString = query.getRequest().getQueryString(); |
|
466 |
|
|
467 |
// by using the Neo4j index directly it is possible to |
|
468 |
// take full advantage of the underlying Lucene search engine |
|
469 |
queryString = QueryParser.escape(queryString); |
|
470 |
ArrayList<Vertex> hitVs = queryClient.vertexIndexQuery("value:" + queryString); |
|
471 |
if(hitVs.size() > 0) { |
|
472 |
Response response = tnrResponseFromResource(hitVs.get(0), query.getRequest(), null, null); |
|
473 |
query.getResponse().add(response); |
|
474 |
} else if(hitVs.size() > 1) { |
|
475 |
throw new DRFChecklistException("More than one node with the id '" + queryString + "' found"); |
|
476 |
} |
|
477 |
} |
|
478 |
} |
|
479 |
|
|
480 |
private void updateQueriesWithResponse(List<Vertex> taxonNodes, List<Vertex> matchNodes, NameType matchType, ServiceProviderInfo ci, Query query){ |
|
481 |
|
|
482 |
if (taxonNodes == null) { |
|
483 |
return; |
|
484 |
} |
|
485 |
|
|
486 |
logger.debug("matching taxon nodes:"); |
|
487 |
int i = -1; |
|
488 |
for (Vertex v : taxonNodes) { |
|
489 |
i++; |
|
490 |
logger.debug(" " + v.toString()); |
|
491 |
printPropertyKeys(v, System.err); |
|
492 |
if(v.getProperty("kind").equals("url")) { |
|
493 |
logger.error("vertex of type 'url' expected, but was " + v.getProperty("type").equals("url")); |
|
494 |
continue; |
|
495 |
} |
|
496 |
Vertex matchNode = null; |
|
497 |
if(matchNodes != null) { |
|
498 |
matchNode = matchNodes.get(i); |
|
499 |
} |
|
500 |
Response tnrResponse = tnrResponseFromResource(v, query.getRequest(), matchNode, matchType); |
|
501 |
if(tnrResponse != null) { |
|
502 |
query.getResponse().add(tnrResponse); |
|
503 |
} |
|
504 |
} |
|
505 |
} |
|
506 |
|
|
507 |
/** |
|
508 |
* @param model |
|
509 |
* @param taxonR |
|
510 |
* @param request |
|
511 |
* @param matchType |
|
512 |
* @param matchNode |
|
513 |
* @return |
|
514 |
*/ |
|
515 |
private Response tnrResponseFromResource(Vertex taxonV, Request request, Vertex matchNode, NameType matchType) { |
|
516 |
|
|
517 |
Response tnrResponse = TnrMsgUtils.tnrResponseFor(getServiceProviderInfo()); |
|
518 |
|
|
519 |
GremlinPipeline<Graph, Vertex> pipe = new GremlinPipeline<Graph, Vertex>(taxonV); |
|
520 |
|
|
521 |
String validName = queryClient.relatedVertexValue(taxonV, RdfSchema.EUNIS_SPECIES, "validName"); |
|
522 |
|
|
523 |
boolean isAccepted = validName != null && validName.equals("true"); |
|
524 |
|
|
525 |
logger.debug("processing " + (isAccepted ? "accepted taxon" : "synonym or other") + " " + taxonV.getId()); |
|
526 |
|
|
527 |
// |
|
528 |
if(matchNode != null) { |
|
529 |
String matchingName = matchNode.getProperty(GraphSail.VALUE).toString(); |
|
530 |
tnrResponse.setMatchingNameString(matchingName); |
|
531 |
tnrResponse.setMatchingNameType(matchType); |
|
532 |
} |
|
533 |
|
|
534 |
// case when accepted name |
|
535 |
if(isAccepted) { |
|
536 |
Taxon taxon = createTaxon(taxonV); |
|
537 |
tnrResponse.setTaxon(taxon); |
|
538 |
if(matchNode == null) { |
|
539 |
tnrResponse.setMatchingNameType(NameType.TAXON); |
|
540 |
String matchingName = taxon.getTaxonName().getCanonicalName(); |
|
541 |
tnrResponse.setMatchingNameString(matchingName); |
|
542 |
} |
|
543 |
|
|
544 |
} |
|
545 |
else { |
|
546 |
// case when synonym |
|
547 |
Vertex synonymV = taxonV; |
|
548 |
taxonV = null; |
|
549 |
try { |
|
550 |
taxonV = queryClient.relatedVertex(synonymV, RdfSchema.EUNIS_SPECIES, "eunisPrimaryName"); |
|
551 |
} catch(Exception e) { |
|
552 |
logger.error("No accepted taxon found for " + synonymV.toString() + " (" + synonymV.getProperty(GraphSail.VALUE) + ")"); |
|
553 |
} |
|
554 |
|
|
555 |
if(taxonV != null) { |
|
556 |
Taxon taxon = createTaxon(taxonV); |
|
557 |
tnrResponse.setTaxon(taxon); |
|
558 |
} else { |
|
559 |
} |
|
560 |
if(matchNode == null) { |
|
561 |
tnrResponse.setMatchingNameType(NameType.SYNONYM); |
|
562 |
String matchingName = queryClient.relatedVertexValue(synonymV, RdfSchema.EUNIS_SPECIES, "binomialName"); |
|
563 |
tnrResponse.setMatchingNameString(matchingName); |
|
564 |
} |
|
565 |
} |
|
566 |
|
|
567 |
if(request.isAddSynonymy()) { |
|
568 |
createSynonyms(taxonV, tnrResponse); |
|
569 |
} |
|
570 |
|
|
571 |
logger.debug("processing " + (isAccepted ? "accepted taxon" : "synonym or other") + " " + taxonV.getId() + " DONE"); |
|
572 |
return tnrResponse; |
|
573 |
} |
|
574 |
|
|
575 |
/** |
|
576 |
* @param vertex |
|
577 |
*/ |
|
578 |
private void printEdges(Neo4j2Vertex vertex) { |
|
579 |
Iterable<Relationship> rels = vertex.getRawVertex().getRelationships(); |
|
580 |
Iterator<Relationship> iterator = rels.iterator(); |
|
581 |
if(iterator.hasNext()) { |
|
582 |
Relationship rel = iterator.next(); |
|
583 |
System.err.println(rel.toString() + ": " + rel.getStartNode().toString() + "-[" + rel.getType() + "]-" + rel.getEndNode().toString()); |
|
584 |
} |
|
585 |
} |
|
586 |
|
|
587 |
private void printPropertyKeys(Vertex v, PrintStream ps) { |
|
588 |
StringBuilder out = new StringBuilder(); |
|
589 |
out.append(v.toString()); |
|
590 |
for(String key : v.getPropertyKeys()) { |
|
591 |
out.append(key).append(": ").append(v.getProperty(key)).append(" "); |
|
592 |
} |
|
593 |
ps.println(out.toString()); |
|
594 |
} |
|
595 |
|
|
596 |
@Override |
|
597 |
public EnumSet<SearchMode> getSearchModes() { |
|
598 |
return SEARCH_MODES; |
|
599 |
} |
|
600 |
|
|
601 |
@Override |
|
602 |
public boolean isSupportedIdentifier(String value) { |
|
603 |
return IdentifierUtils.checkURI(value); |
|
604 |
} |
|
605 |
|
|
606 |
} |
src/main/java/org/bgbm/biovel/drf/checklist/GBIFBackboneClient.java | ||
---|---|---|
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); |
Also available in: Unified diff
renaming project and packages to cybertaxonomy.org/utis/