(no commit message)
[cdmlib.git] / cdmlib-io / src / main / java / eu / etaxonomy / cdm / io / faunaEuropaea / FaunaEuropaeaTaxonNameImport.java
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.faunaEuropaea;
11
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;
20
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;
28 import java.util.Map;
29 import java.util.Set;
30 import java.util.UUID;
31
32 import org.apache.log4j.Logger;
33 import org.springframework.stereotype.Component;
34 import org.springframework.transaction.TransactionStatus;
35
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;
52
53
54 /**
55 * @author a.babadshanjan
56 * @created 12.05.2009
57 * @version 1.0
58 */
59 @Component
60 public class FaunaEuropaeaTaxonNameImport extends FaunaEuropaeaImportBase {
61
62 public static final String OS_NAMESPACE_TAXON = "Taxon";
63 private static final Logger logger = Logger.getLogger(FaunaEuropaeaTaxonNameImport.class);
64
65 /* Max number of taxa to retrieve (for test purposes) */
66 private int maxTaxa = 0;
67
68
69 /* (non-Javadoc)
70 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doCheck(eu.etaxonomy.cdm.io.common.IImportConfigurator)
71 */
72 @Override
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);
78
79 return result;
80 }
81
82 /* (non-Javadoc)
83 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IImportConfigurator)
84 */
85 protected boolean isIgnore(FaunaEuropaeaImportState state) {
86 return ! state.getConfig().isDoTaxa();
87 }
88
89 private boolean checkTaxonStatus(FaunaEuropaeaImportConfigurator fauEuConfig) {
90 boolean result = true;
91 // try {
92 Source source = fauEuConfig.getSource();
93 String sqlStr = "";
94 ResultSet rs = source.getResultSet(sqlStr);
95 return result;
96 // } catch (SQLException e) {
97 // e.printStackTrace();
98 // return false;
99 // }
100 }
101
102 /**
103 * Import taxa from FauEU DB
104 */
105 protected boolean doInvoke(FaunaEuropaeaImportState state) {
106
107 boolean success = true;
108 if(logger.isInfoEnabled()) { logger.info("Start making taxa..."); }
109
110
111
112 success = processTaxa(state);
113
114 logger.info("End making taxa...");
115 return success;
116 }
117
118
119 /** Retrieve taxa from FauEu DB, process in blocks */
120 private boolean processTaxa(FaunaEuropaeaImportState state) {
121
122 int limit = state.getConfig().getLimitSave();
123
124 TransactionStatus txStatus = null;
125
126 Map<String, MapWrapper<? extends CdmBase>> stores = state.getStores();
127 MapWrapper<TeamOrPersonBase> authorStore = (MapWrapper<TeamOrPersonBase>)stores.get(ICdmIO.TEAM_STORE);
128
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;
133
134 FaunaEuropaeaImportConfigurator fauEuConfig = state.getConfig();
135 ReferenceBase<?> sourceRef = fauEuConfig.getSourceReference();
136
137 Source source = fauEuConfig.getSource();
138 int i = 0;
139 boolean success = true;
140
141 String selectCount =
142 " SELECT count(*) ";
143
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.* ";
152
153 String fromClause =
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 ";
163
164 String countQuery =
165 selectCount + fromClause;
166
167 String selectQuery =
168 selectColumns + fromClause;
169
170
171 try {
172
173 ResultSet rs = source.getResultSet(countQuery);
174 rs.next();
175 int count = rs.getInt(1);
176
177 rs = source.getResultSet(selectQuery);
178
179 if (logger.isInfoEnabled()) {
180 logger.info("Number of rows: " + count);
181 logger.info("Count Query: " + countQuery);
182 logger.info("Select Query: " + selectQuery);
183 }
184
185 while (rs.next()) {
186
187 if ((i++ % limit) == 0) {
188
189 txStatus = startTransaction();
190 taxonMap = new HashMap<Integer, TaxonBase<?>>(limit);
191 fauEuTaxonMap = new HashMap<Integer, FaunaEuropaeaTaxon>(limit);
192 synonymSet = new HashSet<Synonym>();
193
194 if(logger.isInfoEnabled()) {
195 logger.info("i = " + i + " - Transaction started");
196 }
197 }
198
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");
221
222 // Avoid publication year 0 for NULL values in database.
223 Integer year = rs.getInt("TAX_YEAR");
224 if (year != null && year.intValue() == 0) {
225 year = null;
226 }
227
228 //int familyId = rs.getInt("TAX_TAX_IDFAMILY");
229
230 Rank rank = null;
231 int parenthesis = rs.getInt("TAX_PARENTHESIS");
232 UUID taxonBaseUuid = null;
233 if (resultSetHasColumn(rs,"UUID")){
234 taxonBaseUuid = UUID.fromString(rs.getString("UUID"));
235 } else {
236 taxonBaseUuid = UUID.randomUUID();
237 }
238
239 FaunaEuropaeaTaxon fauEuTaxon = new FaunaEuropaeaTaxon();
240 fauEuTaxon.setUuid(taxonBaseUuid);
241 fauEuTaxon.setId(taxonId);
242 fauEuTaxon.setRankId(rankId);
243 fauEuTaxon.setLocalName(localName);
244
245 fauEuTaxon.setParentId(parentId);
246 fauEuTaxon.setParentRankId(parentRankId);
247 fauEuTaxon.setParentName(parentName);
248
249 fauEuTaxon.setGrandParentId(grandParentId);
250 fauEuTaxon.setGrandParentRankId(grandParentRankId);
251 fauEuTaxon.setGrandParentName(grandParentName);
252
253 fauEuTaxon.setGreatGrandParentId(greatGrandParentId);
254 fauEuTaxon.setGreatGrandParentRankId(greatGrandParentRankId);
255 fauEuTaxon.setGreatGrandParentName(greatGrandParentName);
256
257 fauEuTaxon.setGreatGreatGrandParentId(greatGreatGrandParentId);
258 fauEuTaxon.setGreatGreatGrandParentRankId(greatGreatGrandParentRankId);
259 fauEuTaxon.setGreatGreatGrandParentName(greatGreatGrandParentName);
260
261 fauEuTaxon.setGreatGreatGreatGrandParentRankId(greatGreatGreatGrandParentRankId);
262 fauEuTaxon.setGreatGreatGreatGrandParentName(greatGreatGreatGrandParentName);
263
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);
270 } else {
271 fauEuTaxon.setParenthesis(false);
272 }
273 if (status == T_STATUS_ACCEPTED) {
274 fauEuTaxon.setValid(true);
275 } else {
276 fauEuTaxon.setValid(false);
277 }
278
279 // fauEuTaxon.setAuthorId(autId);
280
281 try {
282 rank = FaunaEuropaeaTransformer.rankId2Rank(rs, false);
283 } catch (UnknownCdmTypeException e) {
284 logger.warn("Taxon (" + taxonId + ") has unknown rank (" + rankId + ") and could not be saved.");
285 continue;
286 } catch (NullPointerException e) {
287 logger.warn("Taxon (" + taxonId + ") has rank null and can not be saved.");
288 continue;
289 }
290
291 ReferenceBase<?> sourceReference = fauEuConfig.getSourceReference();
292 ReferenceBase<?> auctReference = fauEuConfig.getAuctReference();
293
294 ZoologicalName zooName = ZoologicalName.NewInstance(rank);
295 TeamOrPersonBase<?> author = authorStore.get(autId);
296
297 zooName.setCombinationAuthorTeam(author);
298 zooName.setPublicationYear(year);
299
300 TaxonBase<?> taxonBase;
301
302 Synonym synonym;
303 Taxon taxon;
304 try {
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 + ")");
312 }
313 } else { // accepted taxon
314 taxon = Taxon.NewInstance(zooName, sourceReference);
315 if (logger.isDebugEnabled()) {
316 logger.debug("Taxon created (" + taxonId + ")");
317 }
318 }
319 taxonBase = taxon;
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 + ")");
325 }
326 taxonBase = synonym;
327 } else {
328 logger.warn("Unknown taxon status " + status + ". Taxon (" + taxonId + ") ignored.");
329 continue;
330 }
331
332 taxonBase.setUuid(taxonBaseUuid);
333
334 ImportHelper.setOriginalSource(taxonBase, fauEuConfig.getSourceReference(), taxonId, OS_NAMESPACE_TAXON);
335 ImportHelper.setOriginalSource(zooName, fauEuConfig.getSourceReference(), taxonId, "TaxonName");
336
337
338 if (!taxonMap.containsKey(taxonId)) {
339 if (taxonBase == null) {
340 if (logger.isDebugEnabled()) {
341 logger.debug("Taxon base is null. Taxon (" + taxonId + ") ignored.");
342 }
343 continue;
344 }
345 taxonMap.put(taxonId, taxonBase);
346 fauEuTaxonMap.put(taxonId, fauEuTaxon);
347
348 // if (logger.isDebugEnabled()) {
349 // logger.debug("Stored taxon base (" + taxonId + ") " + localName);
350 // }
351 } else {
352 logger.warn("Not imported taxon base with duplicated TAX_ID (" + taxonId +
353 ") " + localName);
354 }
355 } catch (Exception e) {
356 logger.warn("An exception occurred when creating taxon base with id " + taxonId +
357 ". Taxon base could not be saved.");
358 e.printStackTrace();
359 }
360
361 if (((i % limit) == 0 && i != 1 ) || i == count) {
362
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);
367
368 taxonMap = null;
369 synonymSet = null;
370 fauEuTaxonMap = null;
371 commitTransaction(txStatus);
372
373 if(logger.isInfoEnabled()) {
374 logger.info("i = " + i + " - Transaction committed");
375 }
376 }
377
378 }
379 } catch (SQLException e) {
380 logger.error("SQLException:" + e);
381 success = false;
382 }
383
384 return success;
385 }
386
387
388 /**
389 * Processes taxa from complete taxon store
390 */
391 private boolean processTaxaSecondPass(FaunaEuropaeaImportState state, Map<Integer, TaxonBase<?>> taxonMap,
392 Map<Integer, FaunaEuropaeaTaxon> fauEuTaxonMap, Set<Synonym> synonymSet) {
393
394 if(logger.isDebugEnabled()) { logger.debug("Processing taxa second pass..."); }
395
396 FaunaEuropaeaImportConfigurator fauEuConfig = state.getConfig();
397
398 boolean success = true;
399
400 for (int id : taxonMap.keySet())
401 {
402 if (logger.isDebugEnabled()) { logger.debug("Taxon # " + id); }
403
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;
410 }
411
412 String nameString =
413 buildTaxonName(fauEuTaxon, taxonBase, taxonName, useOriginalGenus, fauEuConfig);
414
415 if (taxonBase instanceof Synonym){
416 logger.info("Name of Synonym: " + nameString);
417 }
418
419 if (fauEuConfig.isDoBasionyms()
420 && fauEuTaxon.getRankId() > R_SUBGENUS
421 && (fauEuTaxon.getOriginalGenusId() != 0)) {
422
423 Integer originalGenusId = fauEuTaxon.getOriginalGenusId();
424 Integer actualGenusId = getActualGenusId(fauEuTaxon);
425
426 if (logger.isDebugEnabled()) {
427 logger.debug("actual genus id = " + actualGenusId + ", original genus id = " + originalGenusId);
428 }
429
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);
439 }
440
441 }
442 }
443 return success;
444 }
445
446
447 private boolean createBasionym(FaunaEuropaeaTaxon fauEuTaxon, TaxonBase<?> taxonBase,
448 TaxonNameBase<?,?>taxonName, FaunaEuropaeaImportConfigurator fauEuConfig,
449 Set<Synonym> synonymSet) {
450
451 boolean success = true;
452
453 try {
454 ZoologicalName zooName = taxonName.deproxy(taxonName, ZoologicalName.class);
455
456 // create basionym
457 ZoologicalName basionym = ZoologicalName.NewInstance(taxonName.getRank());
458 basionym.setCombinationAuthorTeam(zooName.getCombinationAuthorTeam());
459
460 zooName.setOriginalPublicationYear(zooName.getPublicationYear());
461 basionym.setPublicationYear(zooName.getPublicationYear());
462
463 // add originalGenusId as source
464 String originalGenusIdString = "" + fauEuTaxon.getId();
465 IdentifiableSource basionymSource = IdentifiableSource.NewInstance(originalGenusIdString, "originalGenusId");
466 basionym.addSource(basionymSource);
467
468 // add original database reference
469 ImportHelper.setOriginalSource(basionym, fauEuConfig.getSourceReference(), fauEuTaxon.getId(), "TaxonName");
470
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() + ")");
478 }
479
480 // create synonym
481 Synonym synonym = Synonym.NewInstance(basionym, fauEuConfig.getSourceReference());
482
483 if (fauEuTaxon.isValid()) { // Taxon
484
485 // homotypic synonym
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() + ")");
490 }
491
492 } else { // Synonym
493
494 // heterotypic synonym
495 // synonym relationship to the accepted taxon is created later
496 synonymSet.add(synonym);
497
498 if (logger.isDebugEnabled()) {
499 logger.debug("Heterotypic synonym stored (" + fauEuTaxon.getId() + ")");
500 }
501 }
502
503
504 buildTaxonName(fauEuTaxon, synonym, basionym, true, fauEuConfig);
505 } catch (Exception e) {
506 logger.warn("Exception occurred when creating basionym for " + fauEuTaxon.getId());
507 e.printStackTrace();
508 }
509
510
511 return success;
512 }
513
514
515 /* Build name title cache */
516 private String buildNameTitleCache(String nameString, boolean useOriginalGenus, FaunaEuropaeaTaxon fauEuTaxon) {
517
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("(");
524 }
525 titleCacheStringBuilder.append(fauEuTaxon.getAuthor());
526 titleCacheStringBuilder.append(" ");
527 titleCacheStringBuilder.append(year);
528 if ((fauEuTaxon.isParenthesis() == true) && !useOriginalGenus) {
529 titleCacheStringBuilder.append(")");
530 }
531 }
532 return titleCacheStringBuilder.toString();
533 }
534
535
536 /* Build taxon title cache */
537 private String buildTaxonTitleCache(String nameCache, ReferenceBase<?> reference) {
538
539 StringBuilder titleCacheStringBuilder = new StringBuilder(nameCache);
540 titleCacheStringBuilder.append(" sec. ");
541 titleCacheStringBuilder.append(reference.getTitleCache());
542 return titleCacheStringBuilder.toString();
543 }
544
545
546 /* Build name full title cache */
547 private String buildNameFullTitleCache(String titleCache, FaunaEuropaeaImportConfigurator fauEuConfig) {
548
549 StringBuilder fullTitleCacheStringBuilder = new StringBuilder(titleCache);
550 fullTitleCacheStringBuilder.append(" ");
551 fullTitleCacheStringBuilder.append(fauEuConfig.getSourceReferenceTitle());
552 return fullTitleCacheStringBuilder.toString();
553 }
554
555
556 private String genusPart(StringBuilder originalGenusName, boolean useOriginalGenus,
557 StringBuilder genusOrUninomial) {
558
559 StringBuilder stringBuilder = new StringBuilder();
560
561 if(useOriginalGenus) {
562 stringBuilder.append(originalGenusName);
563 genusOrUninomial.delete(0, genusOrUninomial.length());
564 genusOrUninomial.append(originalGenusName);
565 } else {
566 stringBuilder.append(genusOrUninomial);
567 }
568 stringBuilder.append(" ");
569
570 return stringBuilder.toString();
571 }
572
573
574 private String genusSubGenusPart(StringBuilder originalGenusName, boolean useOriginalGenus,
575 StringBuilder genusOrUninomial,
576 StringBuilder infraGenericEpithet,
577 FaunaEuropaeaTaxon fauEuTaxon) {
578
579 StringBuilder stringBuilder = new StringBuilder();
580
581 stringBuilder.append(genusPart(originalGenusName, useOriginalGenus, genusOrUninomial));
582
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();
595 }
596
597 stringBuilder.append("(");
598 stringBuilder.append(infraGenericEpithet);
599 stringBuilder.append(")");
600 stringBuilder.append(" ");
601
602 return stringBuilder.toString();
603 }
604
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());
614
615 actualGenusId = ranks.get(R_GENUS);
616
617 return actualGenusId;
618 }
619
620
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) {
626
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();
632
633 // FaunaEuropaeaTaxon parent = fauEuTaxonMap.get(parentId);
634 if (parentId == 0) {
635 nameCacheStringBuilder.append(localName);
636 if (logger.isInfoEnabled()) {
637 logger.info("Parent of (" + taxonId + ") is null");
638 }
639 return nameCacheStringBuilder.toString();
640 }
641
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();
651
652
653 if (fauEuTaxon.isValid()) { // Taxon
654
655 if (rank == R_SPECIES) {
656
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),
662 fauEuTaxon);
663 nameCacheStringBuilder.append(genusSubGenusPart);
664
665
666 } else if(parentRankId == R_GENUS) {
667
668 String genusPart = genusPart(originalGenus, useOriginalGenus,
669 genusOrUninomial.append(parentName));
670 nameCacheStringBuilder.append(genusPart);
671 }
672 nameCacheStringBuilder.append(localName);
673 specificEpithet.append(localName);
674
675 } else if (rank == R_SUBSPECIES) {
676
677 if(grandParentRankId == R_SUBGENUS) {
678
679 String genusSubGenusPart = genusSubGenusPart(originalGenus, useOriginalGenus,
680 genusOrUninomial.append(greatGrandParentName),
681 infraGenericEpithet.append(grandParentName),
682 fauEuTaxon);
683 nameCacheStringBuilder.append(genusSubGenusPart);
684
685 } else if (grandParentRankId == R_GENUS) {
686
687 String genusPart = genusPart(originalGenus, useOriginalGenus,
688 genusOrUninomial.append(grandParentName));
689 nameCacheStringBuilder.append(genusPart);
690
691 }
692 nameCacheStringBuilder.append(parentName);
693 nameCacheStringBuilder.append(" ");
694 nameCacheStringBuilder.append(localName);
695 specificEpithet.append(parentName);
696 infraSpecificEpithet.append(localName);
697 }
698 } else { // Synonym
699
700 if (rank == R_SPECIES) {
701
702 if(grandParentRankId == R_SUBGENUS) {
703
704 String genusSubGenusPart = genusSubGenusPart(originalGenus, useOriginalGenus,
705 genusOrUninomial.append(greatGrandParentName),
706 infraGenericEpithet.append(grandParentName),
707 fauEuTaxon);
708 nameCacheStringBuilder.append(genusSubGenusPart);
709
710 } else if (grandParentRankId == R_GENUS) {
711
712 String genusPart = genusPart(originalGenus, useOriginalGenus,
713 genusOrUninomial.append(grandParentName));
714 nameCacheStringBuilder.append(genusPart);
715
716 }
717 nameCacheStringBuilder.append(localName);
718 specificEpithet.append(localName);
719
720 } else if (rank == R_SUBSPECIES) {
721
722 String greatGreatGrandParentName = fauEuTaxon.getGreatGreatGrandParentName();
723
724 if(greatGrandParentRankId == R_SUBGENUS) {
725
726 String genusSubGenusPart = genusSubGenusPart(originalGenus, useOriginalGenus,
727 genusOrUninomial.append(greatGreatGrandParentName),
728 infraGenericEpithet.append(greatGrandParentName),
729 fauEuTaxon);
730 nameCacheStringBuilder.append(genusSubGenusPart);
731
732 } else if (greatGrandParentRankId == R_GENUS) {
733
734 String genusPart = genusPart(originalGenus, useOriginalGenus,
735 genusOrUninomial.append(greatGreatGrandParentName));
736 nameCacheStringBuilder.append(genusPart);
737 }
738
739 nameCacheStringBuilder.append(grandParentName);
740 nameCacheStringBuilder.append(" ");
741 specificEpithet.append(grandParentName);
742 nameCacheStringBuilder.append(localName);
743 infraSpecificEpithet.append(localName);
744 }
745
746
747
748 }
749
750 return nameCacheStringBuilder.toString();
751 }
752
753
754 /** Build taxon's name parts and caches */
755 private String buildTaxonName(FaunaEuropaeaTaxon fauEuTaxon, TaxonBase<?> taxonBase, TaxonNameBase<?,?>taxonName,
756 boolean useOriginalGenus, FaunaEuropaeaImportConfigurator fauEuConfig) {
757
758 /* Local taxon name string */
759 String localString = "";
760 /* Concatenated taxon name string */
761 String completeString = "";
762
763 StringBuilder originalGenus = new StringBuilder("");
764
765 StringBuilder genusOrUninomial = new StringBuilder();
766 StringBuilder infraGenericEpithet = new StringBuilder();
767 StringBuilder specificEpithet = new StringBuilder();
768 StringBuilder infraSpecificEpithet = new StringBuilder();
769
770 localString = fauEuTaxon.getLocalName();
771 int rank = fauEuTaxon.getRankId();
772
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();
777 } else {
778 originalGenusString = determineOriginalGenus(fauEuTaxon);
779 }
780
781 if (originalGenusString != null) {
782 originalGenus = new StringBuilder(originalGenusString);
783 }
784
785 if(logger.isDebugEnabled()) {
786 logger.debug("Local taxon name (rank = " + rank + "): " + localString);
787 }
788
789 if (rank < R_SPECIES) {
790 // subgenus or above
791
792 completeString = localString;
793 if (rank == R_SUBGENUS) {
794 // subgenus part
795 infraGenericEpithet.append(localString);
796
797 // genus part
798 genusOrUninomial.append(originalGenus);
799
800 completeString = originalGenus + " ("+ localString + ")";
801 } else {
802 // genus or above
803 genusOrUninomial.append(localString);
804 }
805
806 } else {
807 // species or below
808
809 taxonBase = taxonBase.deproxy(taxonBase, TaxonBase.class);
810
811 completeString =
812 buildLowerTaxonName(originalGenus, useOriginalGenus,
813 genusOrUninomial, infraGenericEpithet, specificEpithet, infraSpecificEpithet,
814 fauEuTaxon);
815
816 completeString = (String) CdmUtils.removeDuplicateWhitespace(completeString.trim());
817
818 }
819 return setCompleteTaxonName(completeString, useOriginalGenus,
820 genusOrUninomial.toString(), infraGenericEpithet.toString(),
821 specificEpithet.toString(), infraSpecificEpithet.toString(),
822 fauEuTaxon, taxonBase, fauEuConfig);
823
824 }
825
826
827 /**
828 * Determines the original genus name by searching the taxon with rank Genus.
829 * @param fauEuTaxon
830 * @return
831 */
832 private String determineOriginalGenus(FaunaEuropaeaTaxon fauEuTaxon) {
833 String originalGenus = null;
834
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());
841
842 originalGenus = ranks.get(R_GENUS);
843
844 return originalGenus;
845 }
846
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) {
851
852 boolean success = true;
853
854 TaxonNameBase<?,?> taxonName = taxonBase.getName();
855 ZoologicalName zooName = (ZoologicalName)taxonName;
856
857 if (!genusOrUninomial.equals("")) {
858 zooName.setGenusOrUninomial(emptyToNull(genusOrUninomial));
859 if (logger.isDebugEnabled()) {
860 logger.debug("genusOrUninomial: " + genusOrUninomial);
861 }
862 }
863
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);
870 }
871 }
872 if ((fauEuTaxon.getRankId() == R_SPECIES || fauEuTaxon.getRankId() == R_SUBSPECIES)) {
873 zooName.setSpecificEpithet(emptyToNull(specificEpithet));
874 if (logger.isDebugEnabled()) {
875 logger.debug("specificEpithet: " + specificEpithet);
876 }
877 }
878 if (fauEuTaxon.getRankId() == R_SUBSPECIES) {
879 zooName.setInfraSpecificEpithet(emptyToNull(infraSpecificEpithet));
880 if (logger.isDebugEnabled()) {
881 logger.debug("infraSpecificEpithet: " + infraSpecificEpithet);
882 }
883 }
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
893
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);
900
901 if (logger.isDebugEnabled()) {
902 logger.debug("Name stored: " + result);
903 }
904 return result;
905 }
906
907 /**
908 * Ensures that empty strings are translated to null.
909 * @param genusOrUninomial
910 * @return
911 */
912 private String emptyToNull(String text) {
913 if (CdmUtils.isEmpty(text)) {
914 return null;
915 } else {
916 return text;
917 }
918 }
919
920 }