1
|
/**
|
2
|
* Copyright (C) 2007 EDIT
|
3
|
* European Distributed Institute of Taxonomy
|
4
|
* http://www.e-taxonomy.eu
|
5
|
*
|
6
|
* The contents of this file are subject to the Mozilla Public License Version 1.1
|
7
|
* See LICENSE.TXT at the top of this package for the full license terms.
|
8
|
*/
|
9
|
|
10
|
package eu.etaxonomy.cdm.io.berlinModel.in;
|
11
|
|
12
|
import java.sql.ResultSet;
|
13
|
import java.sql.SQLException;
|
14
|
import java.util.ArrayList;
|
15
|
import java.util.HashMap;
|
16
|
import java.util.HashSet;
|
17
|
import java.util.List;
|
18
|
import java.util.Map;
|
19
|
import java.util.Set;
|
20
|
import java.util.SortedSet;
|
21
|
import java.util.TreeSet;
|
22
|
import java.util.UUID;
|
23
|
|
24
|
import org.apache.commons.lang.StringUtils;
|
25
|
import org.apache.log4j.Logger;
|
26
|
import org.springframework.stereotype.Component;
|
27
|
|
28
|
import eu.etaxonomy.cdm.common.CdmUtils;
|
29
|
import eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer;
|
30
|
import eu.etaxonomy.cdm.io.berlinModel.in.validation.BerlinModelCommonNamesImportValidator;
|
31
|
import eu.etaxonomy.cdm.io.common.IOValidator;
|
32
|
import eu.etaxonomy.cdm.io.common.ResultSetPartitioner;
|
33
|
import eu.etaxonomy.cdm.io.common.Source;
|
34
|
import eu.etaxonomy.cdm.io.common.TdwgAreaProvider;
|
35
|
import eu.etaxonomy.cdm.model.common.CdmBase;
|
36
|
import eu.etaxonomy.cdm.model.common.Extension;
|
37
|
import eu.etaxonomy.cdm.model.common.ExtensionType;
|
38
|
import eu.etaxonomy.cdm.model.common.Language;
|
39
|
import eu.etaxonomy.cdm.model.common.Marker;
|
40
|
import eu.etaxonomy.cdm.model.common.MarkerType;
|
41
|
import eu.etaxonomy.cdm.model.common.Representation;
|
42
|
import eu.etaxonomy.cdm.model.common.TermType;
|
43
|
import eu.etaxonomy.cdm.model.common.TermVocabulary;
|
44
|
import eu.etaxonomy.cdm.model.description.CommonTaxonName;
|
45
|
import eu.etaxonomy.cdm.model.description.DescriptionElementSource;
|
46
|
import eu.etaxonomy.cdm.model.description.TaxonDescription;
|
47
|
import eu.etaxonomy.cdm.model.location.Country;
|
48
|
import eu.etaxonomy.cdm.model.location.NamedArea;
|
49
|
import eu.etaxonomy.cdm.model.name.TaxonName;
|
50
|
import eu.etaxonomy.cdm.model.reference.Reference;
|
51
|
import eu.etaxonomy.cdm.model.taxon.Taxon;
|
52
|
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
|
53
|
|
54
|
/**
|
55
|
*
|
56
|
* @author a.mueller
|
57
|
* @since 20.03.2008
|
58
|
*/
|
59
|
@Component
|
60
|
public class BerlinModelCommonNamesImport extends BerlinModelImportBase {
|
61
|
private static final long serialVersionUID = -8921948187177864321L;
|
62
|
|
63
|
private static final Logger logger = Logger.getLogger(BerlinModelCommonNamesImport.class);
|
64
|
|
65
|
public static final UUID REFERENCE_LANGUAGE_ISO639_2_UUID = UUID.fromString("40c4f8dd-3d9c-44a4-b77a-76e137a89a5f");
|
66
|
public static final UUID REFERENCE_LANGUAGE_STRING_UUID = UUID.fromString("2a1b678f-c27d-48c1-b43e-98fd0d426305");
|
67
|
public static final UUID COMMONNAME_STATUS_RECOMMENDED_UUID = UUID.fromString("e3f7b80a-1286-458d-812c-5e818f731968");
|
68
|
public static final UUID COMMONNAME_STATUS_SYNONYM_UUID = UUID.fromString("169b2d97-a706-49de-b28b-c67f0ee6764b");
|
69
|
|
70
|
public static final String NAMESPACE = "common name";
|
71
|
|
72
|
|
73
|
private static final String pluralString = "common names";
|
74
|
private static final String dbTableName = "emCommonName";
|
75
|
|
76
|
|
77
|
//map that stores the regions (named areas) and makes them accessible via the regionFk
|
78
|
private Map<String, NamedArea> regionMap = new HashMap<>();
|
79
|
|
80
|
public BerlinModelCommonNamesImport(){
|
81
|
super(dbTableName, pluralString);
|
82
|
}
|
83
|
|
84
|
@Override
|
85
|
protected String getIdQuery(BerlinModelImportState state) {
|
86
|
String result = " SELECT CommonNameId FROM emCommonName WHERE (1=1) ";
|
87
|
if (isNotBlank(state.getConfig().getCommonNameFilter())){
|
88
|
result += " AND " + state.getConfig().getCommonNameFilter();
|
89
|
}
|
90
|
result += " ORDER BY CommonNameId ";
|
91
|
|
92
|
return result;
|
93
|
}
|
94
|
|
95
|
@Override
|
96
|
protected String getRecordQuery(BerlinModelImportConfigurator config) {
|
97
|
String recordQuery = "";
|
98
|
recordQuery =
|
99
|
" SELECT rel.RelPTaxonId, rel.RelQualifierFk, acc.RIdentifier accTaxonId, factTaxon.RIdentifier factTaxonId, accName.NameId, f.FactId, " +
|
100
|
" cn.CommonNameId, cn.CommonName, tax.RIdentifier AS taxonId, cn.PTNameFk, cn.RefFk AS refId, cn.Status, cn.RegionFks, cn.MisNameRefFk, " +
|
101
|
" cn.NameInSourceFk, cn.Created_When, cn.Updated_When, cn.Created_Who, cn.Updated_Who, cn.Note AS Notes, languageCommonName.Language, " +
|
102
|
" languageCommonName.LanguageOriginal, languageCommonName.ISO639_1, languageCommonName.ISO639_2, " +
|
103
|
" emLanguageReference.RefFk AS languageRefRefFk, emLanguageReference.ReferenceShort, emLanguageReference.ReferenceLong, " +
|
104
|
" emLanguageReference.LanguageFk, languageReferenceLanguage.Language AS refLanguage, languageReferenceLanguage.ISO639_2 AS refLanguageIso639_2, "+
|
105
|
" misappliedTaxon.RIdentifier AS misappliedTaxonId " +
|
106
|
" FROM PTaxon AS misappliedTaxon RIGHT OUTER JOIN " +
|
107
|
" emLanguage AS languageReferenceLanguage RIGHT OUTER JOIN " +
|
108
|
" emLanguageReference ON languageReferenceLanguage.LanguageId = emLanguageReference.LanguageFk RIGHT OUTER JOIN " +
|
109
|
" emCommonName AS cn INNER JOIN " +
|
110
|
" PTaxon AS tax ON cn.PTNameFk = tax.PTNameFk AND cn.PTRefFk = tax.PTRefFk ON " +
|
111
|
" emLanguageReference.ReferenceId = cn.LanguageRefFk LEFT OUTER JOIN " +
|
112
|
" emLanguage AS languageCommonName ON cn.LanguageFk = languageCommonName.LanguageId ON misappliedTaxon.PTNameFk = cn.NameInSourceFk AND " +
|
113
|
" misappliedTaxon.PTRefFk = cn.MisNameRefFk " +
|
114
|
|
115
|
" LEFT OUTER JOIN Fact f ON cn.CommonNameId = f.ExtensionFk " +
|
116
|
" LEFT OUTER JOIN PTaxon factTaxon ON factTaxon.PTNameFk = f.PTNameFk AND factTaxon.PTRefFk = f.PTRefFk " +
|
117
|
" LEFT OUTER JOIN RelPTaxon rel ON rel.PTNameFk1 = tax.PTNameFk AND rel.PTRefFk1 = tax.PTRefFk AND rel.RelQualifierFk IN (2,6,7) " +
|
118
|
" LEFT OUTER JOIN PTaxon acc ON rel.PTNameFk2 = acc.PTNameFk AND rel.PTRefFk2 = acc.PTRefFk " +
|
119
|
" LEFT OUTER JOIN Name accName ON accName.NameId = acc.PTNameFk " +
|
120
|
" WHERE cn.CommonNameId IN (" + ID_LIST_TOKEN + ") " +
|
121
|
" ORDER BY cn.CommonNameId ";
|
122
|
|
123
|
return recordQuery;
|
124
|
}
|
125
|
|
126
|
@Override
|
127
|
protected void doInvoke(BerlinModelImportState state) {
|
128
|
try {
|
129
|
makeRegions(state);
|
130
|
} catch (Exception e) {
|
131
|
logger.error("Error when creating common name regions:" + e.getMessage());
|
132
|
e.printStackTrace();
|
133
|
state.setUnsuccessfull();
|
134
|
}
|
135
|
super.doInvoke(state);
|
136
|
return;
|
137
|
}
|
138
|
|
139
|
/**
|
140
|
* @param state
|
141
|
*
|
142
|
*/
|
143
|
private void makeRegions(BerlinModelImportState state) {
|
144
|
try {
|
145
|
SortedSet<Integer> regionFks = new TreeSet<>();
|
146
|
Source source = state.getConfig().getSource();
|
147
|
|
148
|
//fill set with all regionFk from emCommonName.regionFks
|
149
|
getRegionFks(state, regionFks, source);
|
150
|
//concat filter string
|
151
|
String sqlWhere = getSqlWhere(regionFks);
|
152
|
|
153
|
//get E+M - TDWG Mapping
|
154
|
Map<String, String> emTdwgMap = getEmTdwgMap(source);
|
155
|
//fill regionMap
|
156
|
fillRegionMap(state, sqlWhere, emTdwgMap);
|
157
|
|
158
|
return;
|
159
|
} catch (NumberFormatException e) {
|
160
|
e.printStackTrace();
|
161
|
state.setUnsuccessfull();
|
162
|
return;
|
163
|
} catch (SQLException e) {
|
164
|
e.printStackTrace();
|
165
|
state.setUnsuccessfull();
|
166
|
return;
|
167
|
}
|
168
|
}
|
169
|
|
170
|
|
171
|
@Override
|
172
|
public boolean doPartition(ResultSetPartitioner partitioner, BerlinModelImportState state) {
|
173
|
boolean success = true ;
|
174
|
|
175
|
Set<TaxonBase> taxaToSave = new HashSet<>();
|
176
|
@SuppressWarnings("unchecked")
|
177
|
Map<String, Taxon> taxonMap = partitioner.getObjectMap(BerlinModelTaxonImport.NAMESPACE);
|
178
|
@SuppressWarnings("unchecked")
|
179
|
Map<String, TaxonName> taxonNameMap = partitioner.getObjectMap(BerlinModelTaxonNameImport.NAMESPACE);
|
180
|
@SuppressWarnings("unchecked")
|
181
|
Map<String, Reference> refMap = partitioner.getObjectMap(BerlinModelReferenceImport.REFERENCE_NAMESPACE);
|
182
|
|
183
|
Map<String, Language> iso6392Map = new HashMap<>();
|
184
|
|
185
|
// logger.warn("MisappliedNameRefFk not yet implemented for Common Names");
|
186
|
|
187
|
ResultSet rs = partitioner.getResultSet();
|
188
|
Integer lastCommonNameId = null;
|
189
|
try{
|
190
|
while (rs.next()){
|
191
|
|
192
|
//create TaxonName element
|
193
|
Integer commonNameId = rs.getInt("CommonNameId");
|
194
|
int taxonId = rs.getInt("taxonId");
|
195
|
Integer factTaxonId = nullSafeInt(rs, "factTaxonId");
|
196
|
Integer accTaxonId = nullSafeInt(rs, "accTaxonId"); //if common name is related to synonym this is the accepted taxon id
|
197
|
|
198
|
Integer refId = nullSafeInt(rs, "refId");
|
199
|
// Integer ptNameFk = nullSafeInt(rs,"PTNameFk");
|
200
|
String commonNameString = rs.getString("CommonName");
|
201
|
String iso639_2 = rs.getString("ISO639_2");
|
202
|
String iso639_1 = rs.getString("ISO639_1");
|
203
|
String languageString = rs.getString("Language");
|
204
|
String originalLanguageString = rs.getString("LanguageOriginal");
|
205
|
Integer misNameRefFk = nullSafeInt(rs, "MisNameRefFk");
|
206
|
Integer languageRefRefFk = nullSafeInt(rs, "languageRefRefFk");
|
207
|
String refLanguage = rs.getString("refLanguage");
|
208
|
String refLanguageIso639_2 = rs.getString("refLanguageIso639_2");
|
209
|
String status = rs.getString("Status");
|
210
|
Integer nameInSourceFk = nullSafeInt( rs, "NameInSourceFk");
|
211
|
Integer misappliedTaxonId = nullSafeInt( rs, "misappliedTaxonId");
|
212
|
|
213
|
if (commonNameId == lastCommonNameId){
|
214
|
logger.warn("CommonNameId >1 times in query. This may happen due to LEFT JOINS to fact and/or accepted taxon and e.g. multiple taxon relationships. 2018-04-01 no such double relation existed in E+M. ");
|
215
|
}else{
|
216
|
lastCommonNameId = commonNameId;
|
217
|
}
|
218
|
|
219
|
//regions
|
220
|
String regionFks = rs.getString("RegionFks");
|
221
|
String[] regionFkSplit = (regionFks==null)? new String[0] : regionFks.split(",");
|
222
|
|
223
|
//commonNameString
|
224
|
if (isBlank(commonNameString)){
|
225
|
String message = "CommonName is empty or null. Do not import record for taxon " + taxonId;
|
226
|
logger.warn(message);
|
227
|
continue;
|
228
|
}
|
229
|
|
230
|
//taxon
|
231
|
Taxon taxon = null;
|
232
|
TaxonBase<?> taxonBase = taxonMap.get(String.valueOf(taxonId));
|
233
|
if (taxonBase == null){
|
234
|
logger.warn("Taxon (" + taxonId + ") could not be found. Common name " + commonNameString + "(" + commonNameId + ") not imported");
|
235
|
continue;
|
236
|
}else if (taxonBase.isInstanceOf(Taxon.class)){
|
237
|
taxon = CdmBase.deproxy(taxonBase, Taxon.class);
|
238
|
if (factTaxonId != null && !factTaxonId.equals(taxonId)){
|
239
|
logger.warn("Fact taxon ("+factTaxonId+") for common name "+commonNameId+" differs from common name taxon " + taxonId);
|
240
|
}
|
241
|
}else{
|
242
|
Taxon factTaxon = null;
|
243
|
if (factTaxonId != null && factTaxonId.equals(accTaxonId)){
|
244
|
factTaxon = taxonMap.get(String.valueOf(factTaxonId));
|
245
|
}
|
246
|
if (factTaxon != null){
|
247
|
taxon = factTaxon;
|
248
|
}else{
|
249
|
logger.warn("taxon (" + taxonId + ") is not accepted. Can't import common name " + commonNameId + ". FactTaxonId= " + factTaxonId + "; accTaxonId = " + accTaxonId);
|
250
|
continue;
|
251
|
}
|
252
|
}
|
253
|
|
254
|
//Language
|
255
|
Language language = getAndHandleLanguage(iso6392Map, iso639_2, iso639_1, languageString, originalLanguageString, state);
|
256
|
|
257
|
//CommonTaxonName
|
258
|
List<CommonTaxonName> commonTaxonNames = new ArrayList<>();
|
259
|
for (String regionFk : regionFkSplit){ //
|
260
|
CommonTaxonName commonTaxonName;
|
261
|
if (commonTaxonNames.size() == 0){
|
262
|
commonTaxonName = CommonTaxonName.NewInstance(commonNameString, language);
|
263
|
}else{
|
264
|
commonTaxonName = (CommonTaxonName)commonTaxonNames.get(0).clone();
|
265
|
}
|
266
|
commonTaxonNames.add(commonTaxonName);
|
267
|
regionFk = regionFk.trim();
|
268
|
NamedArea area = regionMap.get(regionFk);
|
269
|
if (area == null){
|
270
|
if (regionFkSplit.length > 1 && isNotBlank(regionFk)){
|
271
|
logger.warn("Area for " + regionFk + " not defined in regionMap.");
|
272
|
}else{
|
273
|
//no region is defined
|
274
|
}
|
275
|
}else{
|
276
|
commonTaxonName.setArea(area);
|
277
|
TaxonDescription description = getDescription(taxon);
|
278
|
description.addElement(commonTaxonName);
|
279
|
}
|
280
|
}
|
281
|
|
282
|
//Reference/Source
|
283
|
if (! CdmUtils.nullSafeEqual(refId, languageRefRefFk)){
|
284
|
//use strRefId if languageRefFk is null
|
285
|
if (languageRefRefFk == null){
|
286
|
languageRefRefFk = refId;
|
287
|
}else{
|
288
|
logger.warn("CommonName.RefFk (" + CdmUtils.Nz(refId) + ") and LanguageReference.RefFk " + languageRefRefFk + " are not equal. I will import only languageReference.RefFk");
|
289
|
}
|
290
|
}
|
291
|
|
292
|
Reference reference = refMap.get(String.valueOf(languageRefRefFk));
|
293
|
if (reference == null && languageRefRefFk != null){
|
294
|
logger.warn("CommonName reference was null but reference exists. languageRefRefFk = " + languageRefRefFk + "; commonNameId = " + commonNameId);
|
295
|
}
|
296
|
String microCitation = null;
|
297
|
String originalNameString = null;
|
298
|
|
299
|
TaxonName nameUsedInSource = taxonNameMap.get(String.valueOf(nameInSourceFk));
|
300
|
if (nameInSourceFk != null && nameUsedInSource == null){
|
301
|
if (nameInSourceFk != -1 || !state.getConfig().isEuroMed()){
|
302
|
logger.warn("Name used in source (" + nameInSourceFk + ") was not found for common name " + commonNameId);
|
303
|
}
|
304
|
}
|
305
|
for (CommonTaxonName commonTaxonName : commonTaxonNames){
|
306
|
DescriptionElementSource source = DescriptionElementSource.NewPrimarySourceInstance(reference, microCitation, nameUsedInSource, originalNameString);
|
307
|
commonTaxonName.addSource(source);
|
308
|
}
|
309
|
|
310
|
|
311
|
//MisNameRef
|
312
|
if (misNameRefFk != null){
|
313
|
//Taxon misappliedName = getMisappliedName(biblioRefMap, nomRefMap, misNameRefFk, taxon);
|
314
|
Taxon misappliedNameTaxon = null;
|
315
|
if (misappliedTaxonId != null){
|
316
|
TaxonBase<?> misTaxonBase = taxonMap.get(String.valueOf(misappliedTaxonId));
|
317
|
if (misTaxonBase == null){
|
318
|
logger.warn("MisappliedName not found for misappliedTaxonId " + misappliedTaxonId + "; commonNameId: " + commonNameId);
|
319
|
}else if (misTaxonBase.isInstanceOf(Taxon.class)){
|
320
|
misappliedNameTaxon = CdmBase.deproxy(misTaxonBase, Taxon.class);
|
321
|
}else{
|
322
|
logger.warn("Misapplied name taxon is not of type Taxon but " + misTaxonBase.getClass().getSimpleName());
|
323
|
}
|
324
|
}else{
|
325
|
|
326
|
Reference sec = refMap.get(String.valueOf(misNameRefFk));
|
327
|
if (nameUsedInSource == null || sec == null){
|
328
|
logger.warn("Taxon name or misapplied name reference is null for common name " + commonNameId);
|
329
|
}else{
|
330
|
misappliedNameTaxon = Taxon.NewInstance(nameUsedInSource, sec);
|
331
|
MarkerType misCommonNameMarker = getMarkerType(state, BerlinModelTransformer.uuidMisappliedCommonName,"Misapplied Common Name in Berlin Model", "Misapplied taxon was automatically created by Berlin Model import for a common name with a misapplied name reference", "MCN");
|
332
|
Marker marker = Marker.NewInstance(misCommonNameMarker, true);
|
333
|
misappliedNameTaxon.addMarker(marker);
|
334
|
taxaToSave.add(misappliedNameTaxon);
|
335
|
logger.warn("Misapplied name taxon could not be found in database but misapplied name reference exists for common name. " +
|
336
|
"New misapplied name for misapplied reference common name was added. CommonNameId: " + commonNameId);
|
337
|
}
|
338
|
}
|
339
|
if (misappliedNameTaxon != null){
|
340
|
|
341
|
if (! taxon.getMisappliedNames(false).contains(misappliedNameTaxon)){
|
342
|
taxon.addMisappliedName(misappliedNameTaxon,state.getTransactionalSourceReference(), null);
|
343
|
logger.warn("Misapplied name for common name was not found related to the accepted taxon. Created new relationship. CommonNameId: " + commonNameId);
|
344
|
}
|
345
|
|
346
|
TaxonDescription misappliedNameDescription = getDescription(misappliedNameTaxon);
|
347
|
for (CommonTaxonName commonTaxonName : commonTaxonNames){
|
348
|
CommonTaxonName commonNameClone = (CommonTaxonName)commonTaxonName.clone();
|
349
|
misappliedNameDescription.addElement(commonNameClone);
|
350
|
}
|
351
|
}else{
|
352
|
//wird schon oben gelogged
|
353
|
//logger.warn("Misapplied name is null for common name " + commonNameId);
|
354
|
}
|
355
|
|
356
|
}
|
357
|
|
358
|
//reference extensions
|
359
|
if (reference != null){
|
360
|
if (isNotBlank(refLanguage) && !reference.hasExtension(REFERENCE_LANGUAGE_STRING_UUID, refLanguage)){
|
361
|
ExtensionType refLanguageExtensionType = getExtensionType( state, REFERENCE_LANGUAGE_STRING_UUID, "reference language","The language of the reference","ref. lang.");
|
362
|
Extension.NewInstance(reference, refLanguage, refLanguageExtensionType);
|
363
|
}
|
364
|
|
365
|
if (isNotBlank(refLanguageIso639_2) && !reference.hasExtension(REFERENCE_LANGUAGE_ISO639_2_UUID, refLanguage)){
|
366
|
ExtensionType refLanguageIsoExtensionType = getExtensionType( state, REFERENCE_LANGUAGE_ISO639_2_UUID, "reference language iso 639-2","The iso 639-2 code of the references language","ref. lang. 639-2");
|
367
|
Extension.NewInstance(reference, refLanguageIso639_2, refLanguageIsoExtensionType);
|
368
|
}
|
369
|
}else if (isNotBlank(refLanguage) || isNotBlank(refLanguageIso639_2)){
|
370
|
logger.warn("Reference is null (" + languageRefRefFk + ") but refLanguage (" + CdmUtils.Nz(refLanguage) + ") or iso639_2 (" + CdmUtils.Nz(refLanguageIso639_2) + ") was not null for common name ("+ commonNameId +")");
|
371
|
}
|
372
|
|
373
|
//status
|
374
|
if (isNotBlank(status)){
|
375
|
TermVocabulary<MarkerType> markerTypeVoc = getVocabulary(TermType.MarkerType, BerlinModelTransformer.uuidVocEMMarkerType,
|
376
|
"Euro+Med marker type vocabulary", "E+M marker types", null, null, false, MarkerType.COMPLETE());
|
377
|
MarkerType recommendedMarkerType = getMarkerType( state, COMMONNAME_STATUS_RECOMMENDED_UUID, "recommended","If the common name has the status recommended (see also status 'synonym', if none of them is true the default status is 'unassessed')",
|
378
|
"recommended", markerTypeVoc);
|
379
|
MarkerType synonymMarkerType = getMarkerType( state, COMMONNAME_STATUS_SYNONYM_UUID, "synonym","If the common name has the status synonym (see also status 'recommended', if none of them is true the default status is 'unassessed')",
|
380
|
"synonym", markerTypeVoc);
|
381
|
for (CommonTaxonName commonTaxonName : commonTaxonNames){
|
382
|
Marker marker = null;
|
383
|
if (status.equals("recommended")){
|
384
|
marker = Marker.NewInstance(recommendedMarkerType, true);
|
385
|
}else if (status.equals("synonym")){
|
386
|
marker = Marker.NewInstance(synonymMarkerType, true);
|
387
|
}else if (status.equals("unassessed")){
|
388
|
//do nothing
|
389
|
}else{
|
390
|
logger.warn("Unknown common name status: " + status);
|
391
|
}
|
392
|
if (marker != null){
|
393
|
commonTaxonName.addMarker(marker);
|
394
|
}
|
395
|
}
|
396
|
}
|
397
|
|
398
|
//Notes
|
399
|
for (CommonTaxonName commonTaxonName : commonTaxonNames){
|
400
|
doIdCreatedUpdatedNotes(state, commonTaxonName, rs, String.valueOf(commonNameId), NAMESPACE);
|
401
|
}
|
402
|
partitioner.startDoSave();
|
403
|
taxaToSave.add(taxon);
|
404
|
|
405
|
}
|
406
|
} catch (SQLException e) {
|
407
|
logger.error("SQLException:" + e);
|
408
|
return false;
|
409
|
} catch (ClassCastException e) {
|
410
|
e.printStackTrace();
|
411
|
} catch (Exception e) {
|
412
|
throw e;
|
413
|
}
|
414
|
|
415
|
// logger.info( i + " names handled");
|
416
|
getTaxonService().save(taxaToSave);
|
417
|
return success;
|
418
|
|
419
|
}
|
420
|
|
421
|
/**
|
422
|
* @param iso6392Map
|
423
|
* @param iso639_2
|
424
|
* @param languageString
|
425
|
* @param originalLanguageString
|
426
|
* @param state
|
427
|
* @return
|
428
|
*/
|
429
|
private Language getAndHandleLanguage(Map<String, Language> iso639Map, String iso639_2, String iso639_1, String languageString, String originalLanguageString, BerlinModelImportState state) {
|
430
|
Language language;
|
431
|
if (isNotBlank(iso639_2)|| isNotBlank(iso639_1) ){
|
432
|
//TODO test performance, implement in state
|
433
|
language = getLanguageFromIsoMap(iso639Map, iso639_2, iso639_1);
|
434
|
|
435
|
if (language == null){
|
436
|
language = getTermService().getLanguageByIso(iso639_2);
|
437
|
iso639Map.put(iso639_2, language);
|
438
|
if (language == null){
|
439
|
try {
|
440
|
language = getTermService().getLanguageByIso(iso639_1);
|
441
|
} catch (Exception e) {
|
442
|
// TODO Auto-generated catch block
|
443
|
// TODO remove if problem with duplicate DescElement_Annot id is solved
|
444
|
e.printStackTrace();
|
445
|
}
|
446
|
iso639Map.put(iso639_1, language);
|
447
|
}
|
448
|
if (language == null){
|
449
|
logger.warn("Language for code ISO693-2 '" + iso639_2 + "' and ISO693-1 '" + iso639_1 + "' was not found");
|
450
|
}
|
451
|
}
|
452
|
} else if ("unknown".equals(languageString)){
|
453
|
language = Language.UNKNOWN_LANGUAGE();
|
454
|
} else if ("Majorcan".equalsIgnoreCase(languageString)){
|
455
|
language = getLanguage(state, BerlinModelTransformer.uuidLangMajorcan, "Majorcan", "Majorcan (original 'mallorqu\u00EDn')", null);
|
456
|
}else{
|
457
|
logger.warn("language ISO 639_1 and ISO 639_2 were empty for " + languageString);
|
458
|
language = null;
|
459
|
}
|
460
|
addOriginalLanguage(language, originalLanguageString);
|
461
|
return language;
|
462
|
}
|
463
|
|
464
|
|
465
|
/**
|
466
|
* @param iso639Map
|
467
|
* @param iso639_2
|
468
|
* @param iso639_1
|
469
|
* @return
|
470
|
*/
|
471
|
private Language getLanguageFromIsoMap(Map<String, Language> iso639Map, String iso639_2, String iso639_1) {
|
472
|
Language language;
|
473
|
language = iso639Map.get(iso639_2);
|
474
|
if (language == null){
|
475
|
language = iso639Map.get(iso639_1);
|
476
|
}
|
477
|
return language;
|
478
|
}
|
479
|
|
480
|
/**
|
481
|
* @param language
|
482
|
* @param originalLanguageString
|
483
|
*/
|
484
|
private void addOriginalLanguage(Language language, String originalLanguageString) {
|
485
|
if (isBlank(originalLanguageString)){
|
486
|
return;
|
487
|
}else if (language == null){
|
488
|
logger.warn("Language could not be defined, but originalLanguageString exists: " + originalLanguageString);
|
489
|
}else {
|
490
|
Representation representation = language.getRepresentation(language);
|
491
|
if (representation == null){
|
492
|
language.addRepresentation(Representation.NewInstance(originalLanguageString, originalLanguageString, originalLanguageString, language));
|
493
|
getTermService().saveOrUpdate(language);
|
494
|
}
|
495
|
}
|
496
|
|
497
|
}
|
498
|
|
499
|
|
500
|
|
501
|
/**
|
502
|
* Fills the regionFks with all regionFks from emCommonName. Comma separated regionFks will be split.
|
503
|
* @param state
|
504
|
* @param regionFks
|
505
|
* @param source
|
506
|
* @return
|
507
|
* @throws SQLException
|
508
|
*
|
509
|
*/
|
510
|
private void getRegionFks(BerlinModelImportState state, SortedSet<Integer> regionFks, Source source) throws SQLException {
|
511
|
String sql = " SELECT DISTINCT RegionFks FROM emCommonName";
|
512
|
if (state.getConfig().getCommonNameFilter() != null){
|
513
|
sql += " WHERE " + state.getConfig().getCommonNameFilter();
|
514
|
}
|
515
|
|
516
|
ResultSet rs = source.getResultSet(sql);
|
517
|
while (rs.next()){
|
518
|
String strRegionFks = rs.getString("RegionFks");
|
519
|
if (isBlank(strRegionFks)){
|
520
|
continue;
|
521
|
}
|
522
|
|
523
|
String[] regionFkArray = strRegionFks.split(",");
|
524
|
for (String regionFk: regionFkArray){
|
525
|
regionFk = regionFk.trim();
|
526
|
if (! StringUtils.isNumeric(regionFk) || "".equals(regionFk) ){
|
527
|
state.setUnsuccessfull();
|
528
|
logger.warn("RegionFk is not numeric: " + regionFk + " ( part of " + strRegionFks + ")");
|
529
|
}else{
|
530
|
regionFks.add(Integer.valueOf(regionFk));
|
531
|
}
|
532
|
}
|
533
|
}
|
534
|
return;
|
535
|
}
|
536
|
|
537
|
|
538
|
|
539
|
/**
|
540
|
* Fills the {@link #regionMap} by all emLanguageRegion regions defined in the sql filter.
|
541
|
* {@link #regionMap} maps emLanguageRegion.RegionId to named areas.
|
542
|
* @param state
|
543
|
* @param sqlWhere
|
544
|
* @param emTdwgMap
|
545
|
* @throws SQLException
|
546
|
*/
|
547
|
private void fillRegionMap(BerlinModelImportState state, String sqlWhere,
|
548
|
Map<String, String> emTdwgMap) throws SQLException {
|
549
|
Source source = state.getConfig().getSource();
|
550
|
String sql;
|
551
|
ResultSet rs;
|
552
|
sql = " SELECT RegionId, Region FROM emLanguageRegion WHERE RegionId IN ("+ sqlWhere+ ") ";
|
553
|
rs = source.getResultSet(sql);
|
554
|
while (rs.next()){
|
555
|
Object regionId = rs.getObject("RegionId");
|
556
|
String region = rs.getString("Region");
|
557
|
String[] splitRegion = region.split("-");
|
558
|
if (splitRegion.length <= 1){
|
559
|
NamedArea newArea = getNamedArea(state, null, region, "Language region '" + region + "'", null, null, null);
|
560
|
// getTermService().save(newArea);
|
561
|
regionMap.put(String.valueOf(regionId), newArea);
|
562
|
logger.info("Found new area: " + region);
|
563
|
}else if (splitRegion.length == 2){
|
564
|
String emCode = splitRegion[1].trim();
|
565
|
String tdwgCode = emTdwgMap.get(emCode);
|
566
|
if (isNotBlank(tdwgCode) ){
|
567
|
NamedArea tdwgArea = getNamedArea(state, tdwgCode);
|
568
|
regionMap.put(String.valueOf(regionId), tdwgArea);
|
569
|
}else {
|
570
|
NamedArea area = getOtherAreas(state, emCode, tdwgCode);
|
571
|
if (area != null){
|
572
|
regionMap.put(String.valueOf(regionId), area);
|
573
|
}else{
|
574
|
logger.warn("emCode did not map to valid tdwgCode: " + CdmUtils.Nz(emCode) + "->" + CdmUtils.Nz(tdwgCode));
|
575
|
}
|
576
|
}
|
577
|
}
|
578
|
}
|
579
|
}
|
580
|
|
581
|
|
582
|
/**
|
583
|
* Returns the are for a given TDWG code. See {@link #getEmTdwgMap(Source)} for exceptions from
|
584
|
* the TDWG code
|
585
|
* @param state
|
586
|
* @param tdwgCode
|
587
|
*/
|
588
|
private NamedArea getNamedArea(BerlinModelImportState state, String tdwgCode) {
|
589
|
NamedArea area;
|
590
|
if (tdwgCode.equalsIgnoreCase("Ab")){
|
591
|
area = getNamedArea(state, BerlinModelTransformer.uuidAb, "Azerbaijan & Nakhichevan", "Azerbaijan (including Nakhichevan)", "Ab", null, null);
|
592
|
getTermService().saveOrUpdate(area);
|
593
|
}else if (tdwgCode.equalsIgnoreCase("Uk")){
|
594
|
area = getNamedArea(state, BerlinModelTransformer.uuidUk , "Ukraine & Crimea", "Ukraine (including Crimea)", "Uk", null, null);
|
595
|
getTermService().saveOrUpdate(area);
|
596
|
}else if (tdwgCode.equalsIgnoreCase("Rf")){
|
597
|
// area = getNamedArea(state, BerlinModelTransformer.uuidRf , "Ukraine & Crimea", "Ukraine (including Crimea)", "Uk", null, null);
|
598
|
// getTermService().saveOrUpdate(area);
|
599
|
area = Country.RUSSIANFEDERATION();
|
600
|
}else if (tdwgCode.equalsIgnoreCase("Gg")){
|
601
|
area = Country.GEORGIA();
|
602
|
}else if (tdwgCode.equalsIgnoreCase("SM")){
|
603
|
area = getNamedArea(state, BerlinModelTransformer.uuidSM , "Serbia & Montenegro", "Serbia & Montenegro", "SM", null, null);
|
604
|
getTermService().saveOrUpdate(area);
|
605
|
}else if (tdwgCode.equalsIgnoreCase("Tu")){
|
606
|
area = Country.TURKEYREPUBLICOF();
|
607
|
}else{
|
608
|
area = TdwgAreaProvider.getAreaByTdwgAbbreviation(tdwgCode);
|
609
|
}
|
610
|
if (area == null){
|
611
|
logger.warn("Area is null for " + tdwgCode);
|
612
|
}
|
613
|
return area;
|
614
|
}
|
615
|
|
616
|
/**
|
617
|
* @param regionFks
|
618
|
* @return
|
619
|
*/
|
620
|
private String getSqlWhere(SortedSet<Integer> regionFks) {
|
621
|
String sqlWhere = "";
|
622
|
for (Integer regionFk : regionFks){
|
623
|
sqlWhere += regionFk + ",";
|
624
|
}
|
625
|
sqlWhere = sqlWhere.substring(0, sqlWhere.length()-1);
|
626
|
return sqlWhere;
|
627
|
}
|
628
|
|
629
|
/**
|
630
|
* Returns a map which is filled by the emCode->TdwgCode mapping defined in emArea.
|
631
|
* Some exceptions are defined for emCode 'Ab','Rf','Uk' and some additional mapping is added
|
632
|
* for 'Ab / Ab(A)', 'Ga / Ga(F)', 'It / It(I)', 'Ar / Ar(A)','Hs / Hs(S)'
|
633
|
* @param source
|
634
|
* @throws SQLException
|
635
|
*/
|
636
|
private Map<String, String> getEmTdwgMap(Source source) throws SQLException {
|
637
|
String sql;
|
638
|
ResultSet rs;
|
639
|
Map<String, String> emTdwgMap = new HashMap<>();
|
640
|
sql = " SELECT EmCode, TDWGCode FROM emArea ";
|
641
|
rs = source.getResultSet(sql);
|
642
|
while (rs.next()){
|
643
|
String emCode = rs.getString("EMCode");
|
644
|
String TDWGCode = rs.getString("TDWGCode");
|
645
|
if (isNotBlank(emCode) ){
|
646
|
emCode = emCode.trim();
|
647
|
if (emCode.equalsIgnoreCase("Ab") || emCode.equalsIgnoreCase("Rf")||
|
648
|
emCode.equalsIgnoreCase("Uk") || emCode.equalsIgnoreCase("Gg")
|
649
|
|| emCode.equalsIgnoreCase("SM") || emCode.equalsIgnoreCase("Tu")){
|
650
|
emTdwgMap.put(emCode, emCode);
|
651
|
}else if (isNotBlank(TDWGCode)){
|
652
|
emTdwgMap.put(emCode, TDWGCode.trim());
|
653
|
}
|
654
|
}
|
655
|
}
|
656
|
emTdwgMap.put("Ab / Ab(A)", "Ab");
|
657
|
emTdwgMap.put("Ga / Ga(F)", "FRA-FR");
|
658
|
emTdwgMap.put("It / It(I)", "ITA");
|
659
|
emTdwgMap.put("Uk / Uk(U)", "Uk");
|
660
|
emTdwgMap.put("Ar / Ar(A)", "TCS-AR");
|
661
|
emTdwgMap.put("Hs / Hs(S)", "SPA-SP");
|
662
|
emTdwgMap.put("Hb / Hb(E)", "IRE-IR");
|
663
|
|
664
|
return emTdwgMap;
|
665
|
}
|
666
|
|
667
|
|
668
|
/**
|
669
|
* Returns the first non-image gallery description. Creates a new one if no description exists.
|
670
|
* @param taxon
|
671
|
* @return
|
672
|
*/
|
673
|
private TaxonDescription getDescription(Taxon taxon) {
|
674
|
TaxonDescription result = null;
|
675
|
for (TaxonDescription taxonDescription : taxon.getDescriptions()){
|
676
|
if (! taxonDescription.isImageGallery()){
|
677
|
result = taxonDescription;
|
678
|
}
|
679
|
}
|
680
|
if (result == null){
|
681
|
result = TaxonDescription.NewInstance(taxon);
|
682
|
}
|
683
|
return result;
|
684
|
}
|
685
|
|
686
|
@Override
|
687
|
public Map<Object, Map<String, ? extends CdmBase>> getRelatedObjectsForPartition(ResultSet rs, BerlinModelImportState state) {
|
688
|
String nameSpace;
|
689
|
Class<?> cdmClass;
|
690
|
Set<String> idSet;
|
691
|
Map<Object, Map<String, ? extends CdmBase>> result = new HashMap<>();
|
692
|
|
693
|
String pos = "0";
|
694
|
try{
|
695
|
Set<String> taxonIdSet = new HashSet<>();
|
696
|
Set<String> nameIdSet = new HashSet<>();
|
697
|
Set<String> referenceIdSet = new HashSet<>();
|
698
|
while (rs.next()){
|
699
|
handleForeignKey(rs, taxonIdSet, "taxonId");
|
700
|
handleForeignKey(rs, taxonIdSet, "factTaxonId");
|
701
|
handleForeignKey(rs, taxonIdSet, "misappliedTaxonId");
|
702
|
handleForeignKey(rs, referenceIdSet, "refId");
|
703
|
handleForeignKey(rs, referenceIdSet, "languageRefRefFk");
|
704
|
handleForeignKey(rs, nameIdSet, "NameInSourceFk");
|
705
|
handleForeignKey(rs, nameIdSet, "PTNameFk");
|
706
|
handleForeignKey(rs, referenceIdSet, "MisNameRefFk");
|
707
|
}
|
708
|
|
709
|
//name map
|
710
|
nameSpace = BerlinModelTaxonNameImport.NAMESPACE;
|
711
|
cdmClass = TaxonName.class;
|
712
|
idSet = nameIdSet;
|
713
|
@SuppressWarnings("unchecked")
|
714
|
Map<String, TaxonName> nameMap = (Map<String, TaxonName>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
|
715
|
result.put(nameSpace, nameMap);
|
716
|
|
717
|
//taxon map
|
718
|
nameSpace = BerlinModelTaxonImport.NAMESPACE;
|
719
|
cdmClass = TaxonBase.class;
|
720
|
idSet = taxonIdSet;
|
721
|
@SuppressWarnings("unchecked")
|
722
|
Map<String, TaxonBase<?>> taxonMap = (Map<String, TaxonBase<?>>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
|
723
|
result.put(nameSpace, taxonMap);
|
724
|
|
725
|
//reference map
|
726
|
nameSpace = BerlinModelReferenceImport.REFERENCE_NAMESPACE;
|
727
|
cdmClass = Reference.class;
|
728
|
idSet = referenceIdSet;
|
729
|
@SuppressWarnings("unchecked")
|
730
|
Map<String, Reference> referenceMap = (Map<String, Reference>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
|
731
|
result.put(nameSpace, referenceMap);
|
732
|
// TODO remove if problem with duplicate DescElement_Annot id is solved
|
733
|
} catch (SQLException e) {
|
734
|
throw new RuntimeException("pos: " +pos, e);
|
735
|
} catch (NullPointerException nep){
|
736
|
logger.error("NullPointerException in getRelatedObjectsForPartition()");
|
737
|
}
|
738
|
return result;
|
739
|
}
|
740
|
|
741
|
|
742
|
@Override
|
743
|
protected boolean doCheck(BerlinModelImportState state){
|
744
|
IOValidator<BerlinModelImportState> validator = new BerlinModelCommonNamesImportValidator();
|
745
|
return validator.validate(state);
|
746
|
}
|
747
|
|
748
|
|
749
|
@Override
|
750
|
protected boolean isIgnore(BerlinModelImportState state){
|
751
|
return ! state.getConfig().isDoCommonNames();
|
752
|
}
|
753
|
|
754
|
}
|