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
.faunaEuropaea
;
12 import static eu
.etaxonomy
.cdm
.io
.faunaEuropaea
.FaunaEuropaeaTransformer
.A_AUCT
;
13 import static eu
.etaxonomy
.cdm
.io
.faunaEuropaea
.FaunaEuropaeaTransformer
.P_PARENTHESIS
;
14 import static eu
.etaxonomy
.cdm
.io
.faunaEuropaea
.FaunaEuropaeaTransformer
.R_GENUS
;
15 import static eu
.etaxonomy
.cdm
.io
.faunaEuropaea
.FaunaEuropaeaTransformer
.R_SPECIES
;
16 import static eu
.etaxonomy
.cdm
.io
.faunaEuropaea
.FaunaEuropaeaTransformer
.R_SUBGENUS
;
17 import static eu
.etaxonomy
.cdm
.io
.faunaEuropaea
.FaunaEuropaeaTransformer
.R_SUBSPECIES
;
18 import static eu
.etaxonomy
.cdm
.io
.faunaEuropaea
.FaunaEuropaeaTransformer
.T_STATUS_ACCEPTED
;
19 import static eu
.etaxonomy
.cdm
.io
.faunaEuropaea
.FaunaEuropaeaTransformer
.T_STATUS_NOT_ACCEPTED
;
21 import java
.sql
.ResultSet
;
22 import java
.sql
.SQLException
;
23 import java
.util
.ArrayList
;
24 import java
.util
.Collection
;
25 import java
.util
.HashMap
;
26 import java
.util
.HashSet
;
27 import java
.util
.List
;
30 import java
.util
.UUID
;
32 import org
.apache
.log4j
.Logger
;
33 import org
.springframework
.stereotype
.Component
;
34 import org
.springframework
.transaction
.TransactionStatus
;
36 import eu
.etaxonomy
.cdm
.common
.CdmUtils
;
37 import eu
.etaxonomy
.cdm
.io
.common
.ICdmIO
;
38 import eu
.etaxonomy
.cdm
.io
.common
.ImportHelper
;
39 import eu
.etaxonomy
.cdm
.io
.common
.MapWrapper
;
40 import eu
.etaxonomy
.cdm
.io
.common
.Source
;
41 import eu
.etaxonomy
.cdm
.model
.agent
.TeamOrPersonBase
;
42 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
43 import eu
.etaxonomy
.cdm
.model
.common
.IdentifiableSource
;
44 import eu
.etaxonomy
.cdm
.model
.name
.Rank
;
45 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameBase
;
46 import eu
.etaxonomy
.cdm
.model
.name
.ZoologicalName
;
47 import eu
.etaxonomy
.cdm
.model
.reference
.ReferenceBase
;
48 import eu
.etaxonomy
.cdm
.model
.taxon
.Synonym
;
49 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
50 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
51 import eu
.etaxonomy
.cdm
.strategy
.exceptions
.UnknownCdmTypeException
;
55 * @author a.babadshanjan
60 public class FaunaEuropaeaTaxonNameImport
extends FaunaEuropaeaImportBase
{
62 public static final String OS_NAMESPACE_TAXON
= "Taxon";
63 private static final Logger logger
= Logger
.getLogger(FaunaEuropaeaTaxonNameImport
.class);
65 /* Max number of taxa to retrieve (for test purposes) */
66 private int maxTaxa
= 0;
70 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doCheck(eu.etaxonomy.cdm.io.common.IImportConfigurator)
73 protected boolean doCheck(FaunaEuropaeaImportState state
) {
74 boolean result
= true;
75 FaunaEuropaeaImportConfigurator fauEuConfig
= state
.getConfig();
76 logger
.warn("Checking for Taxa not yet fully implemented");
77 result
&= checkTaxonStatus(fauEuConfig
);
83 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IImportConfigurator)
85 protected boolean isIgnore(FaunaEuropaeaImportState state
) {
86 return ! state
.getConfig().isDoTaxa();
89 private boolean checkTaxonStatus(FaunaEuropaeaImportConfigurator fauEuConfig
) {
90 boolean result
= true;
92 Source source
= fauEuConfig
.getSource();
94 ResultSet rs
= source
.getResultSet(sqlStr
);
96 // } catch (SQLException e) {
97 // e.printStackTrace();
103 * Import taxa from FauEU DB
105 protected boolean doInvoke(FaunaEuropaeaImportState state
) {
107 boolean success
= true;
108 if(logger
.isInfoEnabled()) { logger
.info("Start making taxa..."); }
112 success
= processTaxa(state
);
114 logger
.info("End making taxa...");
119 /** Retrieve taxa from FauEu DB, process in blocks */
120 private boolean processTaxa(FaunaEuropaeaImportState state
) {
122 int limit
= state
.getConfig().getLimitSave();
124 TransactionStatus txStatus
= null;
126 Map
<String
, MapWrapper
<?
extends CdmBase
>> stores
= state
.getStores();
127 MapWrapper
<TeamOrPersonBase
> authorStore
= (MapWrapper
<TeamOrPersonBase
>)stores
.get(ICdmIO
.TEAM_STORE
);
129 Map
<Integer
, TaxonBase
<?
>> taxonMap
= null;
130 Map
<Integer
, FaunaEuropaeaTaxon
> fauEuTaxonMap
= null;
131 /* Store for heterotypic synonyms to be save separately */
132 Set
<Synonym
> synonymSet
= null;
134 FaunaEuropaeaImportConfigurator fauEuConfig
= state
.getConfig();
135 ReferenceBase
<?
> sourceRef
= fauEuConfig
.getSourceReference();
137 Source source
= fauEuConfig
.getSource();
139 boolean success
= true;
144 String selectColumns
=
145 " SELECT Parent.TAX_NAME AS P2Name, Parent.TAX_RNK_ID AS P2RankId, " +
146 " GrandParent.TAX_ID AS GP3Id, GrandParent.TAX_NAME AS GP3Name, GrandParent.TAX_RNK_ID AS GP3RankId, " +
147 " GreatGrandParent.TAX_ID AS GGP4Id, GreatGrandParent.TAX_NAME AS GGP4Name, GreatGrandParent.TAX_RNK_ID AS GGP4RankId, " +
148 " GreatGreatGrandParent.TAX_ID AS GGGP5Id, GreatGreatGrandParent.TAX_NAME AS GGGP5Name, GreatGreatGrandParent.TAX_RNK_ID AS GGGP5RankId, " +
149 " OriginalGenusTaxon.TAX_NAME AS OGenusName, " +
150 " GreatGreatGreatGrandParent.TAX_ID AS GGGGP6Id, GreatGreatGreatGrandParent.TAX_NAME AS GGGGP6Name, GreatGreatGreatGrandParent.TAX_RNK_ID AS GGGGP6RankId," +
151 " Taxon.*, rank.*, author.* ";
154 " FROM Taxon LEFT OUTER JOIN " +
155 " Taxon AS Parent ON Taxon.TAX_TAX_IDPARENT = Parent.TAX_ID LEFT OUTER JOIN " +
156 " Taxon AS GrandParent ON Parent.TAX_TAX_IDPARENT = GrandParent.TAX_ID LEFT OUTER JOIN " +
157 " Taxon AS GreatGrandParent ON GrandParent.TAX_TAX_IDPARENT = GreatGrandParent.TAX_ID LEFT OUTER JOIN " +
158 " Taxon AS GreatGreatGrandParent ON GreatGrandParent.TAX_TAX_IDPARENT = GreatGreatGrandParent.TAX_ID LEFT OUTER JOIN " +
159 " Taxon AS GreatGreatGreatGrandParent ON GreatGreatGrandParent.TAX_TAX_IDPARENT = GreatGreatGreatGrandParent.TAX_ID LEFT OUTER JOIN " +
160 " Taxon AS OriginalGenusTaxon ON Taxon.TAX_TAX_IDGENUS = OriginalGenusTaxon.TAX_ID LEFT OUTER JOIN " +
161 " author ON Taxon.TAX_AUT_ID = author.aut_id LEFT OUTER JOIN " +
162 " rank ON Taxon.TAX_RNK_ID = rank.rnk_id ";
165 selectCount
+ fromClause
;
168 selectColumns
+ fromClause
;
173 ResultSet rs
= source
.getResultSet(countQuery
);
175 int count
= rs
.getInt(1);
177 rs
= source
.getResultSet(selectQuery
);
179 if (logger
.isInfoEnabled()) {
180 logger
.info("Number of rows: " + count
);
181 logger
.info("Count Query: " + countQuery
);
182 logger
.info("Select Query: " + selectQuery
);
187 if ((i
++ % limit
) == 0) {
189 txStatus
= startTransaction();
190 taxonMap
= new HashMap
<Integer
, TaxonBase
<?
>>(limit
);
191 fauEuTaxonMap
= new HashMap
<Integer
, FaunaEuropaeaTaxon
>(limit
);
192 synonymSet
= new HashSet
<Synonym
>();
194 if(logger
.isInfoEnabled()) {
195 logger
.info("i = " + i
+ " - Transaction started");
199 String localName
= rs
.getString("TAX_NAME");
200 String parentName
= rs
.getString("P2Name");
201 int grandParentId
= rs
.getInt("GP3Id");
202 String grandParentName
= rs
.getString("GP3Name");
203 int greatGrandParentId
= rs
.getInt("GGP4Id");
204 String greatGrandParentName
= rs
.getString("GGP4Name");
205 int greatGreatGrandParentId
= rs
.getInt("GGGP5Id");
206 String greatGreatGrandParentName
= rs
.getString("GGGP5Name");
207 String greatGreatGreatGrandParentName
= rs
.getString("GGGGP6Name");
208 String originalGenusName
= rs
.getString("OGenusName");
209 String autName
= rs
.getString("aut_name");
210 int taxonId
= rs
.getInt("TAX_ID");
211 int rankId
= rs
.getInt("TAX_RNK_ID");
212 int parentId
= rs
.getInt("TAX_TAX_IDPARENT");
213 int parentRankId
= rs
.getInt("P2RankId");
214 int grandParentRankId
= rs
.getInt("GP3RankId");
215 int greatGrandParentRankId
= rs
.getInt("GGP4RankId");
216 int greatGreatGrandParentRankId
= rs
.getInt("GGGP5RankId");
217 int greatGreatGreatGrandParentRankId
= rs
.getInt("GGGGP6RankId");
218 int originalGenusId
= rs
.getInt("TAX_TAX_IDGENUS");
219 int autId
= rs
.getInt("TAX_AUT_ID");
220 int status
= rs
.getInt("TAX_VALID");
222 // Avoid publication year 0 for NULL values in database.
223 Integer year
= rs
.getInt("TAX_YEAR");
224 if (year
!= null && year
.intValue() == 0) {
228 //int familyId = rs.getInt("TAX_TAX_IDFAMILY");
231 int parenthesis
= rs
.getInt("TAX_PARENTHESIS");
232 UUID taxonBaseUuid
= null;
233 if (resultSetHasColumn(rs
,"UUID")){
234 taxonBaseUuid
= UUID
.fromString(rs
.getString("UUID"));
236 taxonBaseUuid
= UUID
.randomUUID();
239 FaunaEuropaeaTaxon fauEuTaxon
= new FaunaEuropaeaTaxon();
240 fauEuTaxon
.setUuid(taxonBaseUuid
);
241 fauEuTaxon
.setId(taxonId
);
242 fauEuTaxon
.setRankId(rankId
);
243 fauEuTaxon
.setLocalName(localName
);
245 fauEuTaxon
.setParentId(parentId
);
246 fauEuTaxon
.setParentRankId(parentRankId
);
247 fauEuTaxon
.setParentName(parentName
);
249 fauEuTaxon
.setGrandParentId(grandParentId
);
250 fauEuTaxon
.setGrandParentRankId(grandParentRankId
);
251 fauEuTaxon
.setGrandParentName(grandParentName
);
253 fauEuTaxon
.setGreatGrandParentId(greatGrandParentId
);
254 fauEuTaxon
.setGreatGrandParentRankId(greatGrandParentRankId
);
255 fauEuTaxon
.setGreatGrandParentName(greatGrandParentName
);
257 fauEuTaxon
.setGreatGreatGrandParentId(greatGreatGrandParentId
);
258 fauEuTaxon
.setGreatGreatGrandParentRankId(greatGreatGrandParentRankId
);
259 fauEuTaxon
.setGreatGreatGrandParentName(greatGreatGrandParentName
);
261 fauEuTaxon
.setGreatGreatGreatGrandParentRankId(greatGreatGreatGrandParentRankId
);
262 fauEuTaxon
.setGreatGreatGreatGrandParentName(greatGreatGreatGrandParentName
);
264 fauEuTaxon
.setOriginalGenusId(originalGenusId
);
265 fauEuTaxon
.setYear(year
);
266 fauEuTaxon
.setOriginalGenusName(originalGenusName
);
267 fauEuTaxon
.setAuthorName(autName
);
268 if (parenthesis
== P_PARENTHESIS
) {
269 fauEuTaxon
.setParenthesis(true);
271 fauEuTaxon
.setParenthesis(false);
273 if (status
== T_STATUS_ACCEPTED
) {
274 fauEuTaxon
.setValid(true);
276 fauEuTaxon
.setValid(false);
279 // fauEuTaxon.setAuthorId(autId);
282 rank
= FaunaEuropaeaTransformer
.rankId2Rank(rs
, false);
283 } catch (UnknownCdmTypeException e
) {
284 logger
.warn("Taxon (" + taxonId
+ ") has unknown rank (" + rankId
+ ") and could not be saved.");
286 } catch (NullPointerException e
) {
287 logger
.warn("Taxon (" + taxonId
+ ") has rank null and can not be saved.");
291 ReferenceBase
<?
> sourceReference
= fauEuConfig
.getSourceReference();
292 ReferenceBase
<?
> auctReference
= fauEuConfig
.getAuctReference();
294 ZoologicalName zooName
= ZoologicalName
.NewInstance(rank
);
295 TeamOrPersonBase
<?
> author
= authorStore
.get(autId
);
297 zooName
.setCombinationAuthorTeam(author
);
298 zooName
.setPublicationYear(year
);
300 TaxonBase
<?
> taxonBase
;
305 if ((status
== T_STATUS_ACCEPTED
) || (autId
== A_AUCT
)) { // taxon
306 if (autId
== A_AUCT
) { // misapplied name
307 zooName
.setCombinationAuthorTeam(null);
308 zooName
.setPublicationYear(null);
309 taxon
= Taxon
.NewInstance(zooName
, auctReference
);
310 if (logger
.isDebugEnabled()) {
311 logger
.debug("Misapplied name created (" + taxonId
+ ")");
313 } else { // accepted taxon
314 taxon
= Taxon
.NewInstance(zooName
, sourceReference
);
315 if (logger
.isDebugEnabled()) {
316 logger
.debug("Taxon created (" + taxonId
+ ")");
320 } else if ((status
== T_STATUS_NOT_ACCEPTED
) && (autId
!= A_AUCT
)) { // synonym
321 synonym
= Synonym
.NewInstance(zooName
, sourceReference
);
322 //logger.info("Synonym created: " + synonym.getTitleCache() + " taxonName: " + zooName.getTitleCache());
323 if (logger
.isDebugEnabled()) {
324 logger
.debug("Synonym created (" + taxonId
+ ")");
328 logger
.warn("Unknown taxon status " + status
+ ". Taxon (" + taxonId
+ ") ignored.");
332 taxonBase
.setUuid(taxonBaseUuid
);
334 ImportHelper
.setOriginalSource(taxonBase
, fauEuConfig
.getSourceReference(), taxonId
, OS_NAMESPACE_TAXON
);
335 ImportHelper
.setOriginalSource(zooName
, fauEuConfig
.getSourceReference(), taxonId
, "TaxonName");
338 if (!taxonMap
.containsKey(taxonId
)) {
339 if (taxonBase
== null) {
340 if (logger
.isDebugEnabled()) {
341 logger
.debug("Taxon base is null. Taxon (" + taxonId
+ ") ignored.");
345 taxonMap
.put(taxonId
, taxonBase
);
346 fauEuTaxonMap
.put(taxonId
, fauEuTaxon
);
348 // if (logger.isDebugEnabled()) {
349 // logger.debug("Stored taxon base (" + taxonId + ") " + localName);
352 logger
.warn("Not imported taxon base with duplicated TAX_ID (" + taxonId
+
355 } catch (Exception e
) {
356 logger
.warn("An exception occurred when creating taxon base with id " + taxonId
+
357 ". Taxon base could not be saved.");
361 if (((i
% limit
) == 0 && i
!= 1 ) || i
== count
) {
363 success
= processTaxaSecondPass(state
, taxonMap
, fauEuTaxonMap
, synonymSet
);
364 if(logger
.isDebugEnabled()) { logger
.debug("Saving taxa ..."); }
365 getTaxonService().save((Collection
)taxonMap
.values());
366 getTaxonService().save((Collection
)synonymSet
);
370 fauEuTaxonMap
= null;
371 commitTransaction(txStatus
);
373 if(logger
.isInfoEnabled()) {
374 logger
.info("i = " + i
+ " - Transaction committed");
379 } catch (SQLException e
) {
380 logger
.error("SQLException:" + e
);
389 * Processes taxa from complete taxon store
391 private boolean processTaxaSecondPass(FaunaEuropaeaImportState state
, Map
<Integer
, TaxonBase
<?
>> taxonMap
,
392 Map
<Integer
, FaunaEuropaeaTaxon
> fauEuTaxonMap
, Set
<Synonym
> synonymSet
) {
394 if(logger
.isDebugEnabled()) { logger
.debug("Processing taxa second pass..."); }
396 FaunaEuropaeaImportConfigurator fauEuConfig
= state
.getConfig();
398 boolean success
= true;
400 for (int id
: taxonMap
.keySet())
402 if (logger
.isDebugEnabled()) { logger
.debug("Taxon # " + id
); }
404 TaxonBase
<?
> taxonBase
= taxonMap
.get(id
);
405 TaxonNameBase
<?
,?
> taxonName
= taxonBase
.getName();
406 FaunaEuropaeaTaxon fauEuTaxon
= fauEuTaxonMap
.get(id
);
407 boolean useOriginalGenus
= false;
408 if (taxonBase
instanceof Synonym
){
409 useOriginalGenus
= true;
413 buildTaxonName(fauEuTaxon
, taxonBase
, taxonName
, useOriginalGenus
, fauEuConfig
);
415 if (taxonBase
instanceof Synonym
){
416 logger
.info("Name of Synonym: " + nameString
);
419 if (fauEuConfig
.isDoBasionyms()
420 && fauEuTaxon
.getRankId() > R_SUBGENUS
421 && (fauEuTaxon
.getOriginalGenusId() != 0)) {
423 Integer originalGenusId
= fauEuTaxon
.getOriginalGenusId();
424 Integer actualGenusId
= getActualGenusId(fauEuTaxon
);
426 if (logger
.isDebugEnabled()) {
427 logger
.debug("actual genus id = " + actualGenusId
+ ", original genus id = " + originalGenusId
);
430 if (actualGenusId
!= originalGenusId
&& taxonBase
.isInstanceOf(Taxon
.class)) {
431 success
= createBasionym(fauEuTaxon
, taxonBase
, taxonName
, fauEuConfig
, synonymSet
);
432 } else if (fauEuTaxon
.isParenthesis()) {
433 //the authorteam should be set in parenthesis because there should be a basionym, but we do not know it?
434 ZoologicalName zooName
= taxonName
.deproxy(taxonName
, ZoologicalName
.class);
435 zooName
.setBasionymAuthorTeam(zooName
.getCombinationAuthorTeam());
436 zooName
.setCombinationAuthorTeam(null);
437 zooName
.setOriginalPublicationYear(zooName
.getPublicationYear());
438 zooName
.setPublicationYear(null);
447 private boolean createBasionym(FaunaEuropaeaTaxon fauEuTaxon
, TaxonBase
<?
> taxonBase
,
448 TaxonNameBase
<?
,?
>taxonName
, FaunaEuropaeaImportConfigurator fauEuConfig
,
449 Set
<Synonym
> synonymSet
) {
451 boolean success
= true;
454 ZoologicalName zooName
= taxonName
.deproxy(taxonName
, ZoologicalName
.class);
457 ZoologicalName basionym
= ZoologicalName
.NewInstance(taxonName
.getRank());
458 basionym
.setCombinationAuthorTeam(zooName
.getCombinationAuthorTeam());
460 zooName
.setOriginalPublicationYear(zooName
.getPublicationYear());
461 basionym
.setPublicationYear(zooName
.getPublicationYear());
463 // add originalGenusId as source
464 String originalGenusIdString
= "" + fauEuTaxon
.getId();
465 IdentifiableSource basionymSource
= IdentifiableSource
.NewInstance(originalGenusIdString
, "originalGenusId");
466 basionym
.addSource(basionymSource
);
468 // add original database reference
469 ImportHelper
.setOriginalSource(basionym
, fauEuConfig
.getSourceReference(), fauEuTaxon
.getId(), "TaxonName");
471 zooName
.addBasionym(basionym
, fauEuConfig
.getSourceReference(), null, null);
472 zooName
.setBasionymAuthorTeam(zooName
.getCombinationAuthorTeam());
473 zooName
.setCombinationAuthorTeam(null);
474 zooName
.setPublicationYear(null);
475 zooName
.setTitleCache(null); // This should (re)generate the titleCache automagically
476 if (logger
.isDebugEnabled()) {
477 logger
.debug("Basionym created (" + fauEuTaxon
.getId() + ")");
481 Synonym synonym
= Synonym
.NewInstance(basionym
, fauEuConfig
.getSourceReference());
483 if (fauEuTaxon
.isValid()) { // Taxon
486 Taxon taxon
= taxonBase
.deproxy(taxonBase
, Taxon
.class);
487 taxon
.addHomotypicSynonym(synonym
, fauEuConfig
.getSourceReference(), null);
488 if (logger
.isDebugEnabled()) {
489 logger
.debug("Homotypic synonym created (" + fauEuTaxon
.getId() + ")");
494 // heterotypic synonym
495 // synonym relationship to the accepted taxon is created later
496 synonymSet
.add(synonym
);
498 if (logger
.isDebugEnabled()) {
499 logger
.debug("Heterotypic synonym stored (" + fauEuTaxon
.getId() + ")");
504 buildTaxonName(fauEuTaxon
, synonym
, basionym
, true, fauEuConfig
);
505 } catch (Exception e
) {
506 logger
.warn("Exception occurred when creating basionym for " + fauEuTaxon
.getId());
515 /* Build name title cache */
516 private String
buildNameTitleCache(String nameString
, boolean useOriginalGenus
, FaunaEuropaeaTaxon fauEuTaxon
) {
518 StringBuilder titleCacheStringBuilder
= new StringBuilder(nameString
);
519 Integer year
= fauEuTaxon
.getYear();
520 if (year
!= null) { // TODO: Ignore authors like xp, xf, etc?
521 titleCacheStringBuilder
.append(" ");
522 if ((fauEuTaxon
.isParenthesis() == true) && !useOriginalGenus
) {
523 titleCacheStringBuilder
.append("(");
525 titleCacheStringBuilder
.append(fauEuTaxon
.getAuthor());
526 titleCacheStringBuilder
.append(" ");
527 titleCacheStringBuilder
.append(year
);
528 if ((fauEuTaxon
.isParenthesis() == true) && !useOriginalGenus
) {
529 titleCacheStringBuilder
.append(")");
532 return titleCacheStringBuilder
.toString();
536 /* Build taxon title cache */
537 private String
buildTaxonTitleCache(String nameCache
, ReferenceBase
<?
> reference
) {
539 StringBuilder titleCacheStringBuilder
= new StringBuilder(nameCache
);
540 titleCacheStringBuilder
.append(" sec. ");
541 titleCacheStringBuilder
.append(reference
.getTitleCache());
542 return titleCacheStringBuilder
.toString();
546 /* Build name full title cache */
547 private String
buildNameFullTitleCache(String titleCache
, FaunaEuropaeaImportConfigurator fauEuConfig
) {
549 StringBuilder fullTitleCacheStringBuilder
= new StringBuilder(titleCache
);
550 fullTitleCacheStringBuilder
.append(" ");
551 fullTitleCacheStringBuilder
.append(fauEuConfig
.getSourceReferenceTitle());
552 return fullTitleCacheStringBuilder
.toString();
556 private String
genusPart(StringBuilder originalGenusName
, boolean useOriginalGenus
,
557 StringBuilder genusOrUninomial
) {
559 StringBuilder stringBuilder
= new StringBuilder();
561 if(useOriginalGenus
) {
562 stringBuilder
.append(originalGenusName
);
563 genusOrUninomial
.delete(0, genusOrUninomial
.length());
564 genusOrUninomial
.append(originalGenusName
);
566 stringBuilder
.append(genusOrUninomial
);
568 stringBuilder
.append(" ");
570 return stringBuilder
.toString();
574 private String
genusSubGenusPart(StringBuilder originalGenusName
, boolean useOriginalGenus
,
575 StringBuilder genusOrUninomial
,
576 StringBuilder infraGenericEpithet
,
577 FaunaEuropaeaTaxon fauEuTaxon
) {
579 StringBuilder stringBuilder
= new StringBuilder();
581 stringBuilder
.append(genusPart(originalGenusName
, useOriginalGenus
, genusOrUninomial
));
583 // The infraGenericEpithet is set to empty only if the original genus should be used and
584 // the actualGenusId is not the originalGenusId.
585 // This differentiation is relevant for synonyms and for basionyms.
586 // InfraGenericEpithets of accepted taxa are not touched at all.
587 Integer originalGenusId
= fauEuTaxon
.getOriginalGenusId();
588 Integer actualGenusId
= getActualGenusId(fauEuTaxon
);
589 if (useOriginalGenus
&& originalGenusId
!= actualGenusId
&&
590 originalGenusId
.intValue() > 0 &&
591 actualGenusId
.intValue() > 0) {
592 infraGenericEpithet
.delete(0, infraGenericEpithet
.length());
593 stringBuilder
.append(" ");
594 return stringBuilder
.toString();
597 stringBuilder
.append("(");
598 stringBuilder
.append(infraGenericEpithet
);
599 stringBuilder
.append(")");
600 stringBuilder
.append(" ");
602 return stringBuilder
.toString();
605 /** Get actual genus id **/
606 private Integer
getActualGenusId(FaunaEuropaeaTaxon fauEuTaxon
) {
607 Integer actualGenusId
= null;
608 HashMap
<Integer
, Integer
> ranks
= new HashMap
<Integer
, Integer
>();
609 ranks
.put(fauEuTaxon
.getParentRankId(), fauEuTaxon
.getParentId());
610 ranks
.put(fauEuTaxon
.getGrandParentRankId(), fauEuTaxon
.getGrandParentId());
611 ranks
.put(fauEuTaxon
.getGreatGrandParentRankId(), fauEuTaxon
.getGreatGrandParentId());
612 ranks
.put(fauEuTaxon
.getGreatGreatGrandParentRankId(), fauEuTaxon
.getGreatGreatGrandParentId());
613 ranks
.put(fauEuTaxon
.getGreatGreatGreatGrandParentRankId(), fauEuTaxon
.getGreatGreatGreatGrandParentId());
615 actualGenusId
= ranks
.get(R_GENUS
);
617 return actualGenusId
;
621 /** Build species and subspecies names */
622 private String
buildLowerTaxonName(StringBuilder originalGenus
, boolean useOriginalGenus
,
623 StringBuilder genusOrUninomial
, StringBuilder infraGenericEpithet
,
624 StringBuilder specificEpithet
, StringBuilder infraSpecificEpithet
,
625 FaunaEuropaeaTaxon fauEuTaxon
) {
627 // species or subspecies name
628 String localName
= fauEuTaxon
.getLocalName();
629 int taxonId
= fauEuTaxon
.getId();
630 int parentId
= fauEuTaxon
.getParentId();
631 StringBuilder nameCacheStringBuilder
= new StringBuilder();
633 // FaunaEuropaeaTaxon parent = fauEuTaxonMap.get(parentId);
635 nameCacheStringBuilder
.append(localName
);
636 if (logger
.isInfoEnabled()) {
637 logger
.info("Parent of (" + taxonId
+ ") is null");
639 return nameCacheStringBuilder
.toString();
642 String parentName
= fauEuTaxon
.getParentName();
643 String grandParentName
= fauEuTaxon
.getGrandParentName();
644 String greatGrandParentName
= fauEuTaxon
.getGreatGrandParentName();
645 int rank
= fauEuTaxon
.getRankId();
646 int parentRankId
= fauEuTaxon
.getParentRankId();
647 int grandParentRankId
= fauEuTaxon
.getGrandParentRankId();
648 int greatGrandParentRankId
= fauEuTaxon
.getGreatGrandParentRankId();
649 // int grandParentId = fauEuTaxon.getGrandParentId();
650 // int greatGrandParentId = grandParent.getParentId();
653 if (fauEuTaxon
.isValid()) { // Taxon
655 if (rank
== R_SPECIES
) {
657 if(parentRankId
== R_SUBGENUS
) {
658 //differ between isParanthesis= true and false
659 String genusSubGenusPart
= genusSubGenusPart(originalGenus
, useOriginalGenus
,
660 genusOrUninomial
.append(grandParentName
),
661 infraGenericEpithet
.append(parentName
),
663 nameCacheStringBuilder
.append(genusSubGenusPart
);
666 } else if(parentRankId
== R_GENUS
) {
668 String genusPart
= genusPart(originalGenus
, useOriginalGenus
,
669 genusOrUninomial
.append(parentName
));
670 nameCacheStringBuilder
.append(genusPart
);
672 nameCacheStringBuilder
.append(localName
);
673 specificEpithet
.append(localName
);
675 } else if (rank
== R_SUBSPECIES
) {
677 if(grandParentRankId
== R_SUBGENUS
) {
679 String genusSubGenusPart
= genusSubGenusPart(originalGenus
, useOriginalGenus
,
680 genusOrUninomial
.append(greatGrandParentName
),
681 infraGenericEpithet
.append(grandParentName
),
683 nameCacheStringBuilder
.append(genusSubGenusPart
);
685 } else if (grandParentRankId
== R_GENUS
) {
687 String genusPart
= genusPart(originalGenus
, useOriginalGenus
,
688 genusOrUninomial
.append(grandParentName
));
689 nameCacheStringBuilder
.append(genusPart
);
692 nameCacheStringBuilder
.append(parentName
);
693 nameCacheStringBuilder
.append(" ");
694 nameCacheStringBuilder
.append(localName
);
695 specificEpithet
.append(parentName
);
696 infraSpecificEpithet
.append(localName
);
700 if (rank
== R_SPECIES
) {
702 if(grandParentRankId
== R_SUBGENUS
) {
704 String genusSubGenusPart
= genusSubGenusPart(originalGenus
, useOriginalGenus
,
705 genusOrUninomial
.append(greatGrandParentName
),
706 infraGenericEpithet
.append(grandParentName
),
708 nameCacheStringBuilder
.append(genusSubGenusPart
);
710 } else if (grandParentRankId
== R_GENUS
) {
712 String genusPart
= genusPart(originalGenus
, useOriginalGenus
,
713 genusOrUninomial
.append(grandParentName
));
714 nameCacheStringBuilder
.append(genusPart
);
717 nameCacheStringBuilder
.append(localName
);
718 specificEpithet
.append(localName
);
720 } else if (rank
== R_SUBSPECIES
) {
722 String greatGreatGrandParentName
= fauEuTaxon
.getGreatGreatGrandParentName();
724 if(greatGrandParentRankId
== R_SUBGENUS
) {
726 String genusSubGenusPart
= genusSubGenusPart(originalGenus
, useOriginalGenus
,
727 genusOrUninomial
.append(greatGreatGrandParentName
),
728 infraGenericEpithet
.append(greatGrandParentName
),
730 nameCacheStringBuilder
.append(genusSubGenusPart
);
732 } else if (greatGrandParentRankId
== R_GENUS
) {
734 String genusPart
= genusPart(originalGenus
, useOriginalGenus
,
735 genusOrUninomial
.append(greatGreatGrandParentName
));
736 nameCacheStringBuilder
.append(genusPart
);
739 nameCacheStringBuilder
.append(grandParentName
);
740 nameCacheStringBuilder
.append(" ");
741 specificEpithet
.append(grandParentName
);
742 nameCacheStringBuilder
.append(localName
);
743 infraSpecificEpithet
.append(localName
);
750 return nameCacheStringBuilder
.toString();
754 /** Build taxon's name parts and caches */
755 private String
buildTaxonName(FaunaEuropaeaTaxon fauEuTaxon
, TaxonBase
<?
> taxonBase
, TaxonNameBase
<?
,?
>taxonName
,
756 boolean useOriginalGenus
, FaunaEuropaeaImportConfigurator fauEuConfig
) {
758 /* Local taxon name string */
759 String localString
= "";
760 /* Concatenated taxon name string */
761 String completeString
= "";
763 StringBuilder originalGenus
= new StringBuilder("");
765 StringBuilder genusOrUninomial
= new StringBuilder();
766 StringBuilder infraGenericEpithet
= new StringBuilder();
767 StringBuilder specificEpithet
= new StringBuilder();
768 StringBuilder infraSpecificEpithet
= new StringBuilder();
770 localString
= fauEuTaxon
.getLocalName();
771 int rank
= fauEuTaxon
.getRankId();
773 // determine genus: this also works for cases of synonyms since the accepted taxon is its parent
774 String originalGenusString
= null;
775 if (useOriginalGenus
&& ! "".equals(fauEuTaxon
.getOriginalGenusName())) {
776 originalGenusString
= fauEuTaxon
.getOriginalGenusName();
778 originalGenusString
= determineOriginalGenus(fauEuTaxon
);
781 if (originalGenusString
!= null) {
782 originalGenus
= new StringBuilder(originalGenusString
);
785 if(logger
.isDebugEnabled()) {
786 logger
.debug("Local taxon name (rank = " + rank
+ "): " + localString
);
789 if (rank
< R_SPECIES
) {
792 completeString
= localString
;
793 if (rank
== R_SUBGENUS
) {
795 infraGenericEpithet
.append(localString
);
798 genusOrUninomial
.append(originalGenus
);
800 completeString
= originalGenus
+ " ("+ localString
+ ")";
803 genusOrUninomial
.append(localString
);
809 taxonBase
= taxonBase
.deproxy(taxonBase
, TaxonBase
.class);
812 buildLowerTaxonName(originalGenus
, useOriginalGenus
,
813 genusOrUninomial
, infraGenericEpithet
, specificEpithet
, infraSpecificEpithet
,
816 completeString
= (String
) CdmUtils
.removeDuplicateWhitespace(completeString
.trim());
819 return setCompleteTaxonName(completeString
, useOriginalGenus
,
820 genusOrUninomial
.toString(), infraGenericEpithet
.toString(),
821 specificEpithet
.toString(), infraSpecificEpithet
.toString(),
822 fauEuTaxon
, taxonBase
, fauEuConfig
);
828 * Determines the original genus name by searching the taxon with rank Genus.
832 private String
determineOriginalGenus(FaunaEuropaeaTaxon fauEuTaxon
) {
833 String originalGenus
= null;
835 HashMap
<Integer
, String
> ranks
= new HashMap
<Integer
, String
>();
836 ranks
.put(fauEuTaxon
.getParentRankId(), fauEuTaxon
.getParentName());
837 ranks
.put(fauEuTaxon
.getGrandParentRankId(), fauEuTaxon
.getGrandParentName());
838 ranks
.put(fauEuTaxon
.getGreatGrandParentRankId(), fauEuTaxon
.getGreatGrandParentName());
839 ranks
.put(fauEuTaxon
.getGreatGreatGrandParentRankId(), fauEuTaxon
.getGreatGreatGrandParentName());
840 ranks
.put(fauEuTaxon
.getGreatGreatGreatGrandParentRankId(), fauEuTaxon
.getGreatGreatGreatGrandParentName());
842 originalGenus
= ranks
.get(R_GENUS
);
844 return originalGenus
;
847 /** Sets name parts and caches */
848 private String
setCompleteTaxonName(String concatString
, boolean useOriginalGenus
,
849 String genusOrUninomial
, String infraGenericEpithet
, String specificEpithet
, String infraSpecificEpithet
,
850 FaunaEuropaeaTaxon fauEuTaxon
, TaxonBase
<?
> taxonBase
, FaunaEuropaeaImportConfigurator fauEuConfig
) {
852 boolean success
= true;
854 TaxonNameBase
<?
,?
> taxonName
= taxonBase
.getName();
855 ZoologicalName zooName
= (ZoologicalName
)taxonName
;
857 if (!genusOrUninomial
.equals("")) {
858 zooName
.setGenusOrUninomial(emptyToNull(genusOrUninomial
));
859 if (logger
.isDebugEnabled()) {
860 logger
.debug("genusOrUninomial: " + genusOrUninomial
);
864 //if ((!infraGenericEpithet.equals("") && fauEuTaxon.isParenthesis()) || (!infraGenericEpithet.equals("") && fauEuTaxon.)) {
865 if (fauEuTaxon
.getParentRankId() == R_SUBGENUS
|| fauEuTaxon
.getRankId() == R_SUBGENUS
||
866 fauEuTaxon
.getGrandParentRankId() == R_SUBGENUS
|| fauEuTaxon
.getGreatGrandParentRankId() == R_SUBGENUS
) {
867 zooName
.setInfraGenericEpithet(emptyToNull(infraGenericEpithet
));
868 if (logger
.isDebugEnabled()) {
869 logger
.debug("infraGenericEpithet: " + infraGenericEpithet
);
872 if ((fauEuTaxon
.getRankId() == R_SPECIES
|| fauEuTaxon
.getRankId() == R_SUBSPECIES
)) {
873 zooName
.setSpecificEpithet(emptyToNull(specificEpithet
));
874 if (logger
.isDebugEnabled()) {
875 logger
.debug("specificEpithet: " + specificEpithet
);
878 if (fauEuTaxon
.getRankId() == R_SUBSPECIES
) {
879 zooName
.setInfraSpecificEpithet(emptyToNull(infraSpecificEpithet
));
880 if (logger
.isDebugEnabled()) {
881 logger
.debug("infraSpecificEpithet: " + infraSpecificEpithet
);
884 //TODO: use generate NameCache
885 //zooName.setNameCache(concatString);
886 String result
= zooName
.getNameCache();
887 // zooName.generateTitle();
888 //String titleCache = buildNameTitleCache(concatString, useOriginalGenus, fauEuTaxon);
889 //zooName.setTitleCache(titleCache);
890 //titleCache = buildNameFullTitleCache(concatString, fauEuConfig);
891 // zooName.generateFullTitle();
892 //zooName.setFullTitleCache(titleCache); // TODO: Add reference, NC status
894 // ImportHelper.setOriginalSource(taxonName, fauEuConfig.getSourceReference(),
895 // fauEuTaxon.getId(), "TaxonName");
896 // taxonBase.setSec(fauEuConfig.getSourceReference());
897 // taxonBase.generateTitle();
898 //titleCache = buildTaxonTitleCache(concatString, fauEuConfig.getSourceReference());
899 //taxonBase.setTitleCache(titleCache);
901 if (logger
.isDebugEnabled()) {
902 logger
.debug("Name stored: " + result
);
908 * Ensures that empty strings are translated to null.
909 * @param genusOrUninomial
912 private String
emptyToNull(String text
) {
913 if (CdmUtils
.isEmpty(text
)) {