minor change
[cdmlib.git] / cdmlib-io / src / main / java / eu / etaxonomy / cdm / io / pesi / out / PesiTaxonExport.java
1 // $Id$
2 /**
3 * Copyright (C) 2009 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10 package eu.etaxonomy.cdm.io.pesi.out;
11
12 import java.sql.Connection;
13 import java.sql.PreparedStatement;
14 import java.sql.ResultSet;
15 import java.sql.SQLException;
16 import java.util.ArrayList;
17 import java.util.Date;
18 import java.util.HashMap;
19 import java.util.List;
20 import java.util.Set;
21 import java.util.UUID;
22
23 import org.apache.log4j.Logger;
24 import org.joda.time.DateTime;
25 import org.joda.time.format.DateTimeFormat;
26 import org.joda.time.format.DateTimeFormatter;
27 import org.springframework.stereotype.Component;
28 import org.springframework.transaction.TransactionStatus;
29
30 import eu.etaxonomy.cdm.common.CdmUtils;
31 import eu.etaxonomy.cdm.io.berlinModel.out.mapper.DbExtensionMapper;
32 import eu.etaxonomy.cdm.io.berlinModel.out.mapper.IdMapper;
33 import eu.etaxonomy.cdm.io.berlinModel.out.mapper.MethodMapper;
34 import eu.etaxonomy.cdm.io.common.Source;
35 import eu.etaxonomy.cdm.io.erms.ErmsTransformer;
36 import eu.etaxonomy.cdm.model.agent.Team;
37 import eu.etaxonomy.cdm.model.common.Annotation;
38 import eu.etaxonomy.cdm.model.common.AnnotationType;
39 import eu.etaxonomy.cdm.model.common.CdmBase;
40 import eu.etaxonomy.cdm.model.common.Extension;
41 import eu.etaxonomy.cdm.model.common.ExtensionType;
42 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
43 import eu.etaxonomy.cdm.model.common.IdentifiableSource;
44 import eu.etaxonomy.cdm.model.common.Language;
45 import eu.etaxonomy.cdm.model.name.NameRelationship;
46 import eu.etaxonomy.cdm.model.name.NameRelationshipType;
47 import eu.etaxonomy.cdm.model.name.NameTypeDesignation;
48 import eu.etaxonomy.cdm.model.name.NameTypeDesignationStatus;
49 import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
50 import eu.etaxonomy.cdm.model.name.NomenclaturalStatus;
51 import eu.etaxonomy.cdm.model.name.NomenclaturalStatusType;
52 import eu.etaxonomy.cdm.model.name.NonViralName;
53 import eu.etaxonomy.cdm.model.name.Rank;
54 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
55 import eu.etaxonomy.cdm.model.name.ZoologicalName;
56 import eu.etaxonomy.cdm.model.reference.ReferenceBase;
57 import eu.etaxonomy.cdm.model.taxon.Synonym;
58 import eu.etaxonomy.cdm.model.taxon.Taxon;
59 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
60 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
61 import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
62 import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
63 import eu.etaxonomy.cdm.model.taxon.TaxonomicTree;
64 import eu.etaxonomy.cdm.persistence.query.MatchMode;
65
66 /**
67 * @author e.-m.lee
68 * @date 23.02.2010
69 *
70 */
71 @Component
72 @SuppressWarnings("unchecked")
73 public class PesiTaxonExport extends PesiExportBase {
74 private static final Logger logger = Logger.getLogger(PesiTaxonExport.class);
75 private static final Class<? extends CdmBase> standardMethodParameter = TaxonNameBase.class;
76
77 private static int modCount = 1000;
78 private static final String dbTableName = "Taxon";
79 private static final String pluralString = "Taxa";
80 private static final String parentPluralString = "Taxa";
81 private PreparedStatement parentTaxonFk_TreeIndex_KingdomFkStmt;
82 private PreparedStatement sqlStmt;
83 private PreparedStatement rankSqlStmt;
84 private NomenclaturalCode nomenclaturalCode;
85 private Integer kingdomFk;
86 private HashMap<Rank, Rank> rankMap = new HashMap<Rank, Rank>();
87 private List<Rank> rankList = new ArrayList<Rank>();
88 private static final UUID uuidTreeIndex = UUID.fromString("28f4e205-1d02-4d3a-8288-775ea8413009");
89 private AnnotationType treeIndexAnnotationType;
90 private static ExtensionType lastActionExtensionType;
91 private static ExtensionType lastActionDateExtensionType;
92 private static ExtensionType expertNameExtensionType;
93 private static ExtensionType speciesExpertNameExtensionType;
94 private static ExtensionType cacheCitationExtensionType;
95 private static ExtensionType expertUserIdExtensionType;
96 private static ExtensionType speciesExpertUserIdExtensionType;
97
98 /**
99 * @return the treeIndexAnnotationType
100 */
101 protected AnnotationType getTreeIndexAnnotationType() {
102 return treeIndexAnnotationType;
103 }
104
105 /**
106 * @param treeIndexAnnotationType the treeIndexAnnotationType to set
107 */
108 protected void setTreeIndexAnnotationType(AnnotationType treeIndexAnnotationType) {
109 this.treeIndexAnnotationType = treeIndexAnnotationType;
110 }
111
112 enum NamePosition {
113 beginning,
114 end,
115 between,
116 alone,
117 nowhere
118 }
119
120 public PesiTaxonExport() {
121 super();
122 }
123
124 /* (non-Javadoc)
125 * @see eu.etaxonomy.cdm.io.common.DbExportBase#getStandardMethodParameter()
126 */
127 @Override
128 public Class<? extends CdmBase> getStandardMethodParameter() {
129 return standardMethodParameter;
130 }
131
132 /* (non-Javadoc)
133 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doCheck(eu.etaxonomy.cdm.io.common.IoStateBase)
134 */
135 @Override
136 protected boolean doCheck(PesiExportState state) {
137 boolean result = true;
138 return result;
139 }
140
141 /* (non-Javadoc)
142 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doInvoke(eu.etaxonomy.cdm.io.common.IoStateBase)
143 */
144 @Override
145 protected boolean doInvoke(PesiExportState state) {
146 try {
147 logger.error("*** Started Making " + pluralString + " ...");
148
149 // Prepare TreeIndex-And-KingdomFk-Statement
150 Connection connection = state.getConfig().getDestination().getConnection();
151 String parentTaxonFk_TreeIndex_KingdomFkSql = "UPDATE Taxon SET ParentTaxonFk = ?, TreeIndex = ? WHERE TaxonId = ?";
152 parentTaxonFk_TreeIndex_KingdomFkStmt = connection.prepareStatement(parentTaxonFk_TreeIndex_KingdomFkSql);
153
154 String sql = "UPDATE Taxon SET RankFk = ?, RankCache = ?, TypeNameFk = ?, KingdomFk = ?, " +
155 "ExpertFk = ?, SpeciesExpertFk = ? WHERE TaxonId = ?";
156 sqlStmt = connection.prepareStatement(sql);
157
158 String rankSql = "UPDATE Taxon SET RankFk = ?, RankCache = ?, KingdomFk = ? WHERE TaxonId = ?";
159 rankSqlStmt = connection.prepareStatement(rankSql);
160
161 // Get the limit for objects to save within a single transaction.
162 int limit = state.getConfig().getLimitSave();
163
164 // Stores whether this invoke was successful or not.
165 boolean success = true;
166
167 // PESI: Clear the database table Taxon.
168 doDelete(state);
169
170 // CDM: Get the number of all available taxa.
171 // int maxCount = getTaxonService().count(null);
172 // logger.error("Total amount of " + maxCount + " " + pluralString + " will be exported.");
173
174 // Get specific mappings: (CDM) Taxon -> (PESI) Taxon
175 PesiExportMapping mapping = getMapping();
176
177 // Initialize the db mapper
178 mapping.initialize(state);
179
180 // Find extensionTypes
181 lastActionExtensionType = (ExtensionType)getTermService().find(PesiTransformer.lastActionUuid);
182 lastActionDateExtensionType = (ExtensionType)getTermService().find(PesiTransformer.lastActionDateUuid);
183 expertNameExtensionType = (ExtensionType)getTermService().find(PesiTransformer.expertNameUuid);
184 speciesExpertNameExtensionType = (ExtensionType)getTermService().find(PesiTransformer.speciesExpertNameUuid);
185 cacheCitationExtensionType = (ExtensionType)getTermService().find(PesiTransformer.cacheCitationUuid);
186 expertUserIdExtensionType = (ExtensionType)getTermService().find(PesiTransformer.expertUserIdUuid);
187 speciesExpertUserIdExtensionType = (ExtensionType)getTermService().find(PesiTransformer.speciesExpertUserIdUuid);
188
189 int count = 0;
190 int pastCount = 0;
191 TransactionStatus txStatus = null;
192 List<TaxonNameBase> list = null;
193
194 logger.error("PHASE 1: Export Taxa...");
195 // Start transaction
196 txStatus = startTransaction(true);
197 logger.error("Started new transaction. Fetching some " + pluralString + " (max: " + limit + ") ...");
198 while ((list = getNameService().list(null, limit, count, null, null)).size() > 0) {
199
200 logger.error("Fetched " + list.size() + " " + pluralString + ". Exporting...");
201 for (TaxonNameBase taxonName : list) {
202 doCount(count++, modCount, pluralString);
203 success &= mapping.invoke(taxonName);
204
205 // Check whether some rules are violated
206 nomenclaturalCode = PesiTransformer.getNomenclaturalCode(taxonName);
207 String genusOrUninomial = getGenusOrUninomial(taxonName);
208 String specificEpithet = getSpecificEpithet(taxonName);
209 String infraSpecificEpithet = getInfraSpecificEpithet(taxonName);
210 String infraGenericEpithet = getInfraGenericEpithet(taxonName);
211 Integer rank = getRankFk(taxonName, nomenclaturalCode);
212
213 if (rank == null) {
214 logger.error("Rank was not determined: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
215 } else {
216
217 // Check whether infraGenericEpithet is set correctly
218 // 1. Childs of an accepted taxon of rank subgenus that are accepted taxa of rank species have to have an infraGenericEpithet
219 // 2. Grandchilds of an accepted taxon of rank subgenus that are accepted taxa of rank subspecies have to have an infraGenericEpithet
220
221 int ancestorLevel = 0;
222 if (taxonName.getRank().equals(Rank.SUBSPECIES())) {
223 // The accepted taxon two rank levels above should be of rank subgenus
224 ancestorLevel = 2;
225 }
226 if (taxonName.getRank().equals(Rank.SPECIES())) {
227 // The accepted taxon one rank level above should be of rank subgenus
228 ancestorLevel = 1;
229 }
230 if (ancestorLevel > 0) {
231 if (ancestorOfSpecificRank(taxonName, ancestorLevel, Rank.SUBGENUS())) {
232 // The child (species or subspecies) of this parent (subgenus) has to have an infraGenericEpithet
233 if (infraGenericEpithet == null) {
234 logger.error("InfraGenericEpithet does not exist even though it should for: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
235 // maybe the taxon could be named here
236 }
237 }
238 }
239
240 if (infraGenericEpithet == null && rank.intValue() == 190) {
241 logger.error("InfraGenericEpithet was not determined although it should exist for rank 190: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
242 }
243 if (specificEpithet != null && rank.intValue() < 220) {
244 logger.error("SpecificEpithet was determined for rank " + rank + " although it should only exist for ranks higher or equal to 220: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
245 }
246 if (infraSpecificEpithet != null && rank.intValue() < 230) {
247 logger.error("InfraSpecificEpithet was determined for rank " + rank + " although it should only exist for ranks higher or equal to 230: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
248 }
249 }
250 if (infraSpecificEpithet != null && specificEpithet == null) {
251 logger.error("An infraSpecificEpithet was determined, but a specificEpithet was not determined: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
252 }
253 if (genusOrUninomial == null) {
254 logger.error("GenusOrUninomial was not determined: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
255 }
256
257 }
258
259 // Commit transaction
260 commitTransaction(txStatus);
261 logger.error("Committed transaction.");
262 logger.error("Exported " + (count - pastCount) + " " + pluralString + ". Total: " + count);
263 pastCount = count;
264
265 // Start transaction
266 txStatus = startTransaction(true);
267 logger.error("Started new transaction. Fetching some " + pluralString + " (max: " + limit + ") ...");
268 }
269 if (list.size() == 0) {
270 logger.error("No " + pluralString + " left to fetch.");
271 }
272 // Commit transaction
273 commitTransaction(txStatus);
274 logger.error("Committed transaction.");
275
276 count = 0;
277 pastCount = 0;
278 List<TaxonomicTree> taxonomicTreeList = null;
279 // 2nd Round: Add ParentTaxonFk, TreeIndex to each Taxon
280 logger.error("PHASE 2: Add ParenTaxonFk and TreeIndex...");
281
282 // Specify starting ranks for tree traversing
283 rankList.add(Rank.KINGDOM());
284 rankList.add(Rank.GENUS());
285
286 // Specify where to stop traversing (value) when starting at a specific Rank (key)
287 rankMap.put(Rank.GENUS(), null); // Since NULL does not match an existing Rank, traverse all the way down to the leaves
288 rankMap.put(Rank.KINGDOM(), Rank.GENUS()); // excludes rank genus
289
290 StringBuffer treeIndex = new StringBuffer();
291
292 // Retrieve list of Taxonomic Trees
293 txStatus = startTransaction(true);
294 logger.error("Started transaction. Fetching all Taxonomic Trees...");
295 taxonomicTreeList = getTaxonTreeService().listTaxonomicTrees(null, 0, null, null);
296 commitTransaction(txStatus);
297 logger.error("Committed transaction.");
298
299 logger.error("Fetched " + taxonomicTreeList.size() + " Taxonomic Tree.");
300
301 setTreeIndexAnnotationType(getAnnotationType(uuidTreeIndex, "TreeIndex", "", "TI"));
302
303 for (TaxonomicTree taxonomicTree : taxonomicTreeList) {
304 for (Rank rank : rankList) {
305
306 txStatus = startTransaction(true);
307 logger.error("Started transaction to fetch all rootNodes specific to Rank " + rank.getLabel() + " ...");
308
309 List<TaxonNode> rankSpecificRootNodes = getTaxonTreeService().loadRankSpecificRootNodes(taxonomicTree, rank, null);
310 logger.error("Fetched " + rankSpecificRootNodes.size() + " RootNodes for Rank " + rank.getLabel());
311
312 commitTransaction(txStatus);
313 logger.error("Committed transaction.");
314
315 for (TaxonNode rootNode : rankSpecificRootNodes) {
316 txStatus = startTransaction(false);
317 Rank endRank = rankMap.get(rank);
318 if (endRank != null) {
319 logger.error("Started transaction to traverse childNodes of rootNode (" + rootNode.getUuid() + ") till Rank " + endRank.getLabel() + " ...");
320 } else {
321 logger.error("Started transaction to traverse childNodes of rootNode (" + rootNode.getUuid() + ") till leaves are reached ...");
322 }
323
324 TaxonNode newNode = getTaxonNodeService().load(rootNode.getUuid());
325
326 TaxonNode parentNode = newNode.getParent();
327 if (rank.equals(Rank.KINGDOM())) {
328 treeIndex = new StringBuffer();
329 treeIndex.append("#");
330 } else {
331 // Get treeIndex from parentNode
332 if (parentNode != null) {
333 boolean annotationFound = false;
334 Set<Annotation> annotations = parentNode.getAnnotations();
335 for (Annotation annotation : annotations) {
336 AnnotationType annotationType = annotation.getAnnotationType();
337 if (annotationType != null && annotationType.equals(getTreeIndexAnnotationType())) {
338 treeIndex = new StringBuffer(CdmUtils.Nz(annotation.getText()));
339 annotationFound = true;
340 // logger.error("treeIndex: " + treeIndex);
341 break;
342 }
343 }
344 if (!annotationFound) {
345 // This should not happen because it means that the treeIndex was not set correctly as an annotation to parentNode
346 logger.error("TreeIndex could not be read from annotation of this TaxonNode: " + parentNode.getUuid());
347 treeIndex = new StringBuffer();
348 treeIndex.append("#");
349 }
350 } else {
351 // TreeIndex could not be determined, but it's unclear how to proceed to generate a correct treeIndex if the parentNode is NULL
352 logger.error("ParentNode for RootNode is NULL. TreeIndex could not be determined: " + newNode.getUuid());
353 treeIndex = new StringBuffer(); // This just prevents growing of the treeIndex in a wrong manner
354 treeIndex.append("#");
355 }
356 }
357
358 nomenclaturalCode = PesiTransformer.getNomenclaturalCode(newNode.getTaxon().getName());
359 kingdomFk = PesiTransformer.nomenClaturalCode2Kingdom(nomenclaturalCode);
360 traverseTree(newNode, parentNode, treeIndex, rankMap.get(rank), state);
361
362 commitTransaction(txStatus);
363 logger.error("Committed transaction.");
364
365 }
366 }
367 }
368
369 logger.error("PHASE 3: Add Rank data, KingdomFk, TypeNameFk, expertFk and speciesExpertFk...");
370 // Be sure to add rank information, KingdomFk, TypeNameFk, expertFk and speciesExpertFk to every taxonName
371
372 // Start transaction
373 List<ReferenceBase> referenceList;
374 txStatus = startTransaction(true);
375 logger.error("Started new transaction. Fetching some " + pluralString + " (max: " + limit + ") ...");
376 while ((list = getNameService().list(null, limit, count, null, null)).size() > 0) {
377
378 logger.error("Fetched " + list.size() + " " + pluralString + ". Exporting...");
379 for (TaxonNameBase taxonName : list) {
380
381 // Determine expertFk
382 Integer expertFk = null;
383 String expertUserId = getExpertUserId(taxonName);
384 if (expertUserId != null) {
385
386 // The expertUserId was stored in the field 'title' of the corresponding Reference during FaEu import
387 referenceList = getReferenceService().listByReferenceTitle(null, expertUserId, MatchMode.EXACT, null, null, null, null, null);
388 if (referenceList.size() == 1) {
389 expertFk = getExpertFk(referenceList.iterator().next(), state);
390 } else if (referenceList.size() > 1) {
391 logger.error("Found more than one match using listByReferenceTitle() searching for a Reference with this expertUserId as title: " + expertUserId);
392 } else if (referenceList.size() == 0) {
393 logger.error("Found no match using listByReferenceTitle() searching for a Reference with this expertUserId as title: " + expertUserId);
394 }
395 } else {
396 logger.error("ExpertName is NULL for this TaxonName: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
397 }
398
399 // Determine speciesExpertFk
400 Integer speciesExpertFk = null;
401 String speciesExpertUserId = getSpeciesExpertUserId(taxonName);
402 if (speciesExpertUserId != null) {
403
404 // The speciesExpertUserId was stored in the field 'title' of the corresponding Reference during FaEu import
405 referenceList = getReferenceService().listByReferenceTitle(null, speciesExpertUserId, MatchMode.EXACT, null, null, null, null, null);
406 if (referenceList.size() == 1) {
407 speciesExpertFk = getSpeciesExpertFk(referenceList.iterator().next(), state);
408 } else if (referenceList.size() > 1) {
409 logger.error("Found more than one match using listByTitle() searching for a Reference with this speciesExpertUserId as title: " + speciesExpertUserId);
410 } else if (referenceList.size() == 0) {
411 logger.error("Found no match using listByReferenceTitle() searching for a Reference with this speciesExpertUserId as title: " + speciesExpertUserId);
412 }
413 } else {
414 logger.error("SpeciesExpertName is NULL for this TaxonName: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
415 }
416
417
418 doCount(count++, modCount, pluralString);
419 Integer typeNameFk = getTypeNameFk(taxonName, state);
420 if (expertFk != null || speciesExpertFk != null) {
421 invokeRankDataAndTypeNameFkAndKingdomFk(taxonName, nomenclaturalCode, state.getDbId(taxonName), typeNameFk, kingdomFk,
422 expertFk, speciesExpertFk);
423 }
424 }
425
426 // Commit transaction
427 commitTransaction(txStatus);
428 logger.error("Committed transaction.");
429 logger.error("Exported " + (count - pastCount) + " " + pluralString + ". Total: " + count);
430 pastCount = count;
431
432 // Start transaction
433 txStatus = startTransaction(true);
434 logger.error("Started new transaction. Fetching some " + pluralString + " (max: " + limit + ") ...");
435 }
436 if (list.size() == 0) {
437 logger.error("No " + pluralString + " left to fetch.");
438 }
439 // Commit transaction
440 commitTransaction(txStatus);
441 logger.error("Committed transaction.");
442
443
444 // Create inferred synonyms for accepted taxa
445 logger.error("PHASE 4: Creating Inferred Synonyms...");
446
447 // Determine the count of elements in datawarehouse database table Taxon
448 Integer currentTaxonId = determineTaxonCount(state);
449 currentTaxonId++;
450
451 count = 0;
452 pastCount = 0;
453 int pageSize = limit;
454 int pageNumber = 1;
455 String inferredSynonymPluralString = "Inferred Synonyms";
456
457 // Start transaction
458 TaxonomicTree taxonTree = null;
459 Taxon acceptedTaxon = null;
460 txStatus = startTransaction(true);
461 logger.error("Started new transaction. Fetching some " + parentPluralString + " first (max: " + limit + ") ...");
462 List<TaxonBase> taxonList = null;
463 List<Synonym> inferredSynonyms = null;
464 while ((taxonList = getTaxonService().listTaxaByName(Taxon.class, "*", "*", "*", "*", null, pageSize, pageNumber)).size() > 0) {
465 HashMap<Integer, TaxonNameBase> inferredSynonymsDataToBeSaved = new HashMap<Integer, TaxonNameBase>();
466
467 logger.error("Fetched " + taxonList.size() + " " + parentPluralString + ". Exporting...");
468 for (TaxonBase taxonBase : taxonList) {
469
470 if (taxonBase.isInstanceOf(Taxon.class)) { // this should always be the case since we should have fetched accepted taxon only, but you never know...
471 acceptedTaxon = CdmBase.deproxy(taxonBase, Taxon.class);
472 TaxonNameBase taxonName = acceptedTaxon.getName();
473
474 if (taxonName.isInstanceOf(ZoologicalName.class)) {
475 nomenclaturalCode = PesiTransformer.getNomenclaturalCode(taxonName);
476 kingdomFk = PesiTransformer.nomenClaturalCode2Kingdom(nomenclaturalCode);
477
478 Set<TaxonNode> taxonNodes = acceptedTaxon.getTaxonNodes();
479 TaxonNode singleNode = null;
480 if (taxonNodes.size() > 0) {
481 // Determine the taxonomicTree of the current TaxonNode
482 singleNode = taxonNodes.iterator().next();
483 if (singleNode != null) {
484 taxonTree = singleNode.getTaxonomicTree();
485 } else {
486 logger.error("A TaxonNode belonging to this accepted Taxon is NULL: " + acceptedTaxon.getUuid() + " (" + acceptedTaxon.getTitleCache() +")");
487 }
488 } else {
489 // TaxonomicTree could not be determined directly from this TaxonNode
490 // The stored taxonomicTree from another TaxonNode is used. It's a simple, but not a failsafe fallback solution.
491 if (taxonTree == null) {
492 logger.error("TaxonomicTree could not be determined directly from this TaxonNode: " + singleNode.getUuid() + "). " +
493 "This taxonomicTree stored from another TaxonNode is used: " + taxonTree.getTitleCache());
494 }
495 }
496
497 if (taxonTree != null) {
498 inferredSynonyms = getTaxonService().createAllInferredSynonyms(taxonTree, acceptedTaxon);
499
500 // inferredSynonyms = getTaxonService().createInferredSynonyms(taxonTree, acceptedTaxon, SynonymRelationshipType.INFERRED_GENUS_OF());
501 if (inferredSynonyms != null) {
502 for (Synonym synonym : inferredSynonyms) {
503 TaxonNameBase synonymName = synonym.getName();
504 if (synonymName != null) {
505
506 // Both Synonym and its TaxonName have no valid Id yet
507 synonym.setId(currentTaxonId++);
508 synonymName.setId(currentTaxonId++);
509
510 doCount(count++, modCount, inferredSynonymPluralString);
511 success &= mapping.invoke(synonymName);
512
513 // Add Rank Data and KingdomFk to hashmap for later saving
514 inferredSynonymsDataToBeSaved.put(synonymName.getId(), synonymName);
515 } else {
516 logger.error("TaxonName of this Synonym is NULL: " + synonym.getUuid() + " (" + synonym.getTitleCache() + ")");
517 }
518 }
519 }
520 } else {
521 logger.error("TaxonomicTree is NULL. Inferred Synonyms could not be created for this Taxon: " + acceptedTaxon.getUuid() + " (" + acceptedTaxon.getTitleCache() + ")");
522 }
523 } else {
524 // logger.error("TaxonName is not a ZoologicalName: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
525 }
526 } else {
527 logger.error("This TaxonBase is not a Taxon even though it should be: " + taxonBase.getUuid() + " (" + taxonBase.getTitleCache() + ")");
528 }
529 }
530
531 // Commit transaction
532 commitTransaction(txStatus);
533 logger.error("Committed transaction.");
534 logger.error("Exported " + (count - pastCount) + " " + inferredSynonymPluralString + ". Total: " + count);
535 pastCount = count;
536
537 // Save Rank Data and KingdomFk for inferred synonyms
538 for (Integer taxonFk : inferredSynonymsDataToBeSaved.keySet()) {
539 invokeRankDataAndKingdomFk(inferredSynonymsDataToBeSaved.get(taxonFk), nomenclaturalCode, taxonFk, kingdomFk);
540 }
541
542 // Start transaction
543 txStatus = startTransaction(true);
544 logger.error("Started new transaction. Fetching some " + parentPluralString + " first (max: " + limit + ") ...");
545
546 // Increment pageNumber
547 pageNumber++;
548 }
549 if (taxonList.size() == 0) {
550 logger.error("No " + parentPluralString + " left to fetch.");
551 }
552 // Commit transaction
553 commitTransaction(txStatus);
554 logger.error("Committed transaction.");
555
556
557 logger.error("*** Finished Making " + pluralString + " ..." + getSuccessString(success));
558
559 return success;
560 } catch (SQLException e) {
561 e.printStackTrace();
562 logger.error(e.getMessage());
563 return false;
564 }
565 }
566
567 /**
568 * Determines the number of entries in the datawarehouse database table Taxon.
569 * @return
570 */
571 private Integer determineTaxonCount(PesiExportState state) {
572 Integer result = null;
573 PesiExportConfigurator pesiConfig = (PesiExportConfigurator) state.getConfig();
574
575 String sql;
576 Source destination = pesiConfig.getDestination();
577 sql = "SELECT COUNT(*) FROM Taxon";
578 destination.setQuery(sql);
579 ResultSet resultSet = destination.getResultSet();
580 try {
581 resultSet.next();
582 result = resultSet.getInt(1);
583 } catch (SQLException e) {
584 logger.error("TaxonCount could not be determined: " + e.getMessage());
585 e.printStackTrace();
586 }
587 return result;
588 }
589
590 /**
591 * Returns the userId of the expert associated with the given TaxonName.
592 * @param taxonName
593 * @return
594 */
595 private String getExpertUserId(TaxonNameBase taxonName) {
596 String result = null;
597 try {
598 Set<Extension> extensions = taxonName.getExtensions();
599 for (Extension extension : extensions) {
600 if (extension.getType().equals(expertUserIdExtensionType)) {
601 result = extension.getValue();
602 }
603 }
604 } catch (Exception e) {
605 e.printStackTrace();
606 }
607 return result;
608 }
609
610 /**
611 * Returns the userId of the speciesExpert associated with the given TaxonName.
612 * @param taxonName
613 * @return
614 */
615 private String getSpeciesExpertUserId(TaxonNameBase taxonName) {
616 String result = null;
617 try {
618 Set<Extension> extensions = taxonName.getExtensions();
619 for (Extension extension : extensions) {
620 if (extension.getType().equals(speciesExpertUserIdExtensionType)) {
621 result = extension.getValue();
622 }
623 }
624 } catch (Exception e) {
625 e.printStackTrace();
626 }
627 return result;
628 }
629
630 /**
631 * Checks whether a parent at specific level has a specific Rank.
632 * @param taxonName
633 * @param i
634 * @param subgenus
635 * @return
636 */
637 private boolean ancestorOfSpecificRank(TaxonNameBase taxonName, int level,
638 Rank ancestorRank) {
639 boolean result = false;
640 Set<Taxon> taxa = taxonName.getTaxa();
641 TaxonNode parentNode = null;
642 if (taxa != null && taxa.size() > 0) {
643 if (taxa.size() == 1) {
644 Taxon taxon = taxa.iterator().next();
645 if (taxon != null) {
646 // Get ancestor Taxon via TaxonNode
647
648 Set<TaxonNode> taxonNodes = taxon.getTaxonNodes();
649 if (taxonNodes.size() == 1) {
650 TaxonNode taxonNode = taxonNodes.iterator().next();
651 if (taxonNode != null) {
652 for (int i = 0; i < level; i++) {
653 if (taxonNode != null) {
654 taxonNode = taxonNode.getParent();
655 }
656 }
657 parentNode = taxonNode;
658 }
659 } else if (taxonNodes.size() > 1) {
660 logger.error("This taxon has " + taxonNodes.size() + " taxonNodes: " + taxon.getUuid() + " (" + taxon.getTitleCache() + ")");
661 }
662 }
663 } else {
664 logger.error("This taxonName has " + taxa.size() + " Taxa: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
665 }
666 }
667 if (parentNode != null) {
668 TaxonNode node = CdmBase.deproxy(parentNode, TaxonNode.class);
669 Taxon parentTaxon = node.getTaxon();
670 if (parentTaxon != null) {
671 TaxonNameBase parentTaxonName = parentTaxon.getName();
672 if (parentTaxonName != null && parentTaxonName.getRank().equals(ancestorRank)) {
673 result = true;
674 }
675 } else {
676 logger.error("This TaxonNode has no Taxon: " + node.getUuid());
677 }
678 }
679 return result;
680 }
681
682 /**
683 * Returns the AnnotationType for a given UUID.
684 * @param state
685 * @param uuid
686 * @param label
687 * @param text
688 * @param labelAbbrev
689 * @return
690 */
691 protected AnnotationType getAnnotationType(UUID uuid, String label, String text, String labelAbbrev){
692 AnnotationType annotationType = (AnnotationType)getTermService().find(uuid);
693 if (annotationType == null) {
694 annotationType = AnnotationType.NewInstance(label, text, labelAbbrev);
695 annotationType.setUuid(uuid);
696 // annotationType.setVocabulary(AnnotationType.EDITORIAL().getVocabulary());
697 getTermService().save(annotationType);
698 }
699 return annotationType;
700 }
701
702 /**
703 * Traverses the TaxonTree recursively and stores determined values for every Taxon.
704 * @param childNode
705 * @param parentNode
706 * @param treeIndex
707 * @param fetchLevel
708 * @param state
709 */
710 private void traverseTree(TaxonNode childNode, TaxonNode parentNode, StringBuffer treeIndex, Rank fetchLevel, PesiExportState state) {
711 // Traverse all branches from this childNode until specified fetchLevel is reached.
712 StringBuffer localTreeIndex = new StringBuffer(treeIndex);
713 if (childNode.getTaxon() != null) {
714 TaxonNameBase taxonName = childNode.getTaxon().getName();
715 Integer taxonNameId = state.getDbId(taxonName);
716 if (taxonNameId != null) {
717 Rank childTaxonNameRank = taxonName.getRank();
718 if (childTaxonNameRank != null) {
719 if (! childTaxonNameRank.equals(fetchLevel)) {
720
721 localTreeIndex.append(taxonNameId);
722 localTreeIndex.append("#");
723
724 saveData(childNode, parentNode, localTreeIndex, state, taxonNameId);
725
726 // Store treeIndex as annotation for further use
727 Annotation annotation = Annotation.NewInstance(localTreeIndex.toString(), getTreeIndexAnnotationType(), Language.DEFAULT());
728 childNode.addAnnotation(annotation);
729
730 for (TaxonNode newNode : childNode.getChildNodes()) {
731 traverseTree(newNode, childNode, localTreeIndex, fetchLevel, state);
732 }
733
734 } else {
735 // logger.error("Target Rank " + fetchLevel.getLabel() + " reached");
736 return;
737 }
738 } else {
739 logger.error("Rank is NULL. FetchLevel can not be checked: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
740 }
741 } else {
742 logger.error("TaxonName can not be found in State: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
743 }
744
745 } else {
746 logger.error("Taxon is NULL for TaxonNode: " + childNode.getUuid());
747 }
748 }
749
750 /**
751 * Stores values in database for every recursive round.
752 * @param childNode
753 * @param parentNode
754 * @param treeIndex
755 * @param state
756 * @param currentTaxonFk
757 */
758 private void saveData(TaxonNode childNode, TaxonNode parentNode, StringBuffer treeIndex, PesiExportState state, Integer currentTaxonFk) {
759 // We are differentiating kingdoms by the nomenclatural code for now.
760 // This needs to be handled in a better way as soon as we know how to differentiate between more kingdoms.
761 Taxon childNodeTaxon = childNode.getTaxon();
762 TaxonNameBase childNodeTaxonName = childNode.getTaxon().getName();
763 if (childNodeTaxon != null && childNodeTaxonName != null) {
764 TaxonNameBase parentNodeTaxonName = null;
765 if (parentNode != null) {
766 Taxon parentNodeTaxon = parentNode.getTaxon();
767 if (parentNodeTaxon != null) {
768 parentNodeTaxonName = parentNodeTaxon.getName();
769 }
770 }
771
772 invokeParentTaxonFkAndTreeIndex(
773 state.getDbId(parentNodeTaxonName),
774 currentTaxonFk,
775 treeIndex);
776 }
777
778 }
779
780 /**
781 * Inserts values into the Taxon database table.
782 * @param taxonNameBase
783 * @param state
784 * @param stmt
785 * @return
786 */
787 protected boolean invokeParentTaxonFkAndTreeIndex(Integer parentTaxonFk, Integer currentTaxonFk, StringBuffer treeIndex) {
788 try {
789 if (parentTaxonFk != null) {
790 parentTaxonFk_TreeIndex_KingdomFkStmt.setInt(1, parentTaxonFk);
791 } else {
792 parentTaxonFk_TreeIndex_KingdomFkStmt.setObject(1, null);
793 }
794
795 if (treeIndex != null) {
796 parentTaxonFk_TreeIndex_KingdomFkStmt.setString(2, treeIndex.toString());
797 } else {
798 parentTaxonFk_TreeIndex_KingdomFkStmt.setObject(2, null);
799 }
800
801 if (currentTaxonFk != null) {
802 parentTaxonFk_TreeIndex_KingdomFkStmt.setInt(3, currentTaxonFk);
803 } else {
804 parentTaxonFk_TreeIndex_KingdomFkStmt.setObject(3, null);
805 }
806
807 parentTaxonFk_TreeIndex_KingdomFkStmt.executeUpdate();
808 return true;
809 } catch (SQLException e) {
810 logger.error("ParentTaxonFk and TreeIndex could not be inserted into database: " + e.getMessage());
811 e.printStackTrace();
812 return false;
813 }
814 }
815
816 /**
817 * Inserts Rank data and KingdomFk into the Taxon database table.
818 * @param taxonName
819 * @param nomenclaturalCode
820 * @param taxonFk
821 * @param kindomFk
822 * @return
823 */
824 private boolean invokeRankDataAndKingdomFk(TaxonNameBase taxonName, NomenclaturalCode nomenclaturalCode,
825 Integer taxonFk, Integer kingdomFk) {
826 try {
827 Integer rankFk = getRankFk(taxonName, nomenclaturalCode);
828 if (rankFk != null) {
829 rankSqlStmt.setInt(1, rankFk);
830 } else {
831 rankSqlStmt.setObject(1, null);
832 }
833
834 String rankCache = getRankCache(taxonName, nomenclaturalCode);
835 if (rankCache != null) {
836 rankSqlStmt.setString(2, rankCache);
837 } else {
838 rankSqlStmt.setObject(2, null);
839 }
840
841 if (kingdomFk != null) {
842 rankSqlStmt.setInt(3, kingdomFk);
843 } else {
844 rankSqlStmt.setObject(3, null);
845 }
846
847 if (taxonFk != null) {
848 rankSqlStmt.setInt(4, taxonFk);
849 } else {
850 rankSqlStmt.setObject(4, null);
851 }
852
853 rankSqlStmt.executeUpdate();
854 return true;
855 } catch (SQLException e) {
856 logger.error("Data (RankFk, RankCache, KingdomFk) could not be inserted into database: " + e.getMessage());
857 e.printStackTrace();
858 return false;
859 }
860 }
861
862 /**
863 * Inserts Rank data, TypeNameFk, KingdomFk, expertFk and speciesExpertFk into the Taxon database table.
864 * @param taxonName
865 * @param nomenclaturalCode
866 * @param taxonFk
867 * @param typeNameFk
868 * @param kindomFk
869 * @param expertFk
870 * @param speciesExpertFk
871 * @return
872 */
873 private boolean invokeRankDataAndTypeNameFkAndKingdomFk(TaxonNameBase taxonName, NomenclaturalCode nomenclaturalCode,
874 Integer taxonFk, Integer typeNameFk, Integer kingdomFk,
875 Integer expertFk, Integer speciesExpertFk) {
876 try {
877 Integer rankFk = getRankFk(taxonName, nomenclaturalCode);
878 if (rankFk != null) {
879 sqlStmt.setInt(1, rankFk);
880 } else {
881 sqlStmt.setObject(1, null);
882 }
883
884 String rankCache = getRankCache(taxonName, nomenclaturalCode);
885 if (rankCache != null) {
886 sqlStmt.setString(2, rankCache);
887 } else {
888 sqlStmt.setObject(2, null);
889 }
890
891 if (typeNameFk != null) {
892 sqlStmt.setInt(3, typeNameFk);
893 } else {
894 sqlStmt.setObject(3, null);
895 }
896
897 if (kingdomFk != null) {
898 sqlStmt.setInt(4, kingdomFk);
899 } else {
900 sqlStmt.setObject(4, null);
901 }
902
903 if (expertFk != null) {
904 sqlStmt.setInt(5, expertFk);
905 } else {
906 sqlStmt.setObject(5, null);
907 }
908
909 if (speciesExpertFk != null) {
910 sqlStmt.setInt(6, speciesExpertFk);
911 } else {
912 sqlStmt.setObject(6, null);
913 }
914
915 if (taxonFk != null) {
916 sqlStmt.setInt(7, taxonFk);
917 } else {
918 sqlStmt.setObject(7, null);
919 }
920
921 sqlStmt.executeUpdate();
922 return true;
923 } catch (SQLException e) {
924 logger.error("Data could not be inserted into database: " + e.getMessage());
925 e.printStackTrace();
926 return false;
927 }
928 }
929
930 /**
931 * Deletes all entries of database tables related to <code>Taxon</code>.
932 * @param state The PesiExportState
933 * @return Whether the delete operation was successful or not.
934 */
935 protected boolean doDelete(PesiExportState state) {
936 PesiExportConfigurator pesiConfig = (PesiExportConfigurator) state.getConfig();
937
938 String sql;
939 Source destination = pesiConfig.getDestination();
940
941 // Clear Taxon
942 sql = "DELETE FROM " + dbTableName;
943 destination.setQuery(sql);
944 destination.update(sql);
945 return true;
946 }
947
948 /* (non-Javadoc)
949 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IoStateBase)
950 */
951 @Override
952 protected boolean isIgnore(PesiExportState state) {
953 return ! state.getConfig().isDoTaxa();
954 }
955
956 /**
957 * Returns the <code>RankFk</code> attribute.
958 * @param taxon The {@link TaxonBase Taxon}.
959 * @return The <code>RankFk</code> attribute.
960 * @see MethodMapper
961 */
962 private static Integer getRankFk(TaxonNameBase taxonName, NomenclaturalCode nomenclaturalCode) {
963 Integer result = null;
964 try {
965 if (nomenclaturalCode != null) {
966 if (taxonName != null) {
967 if (taxonName.getRank() == null) {
968 logger.warn("Rank is null: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
969 } else {
970 result = PesiTransformer.rank2RankId(taxonName.getRank(), PesiTransformer.nomenClaturalCode2Kingdom(nomenclaturalCode));
971 }
972 if (result == null) {
973 logger.warn("Rank could not be determined for PESI-Kingdom-Id " + PesiTransformer.nomenClaturalCode2Kingdom(nomenclaturalCode) + " and TaxonName " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
974 }
975 }
976 }
977 } catch (Exception e) {
978 e.printStackTrace();
979 }
980 return result;
981 }
982
983 /**
984 * Returns the <code>RankCache</code> attribute.
985 * @param taxon The {@link TaxonBase Taxon}.
986 * @return The <code>RankCache</code> attribute.
987 * @see MethodMapper
988 */
989 private static String getRankCache(TaxonNameBase taxonName, NomenclaturalCode nomenclaturalCode) {
990 String result = null;
991 try {
992 if (nomenclaturalCode != null) {
993 result = PesiTransformer.rank2RankCache(taxonName.getRank(), PesiTransformer.nomenClaturalCode2Kingdom(nomenclaturalCode));
994 }
995 } catch (Exception e) {
996 e.printStackTrace();
997 }
998 return result;
999 }
1000
1001 /**
1002 *
1003 * @param taxon The {@link TaxonBase Taxon}.
1004 * @return Whether it's genus or uninomial.
1005 * @see MethodMapper
1006 */
1007 private static String getGenusOrUninomial(TaxonNameBase taxonName) {
1008 String result = null;
1009 try {
1010 if (taxonName != null && (taxonName.isInstanceOf(NonViralName.class))) {
1011 NonViralName nonViralName = CdmBase.deproxy(taxonName, NonViralName.class);
1012 result = nonViralName.getGenusOrUninomial();
1013 }
1014 } catch (Exception e) {
1015 e.printStackTrace();
1016 }
1017 return result;
1018 }
1019
1020 /**
1021 * Returns the <code>InfraGenericEpithet</code> attribute.
1022 * @param taxon The {@link TaxonBase Taxon}.
1023 * @return The <code>InfraGenericEpithet</code> attribute.
1024 * @see MethodMapper
1025 */
1026 private static String getInfraGenericEpithet(TaxonNameBase taxonName) {
1027 String result = null;
1028 try {
1029 if (taxonName != null && (taxonName.isInstanceOf(NonViralName.class))) {
1030 NonViralName nonViralName = CdmBase.deproxy(taxonName, NonViralName.class);
1031 result = nonViralName.getInfraGenericEpithet();
1032 }
1033 } catch (Exception e) {
1034 e.printStackTrace();
1035 }
1036 return result;
1037 }
1038
1039 /**
1040 * Returns the <code>SpecificEpithet</code> attribute.
1041 * @param taxon The {@link TaxonBase Taxon}.
1042 * @return The <code>SpecificEpithet</code> attribute.
1043 * @see MethodMapper
1044 */
1045 private static String getSpecificEpithet(TaxonNameBase taxonName) {
1046 String result = null;
1047 try {
1048 if (taxonName != null && (taxonName.isInstanceOf(NonViralName.class))) {
1049 NonViralName nonViralName = CdmBase.deproxy(taxonName, NonViralName.class);
1050 result = nonViralName.getSpecificEpithet();
1051 }
1052 } catch (Exception e) {
1053 e.printStackTrace();
1054 }
1055 return result;
1056 }
1057
1058 /**
1059 * Returns the <code>InfraSpecificEpithet</code> attribute.
1060 * @param taxon The {@link TaxonBase Taxon}.
1061 * @return The <code>InfraSpecificEpithet</code> attribute.
1062 * @see MethodMapper
1063 */
1064 private static String getInfraSpecificEpithet(TaxonNameBase taxonName) {
1065 String result = null;
1066 try {
1067 if (taxonName != null && (taxonName.isInstanceOf(NonViralName.class))) {
1068 NonViralName nonViralName = CdmBase.deproxy(taxonName, NonViralName.class);
1069 result = nonViralName.getInfraSpecificEpithet();
1070 }
1071 } catch (Exception e) {
1072 e.printStackTrace();
1073 }
1074 return result;
1075 }
1076
1077 /**
1078 * Returns the <code>WebSearchName</code> attribute.
1079 * @param taxon The {@link TaxonBase Taxon}.
1080 * @return The <code>WebSearchName</code> attribute.
1081 * @see MethodMapper
1082 */
1083 @SuppressWarnings("unused")
1084 private static String getWebSearchName(TaxonNameBase taxonName) {
1085 String result = null;
1086 try {
1087 if (taxonName != null && (taxonName.isInstanceOf(NonViralName.class))) {
1088 NonViralName nonViralName = CdmBase.deproxy(taxonName, NonViralName.class);
1089 result = nonViralName.getNameCache();
1090 }
1091 } catch (Exception e) {
1092 e.printStackTrace();
1093 }
1094 return result;
1095 }
1096
1097 /**
1098 * Returns the <code>WebShowName</code> attribute.
1099 * @param taxon The {@link TaxonBase Taxon}.
1100 * @return The <code>WebShowName</code> attribute.
1101 * @see MethodMapper
1102 */
1103 private static String getWebShowName(TaxonNameBase taxonName) {
1104 String result = "";
1105
1106 try {
1107 List taggedName = taxonName.getTaggedName();
1108 boolean openTag = false;
1109 boolean start = true;
1110 for (Object object : taggedName) {
1111 if (object instanceof String) {
1112 // Name
1113 if (! openTag) {
1114 if (start) {
1115 result = "<i>";
1116 start = false;
1117 } else {
1118 result += " <i>";
1119 }
1120 openTag = true;
1121 } else {
1122 result += " ";
1123 }
1124 result += object;
1125 } else if (object instanceof Rank) {
1126 // Rank
1127 Rank rank = CdmBase.deproxy(object, Rank.class);
1128
1129 if ("".equals(rank.getAbbreviation().trim())) {
1130 logger.error("Rank abbreviation is an empty string: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
1131 } else {
1132 if (openTag) {
1133 result += "</i> ";
1134 openTag = false;
1135 } else {
1136 result += " ";
1137 }
1138 result += rank.getAbbreviation();
1139 }
1140 } else if (object instanceof Team) {
1141 if (openTag) {
1142 result += "</i> ";
1143 openTag = false;
1144 } else {
1145 result += " ";
1146 }
1147 result += object;
1148 } else if (object instanceof Date) {
1149 if (openTag) {
1150 result += "</i> ";
1151 openTag = false;
1152 } else {
1153 result += " ";
1154 }
1155 result += object;
1156 } else if (object instanceof ReferenceBase) {
1157 if (openTag) {
1158 result += "</i> ";
1159 openTag = false;
1160 } else {
1161 result += " ";
1162 }
1163 result += object;
1164 } else {
1165 if (object == null) {
1166 logger.error("One part of TaggedName is NULL for this TaxonName: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() +")");
1167 } else {
1168 logger.error("Instance of this part of TaggedName is unknown. Object: " + object.getClass().getSimpleName() + ", TaxonName: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
1169 }
1170 }
1171 }
1172 if (openTag) {
1173 result += "</i>";
1174 }
1175 } catch (Exception e) {
1176 e.printStackTrace();
1177 }
1178
1179 return result;
1180 }
1181
1182 /**
1183 * Returns the <code>AuthorString</code> attribute.
1184 * @param taxon The {@link TaxonBase Taxon}.
1185 * @return The <code>AuthorString</code> attribute.
1186 * @see MethodMapper
1187 */
1188 @SuppressWarnings("unused")
1189 private static String getAuthorString(TaxonNameBase taxonName) {
1190 String result = null;
1191 try {
1192 if (taxonName != null) {
1193 if (taxonName.isInstanceOf(NonViralName.class)) {
1194 NonViralName nonViralName = CdmBase.deproxy(taxonName, NonViralName.class);
1195 String authorshipCache = nonViralName.getAuthorshipCache();
1196
1197 // For a misapplied name without an authorshipCache the authorString should be set to "auct."
1198 if (isMisappliedName(taxonName) && authorshipCache == null) {
1199 // Set authorshipCache to "auct."
1200 result = PesiTransformer.auctString;
1201 } else {
1202 // Return the content of the authorshipCache
1203 result = authorshipCache;
1204 }
1205
1206 } else {
1207 logger.warn("TaxonName is not of instance NonViralName: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
1208 }
1209 }
1210 } catch (Exception e) {
1211 e.printStackTrace();
1212 }
1213
1214 if ("".equals(result)) {
1215 return null;
1216 } else {
1217 return result;
1218 }
1219 }
1220
1221 /**
1222 * Checks whether a given TaxonName is a misapplied name.
1223 * @param taxonName
1224 * @return
1225 */
1226 private static boolean isMisappliedName(TaxonNameBase taxonName) {
1227 boolean result = false;
1228 Set<NameRelationship> taxonNameRelations = taxonName.getRelationsFromThisName();
1229 for (NameRelationship nameRelation : taxonNameRelations) {
1230 NameRelationshipType relationshipType = nameRelation.getType();
1231 if (relationshipType.equals(TaxonRelationshipType.MISAPPLIED_NAME_FOR())) {
1232 result = true;
1233 }
1234 }
1235
1236 Set<Taxon> taxa = taxonName.getTaxa();
1237 if (taxa.size() == 1) {
1238 Taxon taxon = CdmBase.deproxy(taxa.iterator().next(), Taxon.class);
1239 Set<TaxonRelationship> taxonRelations = taxon.getRelationsFromThisTaxon();
1240 for (TaxonRelationship taxonRelationship : taxonRelations) {
1241 TaxonRelationshipType taxonRelationshipType = taxonRelationship.getType();
1242 if (taxonRelationshipType.equals(TaxonRelationshipType.MISAPPLIED_NAME_FOR())) {
1243 result = true;
1244 }
1245 }
1246 } else if (taxa.size() > 1) {
1247 logger.error("Could not check for misapplied name. This TaxonName has " + taxa.size() + " Taxa: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
1248 }
1249 return result;
1250 }
1251
1252 /**
1253 * Returns the <code>FullName</code> attribute.
1254 * @param taxon The {@link TaxonBase Taxon}.
1255 * @return The <code>FullName</code> attribute.
1256 * @see MethodMapper
1257 */
1258 @SuppressWarnings("unused")
1259 private static String getFullName(TaxonNameBase taxonName) {
1260 if (taxonName != null) {
1261 return taxonName.getTitleCache();
1262 } else {
1263 return null;
1264 }
1265 }
1266
1267 /**
1268 * Returns the <code>NomRefString</code> attribute.
1269 * @param taxon The {@link TaxonBase Taxon}.
1270 * @return The <code>NomRefString</code> attribute.
1271 * @see MethodMapper
1272 */
1273 @SuppressWarnings("unused")
1274 private static String getNomRefString(TaxonNameBase taxonName) {
1275 String result = null;
1276 try {
1277 if (taxonName != null) {
1278 try {
1279 result = taxonName.getNomenclaturalMicroReference();
1280 } catch (Exception e) {
1281 logger.error("While getting NomRefString");
1282 e.printStackTrace();
1283 }
1284 }
1285 } catch (Exception e) {
1286 e.printStackTrace();
1287 }
1288 return result;
1289 }
1290
1291 /**
1292 * Returns the <code>DisplayName</code> attribute.
1293 * @param taxon The {@link TaxonBase Taxon}.
1294 * @return The <code>DisplayName</code> attribute.
1295 * @see MethodMapper
1296 */
1297 @SuppressWarnings("unused")
1298 private static String getDisplayName(TaxonNameBase taxonName) {
1299 // TODO: extension?
1300 if (taxonName != null) {
1301 return taxonName.getFullTitleCache();
1302 } else {
1303 return null;
1304 }
1305 }
1306
1307 // /**
1308 // * Returns the <code>FuzzyName</code> attribute.
1309 // * @param taxon The {@link TaxonBase Taxon}.
1310 // * @return The <code>FuzzyName</code> attribute.
1311 // * @see MethodMapper
1312 // */
1313 // @SuppressWarnings("unused")
1314 // private static String getFuzzyName(TaxonNameBase taxonName) {
1315 // // TODO: extension
1316 // return null;
1317 // }
1318
1319 /**
1320 * Returns the <code>NameStatusFk</code> attribute.
1321 * @param taxon The {@link TaxonBase Taxon}.
1322 * @return The <code>NameStatusFk</code> attribute.
1323 * @see MethodMapper
1324 */
1325 @SuppressWarnings("unused")
1326 private static Integer getNameStatusFk(TaxonNameBase taxonName) {
1327 Integer result = null;
1328
1329 try {
1330 if (taxonName != null && (taxonName.isInstanceOf(NonViralName.class))) {
1331 NonViralName nonViralName = CdmBase.deproxy(taxonName, NonViralName.class);
1332 Set<NomenclaturalStatus> states = nonViralName.getStatus();
1333 if (states.size() == 1) {
1334 NomenclaturalStatus state = states.iterator().next();
1335 NomenclaturalStatusType statusType = null;
1336 if (state != null) {
1337 statusType = state.getType();
1338 }
1339 if (statusType != null) {
1340 result = PesiTransformer.nomStatus2nomStatusFk(statusType);
1341 }
1342 } else if (states.size() > 1) {
1343 logger.error("This TaxonName has more than one Nomenclatural Status: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
1344 }
1345 }
1346
1347 } catch (Exception e) {
1348 e.printStackTrace();
1349 }
1350 return result;
1351 }
1352
1353 /**
1354 * Returns the <code>NameStatusCache</code> attribute.
1355 * @param taxon The {@link TaxonBase Taxon}.
1356 * @return The <code>NameStatusCache</code> attribute.
1357 * @see MethodMapper
1358 */
1359 @SuppressWarnings("unused")
1360 private static String getNameStatusCache(TaxonNameBase taxonName) {
1361 String result = null;
1362
1363 try {
1364 if (taxonName != null && (taxonName.isInstanceOf(NonViralName.class))) {
1365 NonViralName nonViralName = CdmBase.deproxy(taxonName, NonViralName.class);
1366 Set<NomenclaturalStatus> states = nonViralName.getStatus();
1367 if (states.size() == 1) {
1368 NomenclaturalStatus state = states.iterator().next();
1369 if (state != null) {
1370 result = PesiTransformer.nomStatus2NomStatusCache(state.getType());
1371 }
1372 } else if (states.size() > 1) {
1373 logger.error("This TaxonName has more than one Nomenclatural Status: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
1374 }
1375 }
1376
1377 } catch (Exception e) {
1378 e.printStackTrace();
1379 }
1380 return result;
1381 }
1382
1383 /**
1384 * Returns the <code>TaxonStatusFk</code> attribute.
1385 * @param taxon The {@link TaxonBase Taxon}.
1386 * @return The <code>TaxonStatusFk</code> attribute.
1387 * @see MethodMapper
1388 */
1389 @SuppressWarnings("unused")
1390 private static Integer getTaxonStatusFk(TaxonNameBase taxonName, PesiExportState state) {
1391 Integer result = null;
1392
1393 try {
1394 if (isAuctReference(taxonName, state)) {
1395 Synonym synonym = Synonym.NewInstance(null, null);
1396
1397 // This works as long as only the instance is important to differentiate between TaxonStatus.
1398 result = PesiTransformer.taxonBase2statusFk(synonym); // Auct References are treated as Synonyms in Datawarehouse now.
1399 } else {
1400 Set taxa = taxonName.getTaxa();
1401 if (taxa.size() == 1) {
1402 result = PesiTransformer.taxonBase2statusFk((TaxonBase<?>) taxa.iterator().next());
1403 } else if (taxa.size() > 1) {
1404 logger.warn("This TaxonName has " + taxa.size() + " Taxa: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
1405 }
1406
1407 Set synonyms = taxonName.getSynonyms();
1408 if (synonyms.size() == 1) {
1409 result = PesiTransformer.taxonBase2statusFk((TaxonBase<?>) synonyms.iterator().next());
1410 } else if (synonyms.size() > 1) {
1411 logger.warn("This TaxonName has " + synonyms.size() + " Synonyms: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
1412 }
1413 }
1414
1415 } catch (Exception e) {
1416 e.printStackTrace();
1417 }
1418 return result;
1419 }
1420
1421 /**
1422 * Returns the <code>TaxonStatusCache</code> attribute.
1423 * @param taxon The {@link TaxonBase Taxon}.
1424 * @return The <code>TaxonStatusCache</code> attribute.
1425 * @see MethodMapper
1426 */
1427 @SuppressWarnings("unused")
1428 private static String getTaxonStatusCache(TaxonNameBase taxonName, PesiExportState state) {
1429 String result = null;
1430
1431 try {
1432 if (isAuctReference(taxonName, state)) {
1433 Synonym synonym = Synonym.NewInstance(null, null);
1434
1435 // This works as long as only the instance is important to differentiate between TaxonStatus.
1436 result = PesiTransformer.taxonBase2statusCache(synonym); // Auct References are treated as Synonyms in Datawarehouse now.
1437 } else {
1438 Set taxa = taxonName.getTaxa();
1439 if (taxa.size() == 1) {
1440 result = PesiTransformer.taxonBase2statusCache((TaxonBase<?>) taxa.iterator().next());
1441 } else if (taxa.size() > 1) {
1442 logger.warn("This TaxonName has " + taxa.size() + " Taxa: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
1443 }
1444
1445 Set synonyms = taxonName.getSynonyms();
1446 if (synonyms.size() == 1) {
1447 result = PesiTransformer.taxonBase2statusCache((TaxonBase<?>) synonyms.iterator().next());
1448 } else if (synonyms.size() > 1) {
1449 logger.warn("This TaxonName has " + synonyms.size() + " Synonyms: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
1450 }
1451 }
1452
1453 } catch (Exception e) {
1454 e.printStackTrace();
1455 }
1456 return result;
1457 }
1458
1459 /**
1460 * Returns the <code>TypeNameFk</code> attribute.
1461 * @param taxon The {@link TaxonBase Taxon}.
1462 * @return The <code>TypeNameFk</code> attribute.
1463 * @see MethodMapper
1464 */
1465 private static Integer getTypeNameFk(TaxonNameBase taxonNameBase, PesiExportState state) {
1466 Integer result = null;
1467 if (taxonNameBase != null) {
1468 Set<NameTypeDesignation> nameTypeDesignations = taxonNameBase.getNameTypeDesignations();
1469 if (nameTypeDesignations.size() == 1) {
1470 NameTypeDesignation nameTypeDesignation = nameTypeDesignations.iterator().next();
1471 if (nameTypeDesignation != null) {
1472 TaxonNameBase typeName = nameTypeDesignation.getTypeName();
1473 if (typeName != null) {
1474 result = state.getDbId(typeName);
1475 }
1476 }
1477 } else if (nameTypeDesignations.size() > 1) {
1478 logger.warn("This TaxonName has " + nameTypeDesignations.size() + " NameTypeDesignations: " + taxonNameBase.getUuid() + " (" + taxonNameBase.getTitleCache() + ")");
1479 }
1480 }
1481 return result;
1482 }
1483
1484 /**
1485 * Returns the <code>TypeFullnameCache</code> attribute.
1486 * @param taxon The {@link TaxonBase Taxon}.
1487 * @return The <code>TypeFullnameCache</code> attribute.
1488 * @see MethodMapper
1489 */
1490 @SuppressWarnings("unused")
1491 private static String getTypeFullnameCache(TaxonNameBase taxonName) {
1492 String result = null;
1493
1494 try {
1495 if (taxonName != null) {
1496 Set<NameTypeDesignation> nameTypeDesignations = taxonName.getNameTypeDesignations();
1497 if (nameTypeDesignations.size() == 1) {
1498 NameTypeDesignation nameTypeDesignation = nameTypeDesignations.iterator().next();
1499 if (nameTypeDesignation != null) {
1500 TaxonNameBase typeName = nameTypeDesignation.getTypeName();
1501 if (typeName != null) {
1502 result = typeName.getTitleCache();
1503 }
1504 }
1505 } else if (nameTypeDesignations.size() > 1) {
1506 logger.warn("This TaxonName has " + nameTypeDesignations.size() + " NameTypeDesignations: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
1507 }
1508 }
1509
1510 } catch (Exception e) {
1511 e.printStackTrace();
1512 }
1513 return result;
1514 }
1515
1516 /**
1517 * Returns the <code>QualityStatusFk</code> attribute.
1518 * @param taxon The {@link TaxonBase Taxon}.
1519 * @return The <code>QualityStatusFk</code> attribute.
1520 * @see MethodMapper
1521 */
1522 @SuppressWarnings("unused")
1523 private static Integer getQualityStatusFk(TaxonNameBase taxonName) {
1524 // TODO: Not represented in CDM right now. Depends on import.
1525 Integer result = null;
1526 return result;
1527 }
1528
1529 /**
1530 * Returns the <code>QualityStatusCache</code> attribute.
1531 * @param taxon The {@link TaxonBase Taxon}.
1532 * @return The <code>QualityStatusCache</code> attribute.
1533 * @see MethodMapper
1534 */
1535 @SuppressWarnings("unused")
1536 private static String getQualityStatusCache(TaxonNameBase taxonName) {
1537 // TODO: Not represented in CDM right now. Depends on import.
1538 String result = null;
1539 return result;
1540 }
1541
1542 /**
1543 * Returns the <code>TypeDesignationStatusFk</code> attribute.
1544 * @param taxon The {@link TaxonBase Taxon}.
1545 * @return The <code>TypeDesignationStatusFk</code> attribute.
1546 * @see MethodMapper
1547 */
1548 @SuppressWarnings("unused")
1549 private static Integer getTypeDesignationStatusFk(TaxonNameBase taxonName) {
1550 Integer result = null;
1551
1552 try {
1553 if (taxonName != null) {
1554 Set<NameTypeDesignation> typeDesignations = taxonName.getNameTypeDesignations();
1555 if (typeDesignations.size() == 1) {
1556 Object obj = typeDesignations.iterator().next().getTypeStatus();
1557 NameTypeDesignationStatus designationStatus = CdmBase.deproxy(obj, NameTypeDesignationStatus.class);
1558 result = PesiTransformer.nameTypeDesignationStatus2TypeDesignationStatusId(designationStatus);
1559 } else if (typeDesignations.size() > 1) {
1560 logger.error("Found a TaxonName with more than one NameTypeDesignation: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
1561 }
1562 }
1563
1564 } catch (Exception e) {
1565 e.printStackTrace();
1566 }
1567 return result;
1568 }
1569
1570 /**
1571 * Returns the <code>TypeDesignationStatusCache</code> attribute.
1572 * @param taxon The {@link TaxonBase Taxon}.
1573 * @return The <code>TypeDesignationStatusCache</code> attribute.
1574 * @see MethodMapper
1575 */
1576 @SuppressWarnings("unused")
1577 private static String getTypeDesignationStatusCache(TaxonNameBase taxonName) {
1578 String result = null;
1579
1580 try {
1581 if (taxonName != null) {
1582 Set<NameTypeDesignation> typeDesignations = taxonName.getNameTypeDesignations();
1583 if (typeDesignations.size() == 1) {
1584 Object obj = typeDesignations.iterator().next().getTypeStatus();
1585 NameTypeDesignationStatus designationStatus = CdmBase.deproxy(obj, NameTypeDesignationStatus.class);
1586 result = PesiTransformer.nameTypeDesignationStatus2TypeDesignationStatusCache(designationStatus);
1587 } else if (typeDesignations.size() > 1) {
1588 logger.error("Found a TaxonName with more than one NameTypeDesignation: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
1589 }
1590 }
1591
1592 } catch (Exception e) {
1593 e.printStackTrace();
1594 }
1595 return result;
1596 }
1597
1598 /**
1599 * Returns the <code>FossilStatusFk</code> attribute.
1600 * @param taxon The {@link TaxonBase Taxon}.
1601 * @return The <code>FossilStatusFk</code> attribute.
1602 * @see MethodMapper
1603 */
1604 @SuppressWarnings("unused")
1605 private static Integer getFossilStatusFk(TaxonNameBase taxonNameBase) {
1606 Integer result = null;
1607 // Taxon taxon;
1608 // if (taxonBase.isInstanceOf(Taxon.class)) {
1609 // taxon = CdmBase.deproxy(taxonBase, Taxon.class);
1610 // Set<TaxonDescription> specimenDescription = taxon.;
1611 // result = PesiTransformer.fossil2FossilStatusId(fossil);
1612 // }
1613 return result;
1614 }
1615
1616 /**
1617 * Returns the <code>FossilStatusCache</code> attribute.
1618 * @param taxon The {@link TaxonBase Taxon}.
1619 * @return The <code>FossilStatusCache</code> attribute.
1620 * @see MethodMapper
1621 */
1622 @SuppressWarnings("unused")
1623 private static String getFossilStatusCache(TaxonNameBase taxonName) {
1624 // TODO
1625 String result = null;
1626 return result;
1627 }
1628
1629 /**
1630 * Returns the <code>IdInSource</code> attribute.
1631 * @param taxon The {@link TaxonBase Taxon}.
1632 * @return The <code>IdInSource</code> attribute.
1633 * @see MethodMapper
1634 */
1635 @SuppressWarnings("unused")
1636 private static String getIdInSource(TaxonNameBase taxonName) {
1637 String result = null;
1638
1639 try {
1640 Set<IdentifiableSource> sources = getSources(taxonName);
1641 for (IdentifiableSource source : sources) {
1642 result = "TAX_ID: " + source.getIdInSource();
1643 String sourceIdNameSpace = source.getIdNamespace();
1644 if (sourceIdNameSpace != null) {
1645 if (sourceIdNameSpace.equals("originalGenusId")) {
1646 result = "Nominal Taxon from TAX_ID: " + source.getIdInSource();
1647 } else if (sourceIdNameSpace.equals("InferredEpithetOf")) {
1648 result = "Inferred epithet from TAX_ID: " + source.getIdInSource();
1649 } else if (sourceIdNameSpace.equals("InferredGenusOf")) {
1650 result = "Inferred genus from TAX_ID: " + source.getIdInSource();
1651 } else if (sourceIdNameSpace.equals("PotentialCombinationOf")) {
1652 result = "Potential combination from TAX_ID: " + source.getIdInSource();
1653 } else {
1654 result = "TAX_ID: " + source.getIdInSource();
1655 }
1656 }
1657 }
1658 } catch (Exception e) {
1659 e.printStackTrace();
1660 }
1661
1662 if (result == null) {
1663 logger.error("IdInSource is NULL for this taxonName: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() +")");
1664 }
1665 return result;
1666 }
1667
1668 /**
1669 * Returns the idInSource only.
1670 * @param taxonName
1671 * @return
1672 */
1673 private static String getIdInSourceOnly(TaxonNameBase taxonName) {
1674 String result = null;
1675
1676 // Get the sources first
1677 Set<IdentifiableSource> sources = getSources(taxonName);
1678
1679 // Determine the idInSource
1680 if (sources.size() == 1) {
1681 IdentifiableSource source = sources.iterator().next();
1682 if (source != null) {
1683 result = source.getIdInSource();
1684 }
1685 } else if (sources.size() > 1) {
1686 int count = 1;
1687 result = "";
1688 for (IdentifiableSource source : sources) {
1689 result += source.getIdInSource();
1690 if (count < sources.size()) {
1691 result += "; ";
1692 }
1693 count++;
1694 }
1695
1696 }
1697
1698 return result;
1699 }
1700
1701 /**
1702 * Returns the Sources only.
1703 * @param taxonName
1704 * @return
1705 */
1706 private static Set<IdentifiableSource> getSources(TaxonNameBase taxonName) {
1707 Set<IdentifiableSource> sources = null;
1708
1709 // Sources from TaxonName
1710 Set<IdentifiableSource> nameSources = taxonName.getSources();
1711 sources = nameSources;
1712 if (nameSources.size() > 1) {
1713 logger.warn("This TaxonName has more than one Source: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
1714 }
1715
1716 // Sources from TaxonBase
1717 if (sources == null || sources.isEmpty()) {
1718 Set<Taxon> taxa = taxonName.getTaxa();
1719 Set<Synonym> synonyms = taxonName.getSynonyms();
1720 if (taxa.size() == 1) {
1721 Taxon taxon = taxa.iterator().next();
1722
1723 if (taxon != null) {
1724 sources = taxon.getSources();
1725 }
1726 } else if (taxa.size() > 1) {
1727 logger.warn("This TaxonName has " + taxa.size() + " Taxa: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() +")");
1728 }
1729 if (synonyms.size() == 1) {
1730 Synonym synonym = synonyms.iterator().next();
1731
1732 if (synonym != null) {
1733 sources = synonym.getSources();
1734 }
1735 } else if (synonyms.size() > 1) {
1736 logger.warn("This TaxonName has " + synonyms.size() + " Synonyms: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() +")");
1737 }
1738 }
1739
1740 if (sources == null || sources.isEmpty()) {
1741 logger.error("This TaxonName has no Sources: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() +")");
1742 }
1743 return sources;
1744 }
1745
1746 /**
1747 * Returns the <code>GUID</code> attribute.
1748 * @param taxon The {@link TaxonBase Taxon}.
1749 * @return The <code>GUID</code> attribute.
1750 * @see MethodMapper
1751 */
1752 private static String getGUID(TaxonNameBase taxonName) {
1753 String result = null;
1754 try {
1755 result = "urn:lsid:faunaeur.org:taxname:" + getIdInSourceOnly(taxonName);
1756 } catch (Exception e) {
1757 logger.error("Text could not be excluded from idInSource for taxonName: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() +")");
1758 e.printStackTrace();
1759 }
1760 return result;
1761 }
1762
1763 /**
1764 * Returns the <code>DerivedFromGuid</code> attribute.
1765 * @param taxon The {@link TaxonBase Taxon}.
1766 * @return The <code>DerivedFromGuid</code> attribute.
1767 * @see MethodMapper
1768 */
1769 @SuppressWarnings("unused")
1770 private static String getDerivedFromGuid(TaxonNameBase taxonName) {
1771 String result = null;
1772 try {
1773 // The same as GUID for now
1774 result = getGUID(taxonName);
1775 } catch (Exception e) {
1776 e.printStackTrace();
1777 }
1778 return result;
1779 }
1780
1781 /**
1782 *
1783 * @param taxonName
1784 * @return
1785 */
1786 @SuppressWarnings("unused")
1787 private static String getCacheCitation(TaxonNameBase taxonName) {
1788 String result = "";
1789 try {
1790 String originalDb = getOriginalDB(taxonName);
1791 if (originalDb == null) {
1792 // logger.error("OriginalDB is NULL for this TaxonName: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
1793 } else if (originalDb.equals("ERMS")) {
1794 // TODO: 19.08.2010: An import of CacheCitation does not exist in the ERMS import yet or it will be imported in a different way...
1795 // So the following code is some kind of harmless assumption.
1796 Set<Extension> extensions = taxonName.getExtensions();
1797 for (Extension extension : extensions) {
1798 if (extension.getType().equals(cacheCitationExtensionType)) {
1799 result = extension.getValue();
1800 }
1801 }
1802 } else {
1803 String expertName = getExpertName(taxonName);
1804 String webShowName = getWebShowName(taxonName);
1805
1806 // idInSource only
1807 String idInSource = getIdInSourceOnly(taxonName);
1808
1809 // build the cacheCitation
1810 if (expertName != null) {
1811 result += expertName + ". ";
1812 } else {
1813 // logger.error("ExpertName could not be determined for this TaxonName: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
1814 }
1815 if (webShowName != null) {
1816 result += webShowName + ". ";
1817 } else {
1818 // logger.error("WebShowName could not be determined for this TaxonName: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
1819 }
1820
1821 if (getOriginalDB(taxonName).equals("FaEu")) {
1822 result += "Accessed through: Fauna Europaea at http://faunaeur.org/full_results.php?id=";
1823 } else if (getOriginalDB(taxonName).equals("EM")) {
1824 result += "Accessed through: Euro+Med PlantBase at http://ww2.bgbm.org/euroPlusMed/PTaxonDetail.asp?UUID=";
1825 }
1826
1827 if (idInSource != null) {
1828 result += idInSource;
1829 } else {
1830 // logger.error("IdInSource could not be determined for this TaxonName: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
1831 }
1832 }
1833 } catch (Exception e) {
1834 e.printStackTrace();
1835 }
1836
1837 if ("".equals(result)) {
1838 return null;
1839 } else {
1840 return result;
1841 }
1842 }
1843
1844 /**
1845 * Returns the <code>OriginalDB</code> attribute.
1846 * @param taxon The {@link TaxonBase Taxon}.
1847 * @return The <code>OriginalDB</code> attribute.
1848 * @see MethodMapper
1849 */
1850 private static String getOriginalDB(TaxonNameBase taxonName) {
1851 String result = "";
1852 try {
1853
1854 // Sources from TaxonName
1855 Set<IdentifiableSource> sources = taxonName.getSources();
1856
1857 IdentifiableEntity taxonBase = null;
1858 if (sources != null && sources.isEmpty()) {
1859 // Sources from Taxa or Synonyms
1860 Set taxa = taxonName.getTaxa();
1861 if (taxa.size() == 1) {
1862 taxonBase = (IdentifiableEntity) taxa.iterator().next();
1863 sources = taxonBase.getSources();
1864 } else if (taxa.size() > 1) {
1865 logger.warn("This TaxonName has " + taxa.size() + " Taxa: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() +")");
1866 }
1867 Set synonyms = taxonName.getSynonyms();
1868 if (synonyms.size() == 1) {
1869 taxonBase = (IdentifiableEntity) synonyms.iterator().next();
1870 sources = taxonBase.getSources();
1871 } else if (synonyms.size() > 1) {
1872 logger.warn("This TaxonName has " + synonyms.size() + " Synonyms: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() +")");
1873 }
1874 }
1875
1876 if (sources != null && ! sources.isEmpty()) {
1877 if (sources.size() == 1) {
1878 IdentifiableSource source = sources.iterator().next();
1879 if (source != null) {
1880 ReferenceBase citation = source.getCitation();
1881 if (citation != null) {
1882 result = PesiTransformer.databaseString2Abbreviation(citation.getTitleCache());
1883 }
1884 }
1885 } else if (sources.size() > 1) {
1886 int count = 1;
1887 for (IdentifiableSource source : sources) {
1888 ReferenceBase citation = source.getCitation();
1889 if (citation != null) {
1890 if (count > 1) {
1891 result += "; ";
1892 }
1893 result += PesiTransformer.databaseString2Abbreviation(citation.getTitleCache());
1894 count++;
1895 }
1896 }
1897 } else {
1898 result = null;
1899 }
1900 }
1901
1902 } catch (Exception e) {
1903 e.printStackTrace();
1904 }
1905 if ("".equals(result)) {
1906 return null;
1907 } else {
1908 return result;
1909 }
1910 }
1911
1912 /**
1913 * Returns the <code>LastAction</code> attribute.
1914 * @param taxon The {@link TaxonBase Taxon}.
1915 * @return The <code>LastAction</code> attribute.
1916 * @see MethodMapper
1917 */
1918 @SuppressWarnings("unused")
1919 private static String getLastAction(TaxonNameBase taxonName) {
1920 String result = null;
1921 try {
1922 Set<Extension> extensions = taxonName.getExtensions();
1923 for (Extension extension : extensions) {
1924 if (extension.getType().equals(lastActionExtensionType)) {
1925 result = extension.getValue();
1926 }
1927 }
1928 } catch (Exception e) {
1929 e.printStackTrace();
1930 }
1931 return result;
1932 }
1933
1934 /**
1935 * Returns the <code>LastActionDate</code> attribute.
1936 * @param taxon The {@link TaxonBase Taxon}.
1937 * @return The <code>LastActionDate</code> attribute.
1938 * @see MethodMapper
1939 */
1940 @SuppressWarnings({ "unused" })
1941 private static DateTime getLastActionDate(TaxonNameBase taxonName) {
1942 DateTime result = null;
1943 try {
1944 Set<Extension> extensions = taxonName.getExtensions();
1945 for (Extension extension : extensions) {
1946 if (extension.getType().equals(lastActionDateExtensionType)) {
1947 String dateTime = extension.getValue();
1948 if (dateTime != null) {
1949 DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss.S");
1950 result = formatter.parseDateTime(dateTime);
1951 }
1952 }
1953 }
1954 } catch (Exception e) {
1955 e.printStackTrace();
1956 }
1957 return result;
1958 }
1959
1960 /**
1961 * Returns the <code>ExpertName</code> attribute.
1962 * @param taxon The {@link TaxonBase Taxon}.
1963 * @return The <code>ExpertName</code> attribute.
1964 * @see MethodMapper
1965 */
1966 private static String getExpertName(TaxonNameBase taxonName) {
1967 String result = null;
1968 try {
1969 Set<Extension> extensions = taxonName.getExtensions();
1970 for (Extension extension : extensions) {
1971 if (extension.getType().equals(expertNameExtensionType)) {
1972 result = extension.getValue();
1973 }
1974 }
1975 } catch (Exception e) {
1976 e.printStackTrace();
1977 }
1978 return result;
1979 }
1980
1981 /**
1982 * Returns the <code>ExpertFk</code> attribute.
1983 * @param taxon The {@link TaxonBase Taxon}.
1984 * @return The <code>ExpertFk</code> attribute.
1985 * @see MethodMapper
1986 */
1987 private static Integer getExpertFk(ReferenceBase reference, PesiExportState state) {
1988 Integer result = state.getDbId(reference);
1989 return result;
1990 }
1991
1992 /**
1993 * Returns the <code>SpeciesExpertName</code> attribute.
1994 * @param taxon The {@link TaxonBase Taxon}.
1995 * @return The <code>SpeciesExpertName</code> attribute.
1996 * @see MethodMapper
1997 */
1998 @SuppressWarnings("unused")
1999 private static String getSpeciesExpertName(TaxonNameBase taxonName) {
2000 String result = null;
2001 try {
2002 Set<Extension> extensions = taxonName.getExtensions();
2003 for (Extension extension : extensions) {
2004 if (extension.getType().equals(speciesExpertNameExtensionType)) {
2005 result = extension.getValue();
2006 }
2007 }
2008 } catch (Exception e) {
2009 e.printStackTrace();
2010 }
2011 return result;
2012 }
2013
2014 /**
2015 * Returns the <code>SpeciesExpertFk</code> attribute.
2016 * @param taxon The {@link TaxonBase Taxon}.
2017 * @return The <code>SpeciesExpertFk</code> attribute.
2018 * @see MethodMapper
2019 */
2020 private static Integer getSpeciesExpertFk(ReferenceBase reference, PesiExportState state) {
2021 Integer result = state.getDbId(reference);
2022 return result;
2023 }
2024
2025 /**
2026 *
2027 * @param taxonName
2028 * @param state
2029 * @return
2030 */
2031 @SuppressWarnings("unused")
2032 private static Integer getSourceFk(TaxonNameBase taxonName, PesiExportState state) {
2033 Integer result = null;
2034
2035 try {
2036 TaxonBase taxonBase = getSourceTaxonBase(taxonName);
2037
2038 if (taxonBase != null) {
2039 result = state.getDbId(taxonBase.getSec());
2040 }
2041 } catch (Exception e) {
2042 e.printStackTrace();
2043 }
2044 return result;
2045 }
2046
2047 /**
2048 * Checks whether a Reference of a TaxonName's TaxonBase is an Auct Reference.
2049 * @param taxonName
2050 * @param state
2051 * @return
2052 */
2053 private static boolean isAuctReference(TaxonNameBase taxonName, PesiExportState state) {
2054 boolean result = false;
2055
2056 if (isMisappliedName(taxonName)) {
2057 result = true;
2058 }
2059 return result;
2060 }
2061
2062 /**
2063 * Determines the TaxonBase of a TaxonName.
2064 * @param taxonName
2065 * @return
2066 */
2067 private static TaxonBase getSourceTaxonBase(TaxonNameBase taxonName) {
2068 TaxonBase taxonBase = null;
2069 Set taxa = taxonName.getTaxa();
2070 if (taxa.size() == 1) {
2071 taxonBase = CdmBase.deproxy(taxa.iterator().next(), TaxonBase.class);
2072 } else if (taxa.size() > 1) {
2073 logger.warn("This TaxonName has " + taxa.size() + " Taxa: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
2074 }
2075
2076 Set synonyms = taxonName.getSynonyms();
2077 if (synonyms.size() == 1) {
2078 taxonBase = CdmBase.deproxy(synonyms.iterator().next(), TaxonBase.class);
2079 } else if (synonyms.size() > 1) {
2080 logger.warn("This TaxonName has " + synonyms.size() + " Synonyms: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
2081 }
2082 return taxonBase;
2083 }
2084
2085 /**
2086 * Returns the CDM to PESI specific export mappings.
2087 * @return The {@link PesiExportMapping PesiExportMapping}.
2088 */
2089 private PesiExportMapping getMapping() {
2090 PesiExportMapping mapping = new PesiExportMapping(dbTableName);
2091 ExtensionType extensionType = null;
2092
2093 mapping.addMapper(IdMapper.NewInstance("TaxonId"));
2094 mapping.addMapper(MethodMapper.NewInstance("SourceFK", this.getClass(), "getSourceFk", standardMethodParameter, PesiExportState.class));
2095 mapping.addMapper(MethodMapper.NewInstance("GenusOrUninomial", this));
2096 mapping.addMapper(MethodMapper.NewInstance("InfraGenericEpithet", this));
2097 mapping.addMapper(MethodMapper.NewInstance("SpecificEpithet", this));
2098 mapping.addMapper(MethodMapper.NewInstance("InfraSpecificEpithet", this));
2099 mapping.addMapper(MethodMapper.NewInstance("WebSearchName", this));
2100 mapping.addMapper(MethodMapper.NewInstance("WebShowName", this));
2101 mapping.addMapper(MethodMapper.NewInstance("AuthorString", this));
2102 mapping.addMapper(MethodMapper.NewInstance("FullName", this));
2103 mapping.addMapper(MethodMapper.NewInstance("NomRefString", this));
2104
2105 // DisplayName
2106 extensionType = (ExtensionType)getTermService().find(ErmsTransformer.uuidDisplayName);
2107 if (extensionType != null) {
2108 mapping.addMapper(DbExtensionMapper.NewInstance(extensionType, "DisplayName"));
2109 } else {
2110 mapping.addMapper(MethodMapper.NewInstance("DisplayName", this));
2111 }
2112
2113 // FuzzyName
2114 // extensionType = (ExtensionType)getTermService().find(ErmsTransformer.uuidFuzzyName);
2115 // if (extensionType != null) {
2116 // mapping.addMapper(DbExtensionMapper.NewInstance(extensionType, "FuzzyName"));
2117 // } else {
2118 // mapping.addMapper(MethodMapper.NewInstance("FuzzyName", this));
2119 // }
2120
2121 mapping.addMapper(MethodMapper.NewInstance("NameStatusFk", this));
2122 mapping.addMapper(MethodMapper.NewInstance("NameStatusCache", this));
2123 mapping.addMapper(MethodMapper.NewInstance("TaxonStatusFk", this.getClass(), "getTaxonStatusFk", standardMethodParameter, PesiExportState.class));
2124 mapping.addMapper(MethodMapper.NewInstance("TaxonStatusCache", this.getClass(), "getTaxonStatusCache", standardMethodParameter, PesiExportState.class));
2125 // mapping.addMapper(MethodMapper.NewInstance("TypeNameFk", this.getClass(), "getTypeNameFk", standardMethodParameter, PesiExportState.class));
2126 mapping.addMapper(MethodMapper.NewInstance("TypeFullnameCache", this));
2127
2128 // QualityStatus (Fk, Cache)
2129 extensionType = (ExtensionType)getTermService().find(ErmsTransformer.uuidQualityStatus);
2130 if (extensionType != null) {
2131 mapping.addMapper(DbExtensionMapper.NewInstance(extensionType, "QualityStatusCache"));
2132 } else {
2133 mapping.addMapper(MethodMapper.NewInstance("QualityStatusCache", this));
2134 }
2135 mapping.addMapper(MethodMapper.NewInstance("QualityStatusFk", this)); // PesiTransformer.QualityStatusCache2QualityStatusFk?
2136
2137 mapping.addMapper(MethodMapper.NewInstance("TypeDesignationStatusFk", this));
2138 mapping.addMapper(MethodMapper.NewInstance("TypeDesignationStatusCache", this));
2139
2140 // FossilStatus (Fk, Cache)
2141 extensionType = (ExtensionType)getTermService().find(ErmsTransformer.uuidFossilStatus);
2142 if (extensionType != null) {
2143 mapping.addMapper(DbExtensionMapper.NewInstance(extensionType, "FossilStatusCache"));
2144 } else {
2145 mapping.addMapper(MethodMapper.NewInstance("FossilStatusCache", this));
2146 }
2147 mapping.addMapper(MethodMapper.NewInstance("FossilStatusFk", this)); // PesiTransformer.FossilStatusCache2FossilStatusFk?
2148
2149 mapping.addMapper(MethodMapper.NewInstance("IdInSource", this));
2150 mapping.addMapper(MethodMapper.NewInstance("GUID", this));
2151 mapping.addMapper(MethodMapper.NewInstance("DerivedFromGuid", this));
2152 mapping.addMapper(MethodMapper.NewInstance("CacheCitation", this));
2153 mapping.addMapper(MethodMapper.NewInstance("OriginalDB", this));
2154 mapping.addMapper(MethodMapper.NewInstance("LastAction", this));
2155 mapping.addMapper(MethodMapper.NewInstance("LastActionDate", this));
2156 mapping.addMapper(MethodMapper.NewInstance("ExpertName", this));
2157 // mapping.addMapper(MethodMapper.NewInstance("ExpertFk", this.getClass(), "getExpertFk", standardMethodParameter, PesiExportState.class));
2158 mapping.addMapper(MethodMapper.NewInstance("SpeciesExpertName", this));
2159 // mapping.addMapper(MethodMapper.NewInstance("SpeciesExpertFk", this.getClass(), "getSpeciesExpertFk", standardMethodParameter, PesiExportState.class));
2160
2161 return mapping;
2162 }
2163 }