2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
10 package eu
.etaxonomy
.cdm
.io
.redlist
.gefaesspflanzen
;
12 import java
.sql
.ResultSet
;
13 import java
.sql
.SQLException
;
14 import java
.util
.HashMap
;
15 import java
.util
.HashSet
;
18 import java
.util
.regex
.Matcher
;
19 import java
.util
.regex
.Pattern
;
21 import org
.apache
.log4j
.Logger
;
22 import org
.springframework
.stereotype
.Component
;
24 import eu
.etaxonomy
.cdm
.common
.CdmUtils
;
25 import eu
.etaxonomy
.cdm
.hibernate
.HibernateProxyHelper
;
26 import eu
.etaxonomy
.cdm
.io
.common
.DbImportBase
;
27 import eu
.etaxonomy
.cdm
.io
.common
.IPartitionedIO
;
28 import eu
.etaxonomy
.cdm
.io
.common
.ImportHelper
;
29 import eu
.etaxonomy
.cdm
.io
.common
.ResultSetPartitioner
;
30 import eu
.etaxonomy
.cdm
.io
.common
.mapping
.UndefinedTransformerMethodException
;
31 import eu
.etaxonomy
.cdm
.model
.agent
.AgentBase
;
32 import eu
.etaxonomy
.cdm
.model
.agent
.TeamOrPersonBase
;
33 import eu
.etaxonomy
.cdm
.model
.common
.Annotation
;
34 import eu
.etaxonomy
.cdm
.model
.common
.AnnotationType
;
35 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
36 import eu
.etaxonomy
.cdm
.model
.common
.Language
;
37 import eu
.etaxonomy
.cdm
.model
.description
.CommonTaxonName
;
38 import eu
.etaxonomy
.cdm
.model
.description
.TaxonDescription
;
39 import eu
.etaxonomy
.cdm
.model
.name
.BotanicalName
;
40 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalStatus
;
41 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalStatusType
;
42 import eu
.etaxonomy
.cdm
.model
.name
.NonViralName
;
43 import eu
.etaxonomy
.cdm
.model
.name
.Rank
;
44 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameBase
;
45 import eu
.etaxonomy
.cdm
.model
.taxon
.Synonym
;
46 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
47 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
48 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonRelationship
;
49 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonRelationshipType
;
50 import eu
.etaxonomy
.cdm
.strategy
.parser
.NonViralNameParserImpl
;
60 @SuppressWarnings("serial")
61 public class RedListGefaesspflanzenImportNames
extends DbImportBase
<RedListGefaesspflanzenImportState
, RedListGefaesspflanzenImportConfigurator
> {
63 private static final Logger logger
= Logger
.getLogger(RedListGefaesspflanzenImportNames
.class);
65 private static final String tableName
= "Rote Liste Gefäßpflanzen";
67 private static final String pluralString
= "names";
69 private static final boolean STRICT_TITLE_CHECK
= false;
71 public RedListGefaesspflanzenImportNames() {
72 super(tableName
, pluralString
);
76 protected String
getIdQuery(RedListGefaesspflanzenImportState state
) {
77 return "SELECT NAMNR "
78 + "FROM V_TAXATLAS_D20_EXPORT t "
83 protected String
getRecordQuery(RedListGefaesspflanzenImportConfigurator config
) {
84 String result
= " SELECT * "
85 + " FROM V_TAXATLAS_D20_EXPORT t "
86 + " WHERE t.NAMNR IN (@IDSET)";
87 result
= result
.replace("@IDSET", IPartitionedIO
.ID_LIST_TOKEN
);
92 protected void doInvoke(RedListGefaesspflanzenImportState state
) {
93 super.doInvoke(state
);
98 public boolean doPartition(ResultSetPartitioner partitioner
, RedListGefaesspflanzenImportState state
) {
99 ResultSet rs
= partitioner
.getResultSet();
100 Set
<TaxonNameBase
> namesToSave
= new HashSet
<TaxonNameBase
>();
101 Set
<TaxonBase
> taxaToSave
= new HashSet
<TaxonBase
>();
104 makeSingleNameAndTaxon(state
, rs
, namesToSave
, taxaToSave
);
107 } catch (SQLException e
) {
111 getNameService().saveOrUpdate(namesToSave
);
112 getTaxonService().saveOrUpdate(taxaToSave
);
116 private void makeSingleNameAndTaxon(RedListGefaesspflanzenImportState state
, ResultSet rs
, Set
<TaxonNameBase
> namesToSave
, Set
<TaxonBase
> taxaToSave
)
117 throws SQLException
{
118 long id
= rs
.getLong(RedListUtil
.NAMNR
);
119 String clTaxonString
= rs
.getString(RedListUtil
.CL_TAXON
);
122 NonViralName
<?
> name
= importName(state
, rs
, namesToSave
);
126 importAuthors(state
, rs
, name
);
129 TaxonBase
<?
> taxonBase
= importTaxon(rs
, name
);
131 RedListUtil
.logMessage(id
, "Taxon for name "+name
+" could not be created.", logger
);
135 //---CONCEPT RELATIONSHIPS---
137 TaxonBase
<?
> checklistTaxon
= null;
138 if(CdmUtils
.isNotBlank(clTaxonString
) && !clTaxonString
.trim().equals("-")){
139 checklistTaxon
= (TaxonBase
<?
>) taxonBase
.clone();
140 if(checklistTaxon
.isInstanceOf(Taxon
.class)){
141 TaxonRelationship relation
= HibernateProxyHelper
.deproxy(checklistTaxon
, Taxon
.class).addTaxonRelation(HibernateProxyHelper
.deproxy(taxonBase
, Taxon
.class), TaxonRelationshipType
.CONGRUENT_TO(), null, null);
142 relation
.setDoubtful(true);
145 ImportHelper
.setOriginalSource(checklistTaxon
, state
.getTransactionalSourceReference(), id
, RedListUtil
.TAXON_CHECKLISTE_NAMESPACE
);
146 taxaToSave
.add(checklistTaxon
);
148 //E, W, K, AW, AO, R, O, S
149 cloneTaxon(taxonBase
, RedListUtil
.CLASSIFICATION_NAMESPACE_E
, taxaToSave
, id
, state
);
150 cloneTaxon(taxonBase
, RedListUtil
.CLASSIFICATION_NAMESPACE_W
, taxaToSave
, id
, state
);
151 cloneTaxon(taxonBase
, RedListUtil
.CLASSIFICATION_NAMESPACE_K
, taxaToSave
, id
, state
);
152 cloneTaxon(taxonBase
, RedListUtil
.CLASSIFICATION_NAMESPACE_AW
, taxaToSave
, id
, state
);
153 cloneTaxon(taxonBase
, RedListUtil
.CLASSIFICATION_NAMESPACE_AO
, taxaToSave
, id
, state
);
154 cloneTaxon(taxonBase
, RedListUtil
.CLASSIFICATION_NAMESPACE_R
, taxaToSave
, id
, state
);
155 cloneTaxon(taxonBase
, RedListUtil
.CLASSIFICATION_NAMESPACE_O
, taxaToSave
, id
, state
);
156 cloneTaxon(taxonBase
, RedListUtil
.CLASSIFICATION_NAMESPACE_S
, taxaToSave
, id
, state
);
158 //NOTE: the source has to be added after cloning or otherwise the clone would also get the source
159 ImportHelper
.setOriginalSource(taxonBase
, state
.getTransactionalSourceReference(), id
, RedListUtil
.TAXON_GESAMTLISTE_NAMESPACE
);
160 taxaToSave
.add(taxonBase
);
163 private Taxon
cloneTaxon(final TaxonBase
<?
> gesamtListeTaxon
, String sourceNameSpace
, Set
<TaxonBase
> taxaToSave
, long id
, RedListGefaesspflanzenImportState state
){
164 Taxon clonedTaxon
= null;
166 if(gesamtListeTaxon
.isInstanceOf(Taxon
.class)){
167 clonedTaxon
= HibernateProxyHelper
.deproxy(gesamtListeTaxon
.clone(), Taxon
.class);
169 else if(gesamtListeTaxon
.isInstanceOf(Synonym
.class)){
170 clonedTaxon
= Taxon
.NewInstance(gesamtListeTaxon
.getName(), gesamtListeTaxon
.getSec());
173 RedListUtil
.logMessage(id
, "Taxon base "+gesamtListeTaxon
+" is neither taxon nor synonym! Taxon could not be cloned", logger
);
177 ImportHelper
.setOriginalSource(clonedTaxon
, state
.getTransactionalSourceReference(), id
, sourceNameSpace
);
178 taxaToSave
.add(clonedTaxon
);
182 private TaxonBase
<?
> importTaxon(ResultSet rs
, NonViralName
<?
> name
) throws SQLException
{
184 long id
= rs
.getLong(RedListUtil
.NAMNR
);
185 String taxNameString
= rs
.getString(RedListUtil
.TAXNAME
);
186 String gueltString
= rs
.getString(RedListUtil
.GUELT
);
187 String trivialString
= rs
.getString(RedListUtil
.TRIVIAL
);
188 String authorBasiString
= rs
.getString(RedListUtil
.AUTOR_BASI
);
189 String hybString
= rs
.getString(RedListUtil
.HYB
);
190 String florString
= rs
.getString(RedListUtil
.FLOR
);
191 String atlasIdxString
= rs
.getString(RedListUtil
.ATLAS_IDX
);
192 String kartString
= rs
.getString(RedListUtil
.KART
);
193 String rl2015String
= rs
.getString(RedListUtil
.RL2015
);
194 String ehrdString
= rs
.getString(RedListUtil
.EHRD
);
195 String wisskString
= rs
.getString(RedListUtil
.WISSK
);
197 TaxonBase
<?
> taxonBase
= null;
198 if(authorBasiString
.trim().contains(RedListUtil
.AUCT
)){
199 taxonBase
= Taxon
.NewInstance(name
, null);
200 taxonBase
.setAppendedPhrase(RedListUtil
.AUCT
);
202 else if(gueltString
.equals(RedListUtil
.GUELT_ACCEPTED_TAXON
)){
203 taxonBase
= Taxon
.NewInstance(name
, null);
205 else if(gueltString
.equals(RedListUtil
.GUELT_SYNONYM
) || gueltString
.equals(RedListUtil
.GUELT_BASIONYM
)){
206 taxonBase
= Synonym
.NewInstance(name
, null);
213 if(taxonBase
.isInstanceOf(Taxon
.class) && trivialString
!=null){
214 Taxon taxon
= HibernateProxyHelper
.deproxy(taxonBase
, Taxon
.class);
215 TaxonDescription description
= TaxonDescription
.NewInstance(taxon
);
216 description
.addElement(CommonTaxonName
.NewInstance(trivialString
, Language
.GERMAN()));
220 addAnnotation(RedListUtil
.FLOR
+": "+florString
, taxonBase
);
221 addAnnotation(RedListUtil
.ATLAS_IDX
+": "+atlasIdxString
, taxonBase
);
222 addAnnotation(RedListUtil
.KART
+": "+kartString
, taxonBase
);
223 addAnnotation(RedListUtil
.RL2015
+": "+rl2015String
, taxonBase
);
224 addAnnotation(RedListUtil
.EHRD
+": "+ehrdString
, taxonBase
);
225 addAnnotation(RedListUtil
.WISSK
+": "+wisskString
, taxonBase
);
227 //check taxon name consistency
228 checkTaxonNameConsistency(id
, taxNameString
, hybString
, taxonBase
);
232 private void addAnnotation(String string
, TaxonBase
<?
> taxonBase
) {
233 if(CdmUtils
.isNotBlank(string
)){
234 taxonBase
.addAnnotation(Annotation
.NewInstance(string
, AnnotationType
.TECHNICAL(), Language
.GERMAN()));
238 private void importAuthors(RedListGefaesspflanzenImportState state
, ResultSet rs
, NonViralName
<?
> name
) throws SQLException
{
240 long id
= rs
.getLong(RedListUtil
.NAMNR
);
241 String nomZusatzString
= rs
.getString(RedListUtil
.NOM_ZUSATZ
);
242 String taxZusatzString
= rs
.getString(RedListUtil
.TAX_ZUSATZ
);
243 String zusatzString
= rs
.getString(RedListUtil
.ZUSATZ
);
244 String authorKombString
= rs
.getString(RedListUtil
.AUTOR_KOMB
);
245 String authorBasiString
= rs
.getString(RedListUtil
.AUTOR_BASI
);
248 if(authorKombString
.contains(RedListUtil
.EX
)){
249 //TODO: what happens with multiple ex authors??
250 String
[] kombSplit
= authorKombString
.split(RedListUtil
.EX
);
251 if(kombSplit
.length
!=2){
252 RedListUtil
.logMessage(id
, "Multiple ex combination authors found", logger
);
254 for (int i
= 0; i
< kombSplit
.length
; i
++) {
256 //first author is ex author
257 TeamOrPersonBase
<?
> authorKomb
= (TeamOrPersonBase
<?
>) state
.getRelatedObject(RedListUtil
.AUTHOR_NAMESPACE
, kombSplit
[i
]);
258 name
.setExCombinationAuthorship(authorKomb
);
261 TeamOrPersonBase
<?
> authorKomb
= (TeamOrPersonBase
<?
>) state
.getRelatedObject(RedListUtil
.AUTHOR_NAMESPACE
, kombSplit
[i
]);
262 name
.setCombinationAuthorship(authorKomb
);
266 else if(authorKombString
.trim().contains(RedListUtil
.AUCT
)){
267 RedListUtil
.logMessage(id
, "AUCT information in "+RedListUtil
.AUTOR_KOMB
+" column", logger
);
269 else if(CdmUtils
.isNotBlank(authorKombString
)){
270 TeamOrPersonBase
<?
> authorKomb
= (TeamOrPersonBase
<?
>) state
.getRelatedObject(RedListUtil
.AUTHOR_NAMESPACE
, authorKombString
);
271 name
.setCombinationAuthorship(authorKomb
);
274 if(authorBasiString
.contains(RedListUtil
.EX
)){
275 String
[] basiSplit
= authorBasiString
.split(RedListUtil
.EX
);
276 for (int i
= 0; i
< basiSplit
.length
; i
++) {
277 if(basiSplit
.length
!=2){
278 RedListUtil
.logMessage(id
, "Multiple ex basionymn authors found", logger
);
281 TeamOrPersonBase
<?
> authorBasi
= (TeamOrPersonBase
<?
>) state
.getRelatedObject(RedListUtil
.AUTHOR_NAMESPACE
, basiSplit
[i
]);
282 if(CdmUtils
.isBlank(authorKombString
)){
283 name
.setExCombinationAuthorship(authorBasi
);
286 name
.setExBasionymAuthorship(authorBasi
);
290 TeamOrPersonBase
<?
> authorBasi
= (TeamOrPersonBase
<?
>) state
.getRelatedObject(RedListUtil
.AUTHOR_NAMESPACE
, basiSplit
[i
]);
291 if(CdmUtils
.isBlank(authorKombString
)){
292 name
.setCombinationAuthorship(authorBasi
);
295 name
.setBasionymAuthorship(authorBasi
);
300 else if(CdmUtils
.isNotBlank(authorBasiString
)){
301 //this seems to be a convention in the source database: When there is only a single author then only the "AUTOR_BASI" column is used
302 TeamOrPersonBase
<?
> authorBasi
= (TeamOrPersonBase
<?
>) state
.getRelatedObject(RedListUtil
.AUTHOR_NAMESPACE
, authorBasiString
);
303 if(CdmUtils
.isBlank(authorKombString
)){
304 name
.setCombinationAuthorship(authorBasi
);
307 name
.setBasionymAuthorship(authorBasi
);
311 //check authorship consistency
312 String authorString
= rs
.getString(RedListUtil
.AUTOR
);
313 String authorshipCache
= name
.getAuthorshipCache();
314 checkAuthorShipConsistency(id
, nomZusatzString
, taxZusatzString
, zusatzString
, authorString
, authorshipCache
);
317 private NonViralName
<?
> importName(RedListGefaesspflanzenImportState state
, ResultSet rs
, Set
<TaxonNameBase
> namesToSave
) throws SQLException
{
319 long id
= rs
.getLong(RedListUtil
.NAMNR
);
320 String taxNameString
= rs
.getString(RedListUtil
.TAXNAME
);
321 String rangString
= rs
.getString(RedListUtil
.RANG
);
322 String ep1String
= rs
.getString(RedListUtil
.EPI1
);
323 String ep2String
= rs
.getString(RedListUtil
.EPI2
);
324 String ep3String
= rs
.getString(RedListUtil
.EPI3
);
325 String nomZusatzString
= rs
.getString(RedListUtil
.NOM_ZUSATZ
);
326 String hybString
= rs
.getString(RedListUtil
.HYB
);
327 String formelString
= rs
.getString(RedListUtil
.FORMEL
);
329 if(CdmUtils
.isBlank(taxNameString
) && CdmUtils
.isBlank(ep1String
)){
330 RedListUtil
.logMessage(id
, "No name found!", logger
);
333 Rank rank
= makeRank(id
, state
, rangString
, ep3String
!=null);
334 NonViralName
<?
> name
= BotanicalName
.NewInstance(rank
);
336 //ep1 should always be present
337 if(CdmUtils
.isBlank(ep1String
)){
338 RedListUtil
.logMessage(id
, RedListUtil
.EPI1
+" is empty!", logger
);
340 name
.setGenusOrUninomial(ep1String
);
341 if(CdmUtils
.isNotBlank(ep2String
)){
342 if(rank
!=null && rank
.isInfraGenericButNotSpeciesGroup()){
343 name
.setInfraGenericEpithet(ep2String
);
346 name
.setSpecificEpithet(ep2String
);
349 if(CdmUtils
.isNotBlank(ep3String
)){
350 name
.setInfraSpecificEpithet(ep3String
);
352 //nomenclatural status
353 if(CdmUtils
.isNotBlank(nomZusatzString
)){
354 NomenclaturalStatusType statusType
= makeNomenclaturalStatus(id
, state
, nomZusatzString
);
355 if(statusType
!=null){
356 NomenclaturalStatus status
= NomenclaturalStatus
.NewInstance(statusType
);
357 //special case for invalid names where the DB entry contains
358 //additional information in brackets e.g. "nom. inval. (sine basion.)"
359 if(statusType
.equals(NomenclaturalStatusType
.INVALID())){
360 Pattern pattern
= Pattern
.compile("\\((.*?)\\)");
361 Matcher matcher
= pattern
.matcher(nomZusatzString
);
363 status
.setRuleConsidered(matcher
.group(1));
366 name
.addStatus(status
);
370 if(CdmUtils
.isNotBlank(hybString
)){
371 //save hybrid formula
372 if(CdmUtils
.isNotBlank(formelString
)){
373 Annotation annotation
= Annotation
.NewDefaultLanguageInstance(formelString
);
374 annotation
.setAnnotationType(AnnotationType
.TECHNICAL());
375 name
.addAnnotation(annotation
);
378 if(hybString
.equals(RedListUtil
.HYB_X
)){
379 name
.setBinomHybrid(true);
381 else if(hybString
.equals(RedListUtil
.HYB_G
)){
382 name
.setMonomHybrid(true);
384 else if(hybString
.equals(RedListUtil
.HYB_XF
)){
385 name
.setHybridFormula(true);
386 if(ep1String
.contains(RedListUtil
.HYB_SIGN
)){
387 RedListUtil
.logMessage(id
, "EPI1 has hybrid signs but with flag: "+RedListUtil
.HYB_XF
, logger
);
389 else if(ep2String
.contains(RedListUtil
.HYB_SIGN
)){
390 String
[] split
= ep2String
.split(RedListUtil
.HYB_SIGN
);
392 RedListUtil
.logMessage(id
, "Multiple hybrid signs found in "+ep2String
, logger
);
394 String hybridFormula1
= ep1String
+" "+split
[0].trim();
395 String hybridFormula2
= ep1String
+" "+split
[1].trim();
396 if(CdmUtils
.isNotBlank(ep3String
)){
397 hybridFormula1
+= " "+ep3String
;
398 hybridFormula2
+= " "+ep3String
;
400 String fullFormula
= hybridFormula1
+" "+RedListUtil
.HYB_SIGN
+" "+hybridFormula2
;
401 name
= NonViralNameParserImpl
.NewInstance().parseFullName(fullFormula
);
403 else if(ep3String
.contains(RedListUtil
.HYB_SIGN
)){
404 String
[] split
= ep3String
.split(RedListUtil
.HYB_SIGN
);
406 RedListUtil
.logMessage(id
, "Multiple hybrid signs found in "+ep3String
, logger
);
408 String hybridFormula1
= ep1String
+" "+ep2String
+" "+split
[0];
409 String hybridFormula2
= ep1String
+" "+ep2String
+" "+split
[1];
410 String fullFormula
= hybridFormula1
+" "+RedListUtil
.HYB_SIGN
+" "+hybridFormula2
;
411 name
= NonViralNameParserImpl
.NewInstance().parseFullName(fullFormula
);
414 else if(hybString
.equals(RedListUtil
.HYB_N
)){
415 name
= NonViralNameParserImpl
.NewInstance().parseFullName(ep1String
+" "+ep2String
+" nothosubsp. "+ep3String
);
417 else if(hybString
.equals(RedListUtil
.HYB_GF
)){
418 if(ep1String
.contains(RedListUtil
.HYB_SIGN
)){
419 name
= NonViralNameParserImpl
.NewInstance().parseFullName(ep1String
);
422 RedListUtil
.logMessage(id
, "HYB is "+hybString
+" but "+RedListUtil
.HYB
+" does not contain "+RedListUtil
.HYB_SIGN
, logger
);
425 else if(hybString
.equals(RedListUtil
.HYB_XS
)){
429 logger
.error("HYB value "+hybString
+" not yet handled");
433 ImportHelper
.setOriginalSource(name
, state
.getTransactionalSourceReference(), id
, RedListUtil
.NAME_NAMESPACE
);
435 namesToSave
.add(name
);
439 private void checkAuthorShipConsistency(long id
, String nomZusatzString
, String taxZusatzString
,
440 String zusatzString
, String authorString
, String authorshipCache
) {
441 if(CdmUtils
.isNotBlank(zusatzString
)){
442 authorString
= authorString
.replace(", "+zusatzString
, "");
444 if(CdmUtils
.isNotBlank(nomZusatzString
)){
445 authorString
= authorString
.replace(", "+nomZusatzString
, "");
447 if(CdmUtils
.isNotBlank(taxZusatzString
)){
448 authorString
= authorString
.replace(", "+taxZusatzString
, "");
450 if(authorString
.equals(RedListUtil
.AUCT
)){
453 if(STRICT_TITLE_CHECK
){
454 if(!authorString
.equals(authorshipCache
)){
455 RedListUtil
.logMessage(id
, "Authorship inconsistent! name.authorhshipCache <-> Column "+RedListUtil
.AUTOR
+": "+authorshipCache
+" <-> "+authorString
, logger
);
459 if(CdmUtils
.isNotBlank(authorString
) && !authorString
.startsWith(authorshipCache
)){
460 RedListUtil
.logMessage(id
, "Authorship inconsistent! name.authorhshipCache <-> Column "+RedListUtil
.AUTOR
+": "+authorshipCache
+" <-> "+authorString
, logger
);
465 private void checkTaxonNameConsistency(long id
, String taxNameString
, String hybString
, TaxonBase
<?
> taxonBase
) {
466 if(hybString
.equals(RedListUtil
.HYB_XF
)){
467 if(HibernateProxyHelper
.deproxy(taxonBase
.getName(),NonViralName
.class).getHybridChildRelations().isEmpty()){
468 RedListUtil
.logMessage(id
, "Hybrid name but no hybrid child relations: "+taxonBase
.getTitleCache(), logger
);
475 String nameCache
= HibernateProxyHelper
.deproxy(taxonBase
.getName(), NonViralName
.class).getNameCache().trim();
476 taxNameString
= taxNameString
.trim();
477 taxNameString
.replaceAll(" +", " ");
479 if(taxNameString
.endsWith("agg.")){
480 taxNameString
= taxNameString
.replace("agg.", "aggr.");
483 if(hybString
.equals(RedListUtil
.HYB_X
)){
484 taxNameString
= taxNameString
.replace(" "+RedListUtil
.HYB_SIGN
+" ", " "+RedListUtil
.HYB_SIGN
);//hybrid sign has no space after it in titleCache for binomial hybrids
485 taxNameString
= taxNameString
.replace(" x ", " "+RedListUtil
.HYB_SIGN
);//in some cases a standard 'x' is used
487 else if(hybString
.equals(RedListUtil
.HYB_G
)){
488 taxNameString
= taxNameString
.replace("X ", RedListUtil
.HYB_SIGN
);
490 else if(hybString
.equals(RedListUtil
.HYB_GF
)){
491 taxNameString
= taxNameString
.replace(" "+RedListUtil
.HYB_SIGN
, " x");
494 if(taxNameString
.endsWith("- Gruppe")){String a
="Festuca ×xx Lolium <-> Festuca ×× Lolium";
495 taxNameString
= taxNameString
.replaceAll("- Gruppe", "species group");
497 if(taxNameString
.endsWith("- group")){
498 taxNameString
= taxNameString
.replaceAll("- group", "species group");
501 taxNameString
= taxNameString
.replace("[ranglos]", "[unranked]");
502 if(STRICT_TITLE_CHECK
){
503 if(!taxNameString
.trim().equals(nameCache
)){
504 RedListUtil
.logMessage(id
, "Taxon name inconsistent! taxon.titleCache <-> Column "+RedListUtil
.TAXNAME
+": "+nameCache
+" <-> "+taxNameString
, logger
);
508 if(!taxNameString
.startsWith(nameCache
)){
509 RedListUtil
.logMessage(id
, "Taxon name inconsistent! taxon.titleCache <-> Column "+RedListUtil
.TAXNAME
+": "+nameCache
+" <-> "+taxNameString
, logger
);
514 private Rank
makeRank(long id
, RedListGefaesspflanzenImportState state
, String rankStr
, boolean hasSpecificEpithet
) {
517 if(rankStr
.equals("ORA")){
518 //special handling for ORA because of two possibilities
519 if(hasSpecificEpithet
){
520 return Rank
.UNRANKED_INFRASPECIFIC();
523 return Rank
.UNRANKED_INFRAGENERIC();
527 rank
= state
.getTransformer().getRankByKey(rankStr
);
529 } catch (UndefinedTransformerMethodException e
) {
533 RedListUtil
.logMessage(id
, rankStr
+" could not be associated to a known rank.", logger
);
538 private NomenclaturalStatusType
makeNomenclaturalStatus(long id
, RedListGefaesspflanzenImportState state
, String nomZusatzString
) {
539 NomenclaturalStatusType status
= null;
541 status
= state
.getTransformer().getNomenclaturalStatusByKey(nomZusatzString
);
542 } catch (UndefinedTransformerMethodException e
) {
546 RedListUtil
.logMessage(id
, nomZusatzString
+" could not be associated to a known nomenclatural status.", logger
);
554 public Map
<Object
, Map
<String
, ?
extends CdmBase
>> getRelatedObjectsForPartition(ResultSet rs
,
555 RedListGefaesspflanzenImportState state
) {
556 Map
<Object
, Map
<String
, ?
extends CdmBase
>> result
= new HashMap
<>();
557 Map
<String
, AgentBase
<?
>> authorMap
= new HashMap
<String
, AgentBase
<?
>>();
561 String authorKombString
= rs
.getString(RedListUtil
.AUTOR_KOMB
);
563 if(authorKombString
.contains(RedListUtil
.EX
)){
564 String
[] kombSplit
= authorKombString
.split(RedListUtil
.EX
);
565 for (int i
= 0; i
< kombSplit
.length
; i
++) {
566 if(!authorMap
.containsKey(kombSplit
[i
])){
567 authorMap
.put(kombSplit
[i
], getAgentService().load(state
.getAuthorMap().get(kombSplit
[i
])));
571 else if(CdmUtils
.isNotBlank(authorKombString
) && !authorMap
.containsKey(authorKombString
)){
572 authorMap
.put(authorKombString
, getAgentService().load(state
.getAuthorMap().get(authorKombString
)));
575 String authorBasiString
= rs
.getString(RedListUtil
.AUTOR_BASI
);
577 if(authorBasiString
.contains(RedListUtil
.EX
)){
578 String
[] basiSplit
= authorBasiString
.split(RedListUtil
.EX
);
579 for (int i
= 0; i
< basiSplit
.length
; i
++) {
580 if(!authorMap
.containsKey(basiSplit
[i
])){
581 authorMap
.put(basiSplit
[i
], getAgentService().load(state
.getAuthorMap().get(basiSplit
[i
])));
585 else if(CdmUtils
.isNotBlank(authorBasiString
) && !authorMap
.containsKey(authorBasiString
)){
586 authorMap
.put(authorBasiString
, getAgentService().load(state
.getAuthorMap().get(authorBasiString
)));
589 } catch (SQLException e
) {
592 result
.put(RedListUtil
.AUTHOR_NAMESPACE
, authorMap
);
598 protected boolean doCheck(RedListGefaesspflanzenImportState state
) {
603 protected boolean isIgnore(RedListGefaesspflanzenImportState state
) {