(no commit message)
[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.SQLException;
15 import java.util.ArrayList;
16 import java.util.HashMap;
17 import java.util.List;
18 import java.util.Set;
19 import java.util.UUID;
20 import java.util.regex.Matcher;
21 import java.util.regex.Pattern;
22
23 import org.apache.log4j.Logger;
24 import org.joda.time.DateTime;
25 import org.springframework.stereotype.Component;
26 import org.springframework.transaction.TransactionStatus;
27
28 import eu.etaxonomy.cdm.common.CdmUtils;
29 import eu.etaxonomy.cdm.io.berlinModel.out.mapper.IdMapper;
30 import eu.etaxonomy.cdm.io.berlinModel.out.mapper.MethodMapper;
31 import eu.etaxonomy.cdm.io.common.Source;
32 import eu.etaxonomy.cdm.model.common.Annotation;
33 import eu.etaxonomy.cdm.model.common.AnnotationType;
34 import eu.etaxonomy.cdm.model.common.CdmBase;
35 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
36 import eu.etaxonomy.cdm.model.common.IdentifiableSource;
37 import eu.etaxonomy.cdm.model.common.Language;
38 import eu.etaxonomy.cdm.model.common.VersionableEntity;
39 import eu.etaxonomy.cdm.model.name.NameTypeDesignation;
40 import eu.etaxonomy.cdm.model.name.NameTypeDesignationStatus;
41 import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
42 import eu.etaxonomy.cdm.model.name.NomenclaturalStatus;
43 import eu.etaxonomy.cdm.model.name.NomenclaturalStatusType;
44 import eu.etaxonomy.cdm.model.name.NonViralName;
45 import eu.etaxonomy.cdm.model.name.Rank;
46 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
47 import eu.etaxonomy.cdm.model.reference.ReferenceBase;
48 import eu.etaxonomy.cdm.model.taxon.Taxon;
49 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
50 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
51 import eu.etaxonomy.cdm.model.taxon.TaxonomicTree;
52
53 /**
54 * @author a.mueller
55 * @author e.-m.lee
56 * @date 23.02.2010
57 *
58 */
59 @Component
60 @SuppressWarnings("unchecked")
61 public class PesiTaxonExport extends PesiExportBase {
62 private static final Logger logger = Logger.getLogger(PesiTaxonExport.class);
63 private static final Class<? extends CdmBase> standardMethodParameter = TaxonNameBase.class;
64
65 private static int modCount = 1000;
66 private static final String dbTableName = "Taxon";
67 private static final String pluralString = "Taxa";
68 private PreparedStatement parentTaxonFk_TreeIndex_KingdomFkStmt;
69 private NomenclaturalCode nomenclaturalCode;
70 private Integer kingdomFk;
71 private HashMap<Rank, Rank> rankMap = new HashMap<Rank, Rank>();
72 private List<Rank> rankList = new ArrayList<Rank>();
73 private static final UUID uuidTreeIndex = UUID.fromString("28f4e205-1d02-4d3a-8288-775ea8413009");
74 private AnnotationType treeIndexAnnotationType;
75
76 /**
77 * @return the treeIndexAnnotationType
78 */
79 protected AnnotationType getTreeIndexAnnotationType() {
80 return treeIndexAnnotationType;
81 }
82
83 /**
84 * @param treeIndexAnnotationType the treeIndexAnnotationType to set
85 */
86 protected void setTreeIndexAnnotationType(AnnotationType treeIndexAnnotationType) {
87 this.treeIndexAnnotationType = treeIndexAnnotationType;
88 }
89
90 enum NamePosition {
91 beginning,
92 end,
93 between,
94 alone,
95 nowhere
96 }
97
98 public PesiTaxonExport() {
99 super();
100 }
101
102 /* (non-Javadoc)
103 * @see eu.etaxonomy.cdm.io.common.DbExportBase#getStandardMethodParameter()
104 */
105 @Override
106 public Class<? extends CdmBase> getStandardMethodParameter() {
107 return standardMethodParameter;
108 }
109
110 /* (non-Javadoc)
111 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doCheck(eu.etaxonomy.cdm.io.common.IoStateBase)
112 */
113 @Override
114 protected boolean doCheck(PesiExportState state) {
115 boolean result = true;
116 return result;
117 }
118
119 /* (non-Javadoc)
120 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doInvoke(eu.etaxonomy.cdm.io.common.IoStateBase)
121 */
122 @Override
123 protected boolean doInvoke(PesiExportState state) {
124 try {
125 logger.error("*** Started Making " + pluralString + " ...");
126
127 // Prepare TreeIndex-And-KingdomFk-Statement
128 Connection connection = state.getConfig().getDestination().getConnection();
129 String parentTaxonFk_TreeIndex_KingdomFkSql = "UPDATE Taxon SET ParentTaxonFk = ?, TreeIndex = ?, " +
130 "KingdomFk = ?, RankFk = ?, RankCache = ? WHERE TaxonId = ?";
131 parentTaxonFk_TreeIndex_KingdomFkStmt = connection.prepareStatement(parentTaxonFk_TreeIndex_KingdomFkSql);
132
133 // Get the limit for objects to save within a single transaction.
134 int limit = state.getConfig().getLimitSave();
135
136 // Stores whether this invoke was successful or not.
137 boolean success = true;
138
139 // PESI: Clear the database table Taxon.
140 doDelete(state);
141
142 // CDM: Get the number of all available taxa.
143 // int maxCount = getTaxonService().count(null);
144 // logger.error("Total amount of " + maxCount + " " + pluralString + " will be exported.");
145
146 // Get specific mappings: (CDM) Taxon -> (PESI) Taxon
147 PesiExportMapping mapping = getMapping();
148
149 // Initialize the db mapper
150 mapping.initialize(state);
151
152 int count = 0;
153 int pastCount = 0;
154 TransactionStatus txStatus = null;
155 List<TaxonNameBase> list = null;
156
157 // 1st Round: Make Taxa
158 logger.error("PHASE 1...");
159 // Start transaction
160 txStatus = startTransaction(true);
161 logger.error("Started new transaction. Fetching some " + pluralString + " (max: " + limit + ") ...");
162 while ((list = getNameService().list(null, limit, count, null, null)).size() > 0) {
163
164 logger.error("Fetched " + list.size() + " " + pluralString + ". Exporting...");
165 for (TaxonNameBase taxonName : list) {
166 doCount(count++, modCount, pluralString);
167 success &= mapping.invoke(taxonName);
168
169 // Check whether some rules are violated
170 nomenclaturalCode = taxonName.getNomenclaturalCode();
171 String genusOrUninomial = getGenusOrUninomial(taxonName);
172 String specificEpithet = getSpecificEpithet(taxonName);
173 String infraSpecificEpithet = getInfraSpecificEpithet(taxonName);
174 String infraGenericEpithet = getInfraGenericEpithet(taxonName);
175 Integer rank = getRankFk(taxonName, nomenclaturalCode);
176
177 if (rank == null) {
178 logger.error("Rank was not determined: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
179 } else {
180 if (infraGenericEpithet == null && rank.intValue() == 190) {
181 logger.error("InfraSpecificEpithet was not determined although it should exist for rank 190: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
182 }
183 if (specificEpithet != null && rank.intValue() < 220) {
184 logger.error("SpecificEpithet was determined for rank " + rank + " although it should only exist for ranks higher or equal to 220: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
185 }
186 if (infraSpecificEpithet != null && rank.intValue() < 230) {
187 logger.error("InfraSpecificEpithet was determined for rank " + rank + " although it should only exist for ranks higher or equal to 230: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
188 }
189 }
190 if (infraSpecificEpithet != null && specificEpithet == null) {
191 logger.error("An infraSpecificEpithet was determined, but a specificEpithet was not determined: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
192 }
193 if (genusOrUninomial == null) {
194 logger.error("GenusOrUninomial was not determined: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
195 }
196
197 }
198
199 // Commit transaction
200 commitTransaction(txStatus);
201 logger.error("Committed transaction.");
202 logger.error("Exported " + (count - pastCount) + " " + pluralString + ". Total: " + count);
203 pastCount = count;
204
205 // Start transaction
206 txStatus = startTransaction(true);
207 logger.error("Started new transaction. Fetching some " + pluralString + " (max: " + limit + ") ...");
208 }
209 if (list.size() == 0) {
210 logger.error("No " + pluralString + " left to fetch.");
211 }
212 // Commit transaction
213 commitTransaction(txStatus);
214 logger.error("Committed transaction.");
215
216 count = 0;
217 pastCount = 0;
218 List<TaxonomicTree> taxonomicTreeList = null;
219 // 2nd Round: Add ParentTaxonFk, TreeIndex, Rank and KingdomFk to each Taxon
220 logger.error("PHASE 2...");
221
222 // Specify starting ranks for tree traversing
223 rankList.add(Rank.KINGDOM());
224 rankList.add(Rank.GENUS());
225
226 // Specify where to stop traversing (value) when starting at a specific Rank (key)
227 rankMap.put(Rank.GENUS(), null); // Since NULL does not match an existing Rank, traverse all the way down to the leafs
228 rankMap.put(Rank.KINGDOM(), Rank.GENUS()); // excludes rank genus
229
230 StringBuffer treeIndex = new StringBuffer();
231
232 // Retrieve list of Taxonomic Trees
233 txStatus = startTransaction(true);
234 logger.error("Started transaction. Fetching all Taxonomic Trees...");
235 taxonomicTreeList = getTaxonTreeService().listTaxonomicTrees(null, 0, null, null);
236 commitTransaction(txStatus);
237 logger.error("Committed transaction.");
238
239 logger.error("Fetched " + taxonomicTreeList.size() + " Taxonomic Tree.");
240
241 setTreeIndexAnnotationType(getAnnotationType(uuidTreeIndex, "TreeIndex", "", "TI"));
242
243 for (TaxonomicTree taxonomicTree : taxonomicTreeList) {
244 for (Rank rank : rankList) {
245
246 txStatus = startTransaction(true);
247 logger.error("Started transaction to fetch all rootNodes specific to Rank " + rank.getLabel() + " ...");
248
249 List<TaxonNode> rankSpecificRootNodes = getTaxonTreeService().loadRankSpecificRootNodes(taxonomicTree, rank, null);
250 logger.error("Fetched " + rankSpecificRootNodes.size() + " RootNodes for Rank " + rank.getLabel());
251
252 commitTransaction(txStatus);
253 logger.error("Committed transaction.");
254
255 // int elementCount = 0;
256 // int halfCount = rankSpecificRootNodes.size() / 2;
257
258 for (TaxonNode rootNode : rankSpecificRootNodes) {
259 txStatus = startTransaction(false);
260 Rank endRank = rankMap.get(rank);
261 if (endRank != null) {
262 logger.error("Started transaction to traverse childNodes of rootNode (" + rootNode.getUuid() + ") till Rank " + endRank.getLabel() + " ...");
263 } else {
264 logger.error("Started transaction to traverse childNodes of rootNode (" + rootNode.getUuid() + ") till leafs are reached ...");
265 }
266
267 TaxonNode newNode = getTaxonNodeService().load(rootNode.getUuid());
268
269 TaxonNode parentNode = newNode.getParent();
270 if (rank.equals(Rank.KINGDOM())) {
271 treeIndex = new StringBuffer();
272 treeIndex.append("#");
273 } else {
274 // Get treeIndex from parentNode
275 if (parentNode != null) {
276 boolean annotationFound = false;
277 Set<Annotation> annotations = parentNode.getAnnotations();
278 for (Annotation annotation : annotations) {
279 AnnotationType annotationType = annotation.getAnnotationType();
280 if (annotationType != null && annotationType.equals(getTreeIndexAnnotationType())) {
281 // It is assumed that there is only one annotation using AnnotationType TREEINDEX. If there are more only one is noticed.
282 treeIndex = new StringBuffer(CdmUtils.Nz(annotation.getText()));
283 annotationFound = true;
284 logger.error("treeIndex: " + treeIndex);
285 break;
286 }
287 }
288 if (!annotationFound) {
289 // This should not happen because it means that the treeIndex was not set correctly as an annotation to parentNode
290 logger.error("TreeIndex could not be read from annotation of this TaxonNode: " + parentNode.getUuid());
291 treeIndex = new StringBuffer();
292 treeIndex.append("#");
293 }
294 } else {
295 // TreeIndex could not be determined, but it's unclear how to proceed to generate a correct treeIndex if the parentNode is NULL
296 logger.error("ParentNode for RootNode is NULL. TreeIndex could not be determined: " + newNode.getUuid());
297 treeIndex = new StringBuffer(); // This just prevents growing of the treeIndex in a wrong manner
298 treeIndex.append("#");
299 }
300 }
301
302 nomenclaturalCode = newNode.getTaxon().getName().getNomenclaturalCode();
303 kingdomFk = PesiTransformer.nomenClaturalCode2Kingdom(nomenclaturalCode);
304 traverseTree(newNode, parentNode, treeIndex, rankMap.get(rank), state);
305
306 commitTransaction(txStatus);
307 logger.error("Committed transaction.");
308
309 // elementCount++;
310 // if (elementCount == halfCount) {
311 // logger.error("50% of " + rank.getLabel() + " RootNodes processed...");
312 // }
313 }
314 }
315 }
316
317 logger.error("*** Finished Making " + pluralString + " ..." + getSuccessString(success));
318
319 return success;
320 } catch (SQLException e) {
321 e.printStackTrace();
322 logger.error(e.getMessage());
323 return false;
324 }
325 }
326
327 /**
328 * Returns the AnnotationType for a given UUID.
329 * @param state
330 * @param uuid
331 * @param label
332 * @param text
333 * @param labelAbbrev
334 * @return
335 */
336 protected AnnotationType getAnnotationType(UUID uuid, String label, String text, String labelAbbrev){
337 AnnotationType annotationType = (AnnotationType)getTermService().find(uuid);
338 if (annotationType == null) {
339 annotationType = AnnotationType.NewInstance(label, text, labelAbbrev);
340 annotationType.setUuid(uuid);
341 // annotationType.setVocabulary(AnnotationType.EDITORIAL().getVocabulary());
342 getTermService().save(annotationType);
343 }
344 return annotationType;
345 }
346
347 /**
348 * Traverses the TaxonTree recursively and stores determined values for every Taxon.
349 * @param childNode
350 * @param parentNode
351 * @param treeIndex
352 * @param fetchLevel
353 * @param state
354 */
355 private void traverseTree(TaxonNode childNode, TaxonNode parentNode, StringBuffer treeIndex, Rank fetchLevel, PesiExportState state) {
356 // Traverse all branches from this childNode until specified fetchLevel is reached.
357 StringBuffer localTreeIndex = new StringBuffer(treeIndex);
358 if (childNode.getTaxon() != null) {
359 TaxonNameBase taxonName = childNode.getTaxon().getName();
360 Integer taxonNameId = state.getDbId(taxonName);
361 if (taxonNameId != null) {
362 Rank childTaxonNameRank = taxonName.getRank();
363 if (childTaxonNameRank != null) {
364 if (! childTaxonNameRank.equals(fetchLevel)) {
365
366 localTreeIndex.append(taxonNameId);
367 localTreeIndex.append("#");
368
369 saveData(childNode, parentNode, localTreeIndex, state, taxonNameId);
370
371 // Store treeIndex as annotation for further use
372 Annotation annotation = Annotation.NewInstance(localTreeIndex.toString(), getTreeIndexAnnotationType(), Language.DEFAULT());
373 childNode.addAnnotation(annotation);
374
375 for (TaxonNode newNode : childNode.getChildNodes()) {
376 traverseTree(newNode, childNode, localTreeIndex, fetchLevel, state);
377 }
378
379 } else {
380 // logger.error("Target Rank " + fetchLevel.getLabel() + " reached");
381 return;
382 }
383 } else {
384 logger.error("Rank is NULL. FetchLevel can not be checked: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
385 }
386 } else {
387 logger.error("TaxonName can not be found in State: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
388 }
389
390 } else {
391 logger.error("Taxon is NULL for TaxonNode: " + childNode.getUuid());
392 }
393 }
394
395 /**
396 * Stores values in database for every recursive round.
397 * @param childNode
398 * @param parentNode
399 * @param treeIndex
400 * @param state
401 * @param currentTaxonFk
402 */
403 private void saveData(TaxonNode childNode, TaxonNode parentNode, StringBuffer treeIndex, PesiExportState state, Integer currentTaxonFk) {
404 // We are differentiating kingdoms by the nomenclatural code for now.
405 // This needs to be handled in a better way as soon as we know how to differentiate between more kingdoms.
406 Taxon childNodeTaxon = childNode.getTaxon();
407 TaxonNameBase childNodeTaxonName = childNode.getTaxon().getName();
408 if (childNodeTaxon != null && childNodeTaxonName != null) {
409 TaxonNameBase parentNodeTaxonName = null;
410 if (parentNode != null) {
411 Taxon parentNodeTaxon = parentNode.getTaxon();
412 if (parentNodeTaxon != null) {
413 parentNodeTaxonName = parentNodeTaxon.getName();
414 }
415 }
416
417 invokeParentTaxonFkAndTreeIndexAndKingdomFk(childNodeTaxonName,
418 nomenclaturalCode,
419 kingdomFk,
420 state.getDbId(parentNodeTaxonName),
421 currentTaxonFk,
422 treeIndex);
423 }
424
425 }
426
427 /**
428 * Inserts values into the Taxon database table.
429 * @param taxonNameBase
430 * @param state
431 * @param stmt
432 * @return
433 */
434 protected boolean invokeParentTaxonFkAndTreeIndexAndKingdomFk(TaxonNameBase taxonName, NomenclaturalCode nomenclaturalCode, Integer kingdomFk, Integer parentTaxonFk, Integer currentTaxonFk, StringBuffer treeIndex) {
435 try {
436 if (parentTaxonFk != null) {
437 parentTaxonFk_TreeIndex_KingdomFkStmt.setInt(1, parentTaxonFk);
438 } else {
439 parentTaxonFk_TreeIndex_KingdomFkStmt.setObject(1, parentTaxonFk);
440 }
441 parentTaxonFk_TreeIndex_KingdomFkStmt.setString(2, treeIndex.toString());
442 parentTaxonFk_TreeIndex_KingdomFkStmt.setInt(3, kingdomFk);
443 parentTaxonFk_TreeIndex_KingdomFkStmt.setInt(4, getRankFk(taxonName, nomenclaturalCode));
444 parentTaxonFk_TreeIndex_KingdomFkStmt.setString(5, getRankCache(taxonName, nomenclaturalCode));
445 parentTaxonFk_TreeIndex_KingdomFkStmt.setInt(6, currentTaxonFk);
446 parentTaxonFk_TreeIndex_KingdomFkStmt.executeUpdate();
447 return true;
448 } catch (SQLException e) {
449 logger.error("SQLException during treeIndex invoke for taxonName - " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + "): " + e.getMessage());
450 logger.error("parentTaxonFk: " + parentTaxonFk);
451 logger.error("treeIndex: " + treeIndex);
452 logger.error("kingdomFk: " + kingdomFk);
453 logger.error("rankFk: " + getRankFk(taxonName, nomenclaturalCode));
454 logger.error("rankCache: " + getRankCache(taxonName, nomenclaturalCode));
455 logger.error("taxonFk: " + currentTaxonFk);
456 // e.printStackTrace();
457 return false;
458 }
459 }
460
461 /**
462 * Deletes all entries of database tables related to <code>Taxon</code>.
463 * @param state The PesiExportState
464 * @return Whether the delete operation was successful or not.
465 */
466 protected boolean doDelete(PesiExportState state) {
467 PesiExportConfigurator pesiConfig = (PesiExportConfigurator) state.getConfig();
468
469 String sql;
470 Source destination = pesiConfig.getDestination();
471
472 // Clear Taxon
473 sql = "DELETE FROM " + dbTableName;
474 destination.setQuery(sql);
475 destination.update(sql);
476 return true;
477 }
478
479 /* (non-Javadoc)
480 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IoStateBase)
481 */
482 @Override
483 protected boolean isIgnore(PesiExportState state) {
484 return ! state.getConfig().isDoTaxa();
485 }
486
487 /**
488 * Returns the <code>RankFk</code> attribute.
489 * @param taxon The {@link TaxonBase Taxon}.
490 * @return The <code>RankFk</code> attribute.
491 * @see MethodMapper
492 */
493 private static Integer getRankFk(TaxonNameBase taxonName, NomenclaturalCode nomenclaturalCode) {
494 Integer result = null;
495 if (nomenclaturalCode != null) {
496 if (taxonName != null && taxonName.getRank() == null) {
497 logger.warn("Rank is null: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
498 }
499 result = PesiTransformer.rank2RankId(taxonName.getRank(), PesiTransformer.nomenClaturalCode2Kingdom(nomenclaturalCode));
500 if (result == null) {
501 logger.warn("Rank " + taxonName.getRank().getLabel() + " could not be determined for PESI-Kingdom-Id " + PesiTransformer.nomenClaturalCode2Kingdom(nomenclaturalCode));
502 }
503 }
504 return result;
505 }
506
507 /**
508 * Returns the <code>RankCache</code> attribute.
509 * @param taxon The {@link TaxonBase Taxon}.
510 * @return The <code>RankCache</code> attribute.
511 * @see MethodMapper
512 */
513 private static String getRankCache(TaxonNameBase taxonName, NomenclaturalCode nomenclaturalCode) {
514 String result = null;
515 if (nomenclaturalCode != null) {
516 result = PesiTransformer.rank2RankCache(taxonName.getRank(), PesiTransformer.nomenClaturalCode2Kingdom(nomenclaturalCode));
517 }
518 return result;
519 }
520
521 /**
522 *
523 * @param taxon The {@link TaxonBase Taxon}.
524 * @return Whether it's genus or uninomial.
525 * @see MethodMapper
526 */
527 private static String getGenusOrUninomial(TaxonNameBase taxonName) {
528 String result = null;
529 if (taxonName != null && (taxonName.isInstanceOf(NonViralName.class))) {
530 NonViralName nonViralName = CdmBase.deproxy(taxonName, NonViralName.class);
531 result = nonViralName.getGenusOrUninomial();
532 }
533 return result;
534 }
535
536 /**
537 * Returns the <code>InfraGenericEpithet</code> attribute.
538 * @param taxon The {@link TaxonBase Taxon}.
539 * @return The <code>InfraGenericEpithet</code> attribute.
540 * @see MethodMapper
541 */
542 private static String getInfraGenericEpithet(TaxonNameBase taxonName) {
543 String result = null;
544 if (taxonName != null && (taxonName.isInstanceOf(NonViralName.class))) {
545 NonViralName nonViralName = CdmBase.deproxy(taxonName, NonViralName.class);
546 result = nonViralName.getInfraGenericEpithet();
547 }
548 return result;
549 }
550
551 /**
552 * Returns the <code>SpecificEpithet</code> attribute.
553 * @param taxon The {@link TaxonBase Taxon}.
554 * @return The <code>SpecificEpithet</code> attribute.
555 * @see MethodMapper
556 */
557 private static String getSpecificEpithet(TaxonNameBase taxonName) {
558 String result = null;
559 if (taxonName != null && (taxonName.isInstanceOf(NonViralName.class))) {
560 NonViralName nonViralName = CdmBase.deproxy(taxonName, NonViralName.class);
561 result = nonViralName.getSpecificEpithet();
562 }
563 return result;
564 }
565
566 /**
567 * Returns the <code>InfraSpecificEpithet</code> attribute.
568 * @param taxon The {@link TaxonBase Taxon}.
569 * @return The <code>InfraSpecificEpithet</code> attribute.
570 * @see MethodMapper
571 */
572 private static String getInfraSpecificEpithet(TaxonNameBase taxonName) {
573 String result = null;
574 if (taxonName != null && (taxonName.isInstanceOf(NonViralName.class))) {
575 NonViralName nonViralName = CdmBase.deproxy(taxonName, NonViralName.class);
576 result = nonViralName.getInfraSpecificEpithet();
577 }
578 return result;
579 }
580
581 /**
582 * Returns the <code>WebSearchName</code> attribute.
583 * @param taxon The {@link TaxonBase Taxon}.
584 * @return The <code>WebSearchName</code> attribute.
585 * @see MethodMapper
586 */
587 @SuppressWarnings("unused")
588 private static String getWebSearchName(TaxonNameBase taxonName) {
589 String result = null;
590 if (taxonName != null && (taxonName.isInstanceOf(NonViralName.class))) {
591 NonViralName nonViralName = CdmBase.deproxy(taxonName, NonViralName.class);
592 result = nonViralName.getNameCache();
593 }
594 return result;
595 }
596
597 /**
598 * Returns the <code>WebShowName</code> attribute.
599 * @param taxon The {@link TaxonBase Taxon}.
600 * @return The <code>WebShowName</code> attribute.
601 * @see MethodMapper
602 */
603 @SuppressWarnings("unused")
604 private static String getWebShowName(TaxonNameBase taxonName) {
605 String result = null;
606 try {
607 if (taxonName != null) {
608 if (taxonName != null && taxonName.isInstanceOf(NonViralName.class)) {
609 NonViralName nonViralName = CdmBase.deproxy(taxonName, NonViralName.class);
610 String singleWhitespace = "\\s";
611 String multipleWhitespaces = "\\s*";
612 String whitespaceOrNothing = "\\s?";
613 String singleBlank = " ";
614 String anyNumberOfCharacters = ".*";
615 String backSlashRegEx = "\\";
616 // String periodRegEx = "\\.";
617 // String asterixRegEx = "\\*";
618 String questionMarkRegEx = "\\?";
619 // String plusRegEx = "\\+";
620 // String squareBracketRegEx = "\\[";
621 // String curlyBracketRegEx = "\\{";
622 // String pipeRegEx = "\\|";
623 // String accentRegEx = "\\^";
624 // String dollarSignRegEx = "\\$";
625 String openingParenthesisRegEx = "\\(";
626 String closingParenthesisRegEx = "\\)";
627 String openParenthesis = "(";
628 String closeParenthesis = ")";
629 String italicBeginTag = "<i>";
630 String italicEndTag = "</i>";
631 String endAnchor = "$";
632
633 String questionMarkReplacement = backSlashRegEx + questionMarkRegEx;
634 // String backSlashReplacement = backSlashRegEx + backSlashRegEx;
635 // String periodReplacement = backSlashRegEx + periodRegEx;
636 // String asterixReplacement = backSlashRegEx + asterixRegEx;
637 // String plusReplacement = backSlashRegEx + plusRegEx;
638 // String squareBracketReplacement = backSlashRegEx + squareBracketRegEx;
639 // String curlyBracketReplacement = backSlashRegEx + curlyBracketRegEx;
640 // String pipeReplacement = backSlashRegEx + pipeRegEx;
641 // String accentReplacement = backSlashRegEx + accentRegEx;
642 // String dollarSignReplacement = backSlashRegEx + dollarSignRegEx;
643
644 if (nonViralName != null) {
645 if (nonViralName.getTitleCache() != null) {
646 try {
647 String fullName = nonViralName.getTitleCache();
648
649 // This deals with question marks that are reserved in regular expressions
650 fullName = fullName.replaceAll(questionMarkRegEx, questionMarkReplacement);
651
652 String genusOrUninomial = nonViralName.getGenusOrUninomial();
653 String infraGenericEpithet = nonViralName.getInfraGenericEpithet();
654 if (infraGenericEpithet != null) {
655 infraGenericEpithet = openParenthesis + infraGenericEpithet + closeParenthesis;
656 }
657 String specificEpithet = nonViralName.getSpecificEpithet();
658 String infraSpecificEpithet = nonViralName.getInfraSpecificEpithet();
659
660 StringBuffer replaceFullName = new StringBuffer(fullName);
661 List<NamePosition> genusOrUninomialPosition = getPosition(genusOrUninomial, fullName);
662 List<NamePosition> infraGenericEpithetPosition = getPosition(infraGenericEpithet, fullName);
663 List<NamePosition> specificEpithetPosition = getPosition(specificEpithet, fullName);
664 List<NamePosition> authorshipPosition = getPosition(specificEpithet, fullName);
665 if (nameExists(genusOrUninomialPosition) || nameExists(infraGenericEpithetPosition) || nameExists(specificEpithetPosition)) {
666 replaceFullName.insert(0, italicBeginTag);
667
668 if (nameExists(specificEpithetPosition)) {
669 boolean insertSpecificEpithetEndTag = true;
670
671 if ((specificEpithet.equals(infraSpecificEpithet) && countPattern(infraSpecificEpithet, fullName) == 2) |
672 (! specificEpithet.equals(infraSpecificEpithet) && countPattern(infraSpecificEpithet, fullName) == 1)) {
673 // infraSpecificEpithet exists
674
675 // Determine position of infraSpecificEpithet
676 int infraSpecificEpithetLocation = replaceFullName.lastIndexOf(infraSpecificEpithet);
677 int infraSpecificEpithetBeginLocation = infraSpecificEpithetLocation;
678 int infraSpecificEpithetEndLocation = infraSpecificEpithetLocation + infraSpecificEpithet.length();
679
680 // Check whether rank information exists between specificEpithet and infraSpecificEpithet
681 String rankExistsRegEx = specificEpithet + singleWhitespace + anyNumberOfCharacters + singleWhitespace + infraSpecificEpithet;
682 List<NamePosition> rankPosition = getPosition(rankExistsRegEx, fullName);
683 if (rankPosition != null && nameExists(rankPosition)) {
684 // Rank information exists
685
686 // Insert italicBeginTag
687 replaceFullName.insert(infraSpecificEpithetBeginLocation, italicBeginTag);
688
689 // Check position of infraSpecificEpithet
690 List<NamePosition> infraSpecificEpithetPosition = getPosition(infraSpecificEpithet, fullName);
691 if (infraSpecificEpithetPosition != null) {
692 if (infraSpecificEpithetPosition.contains(NamePosition.end)) {
693 // Append italicEndTag
694 replaceFullName.append(italicEndTag);
695 } else {
696 // Insert italicEndTag
697 replaceFullName.insert(infraSpecificEpithetEndLocation + italicBeginTag.length(), italicEndTag);
698 }
699 }
700 } else if (rankPosition != null && ! nameExists(rankPosition)) {
701 // Rank information does not exist
702 insertSpecificEpithetEndTag = false;
703
704 // Insert italicEndTag
705 replaceFullName.insert(infraSpecificEpithetEndLocation + italicBeginTag.length(), italicEndTag);
706 }
707 }
708
709 // Insert an italicEndTag for the specificEpithet
710 if (insertSpecificEpithetEndTag) {
711 int specificEpithetLocation = replaceFullName.indexOf(specificEpithet) + specificEpithet.length();
712 if (specificEpithetPosition.contains(NamePosition.end)) {
713 replaceFullName.append(italicEndTag);
714 } else {
715 replaceFullName.insert(specificEpithetLocation, italicEndTag);
716 }
717 }
718 } else if (nameExists(infraGenericEpithetPosition)) {
719 int infraGenericEpithetLocation = replaceFullName.indexOf(infraGenericEpithet) +
720 openParenthesis.length() + infraGenericEpithet.length() + closeParenthesis.length();
721 if (infraGenericEpithetPosition.contains(NamePosition.end)) {
722 replaceFullName.append(italicEndTag);
723 } else {
724 replaceFullName.insert(infraGenericEpithetLocation, italicEndTag);
725 }
726 } else if (nameExists(genusOrUninomialPosition)) {
727 replaceFullName.insert(genusOrUninomial.length() + italicBeginTag.length(), italicEndTag);
728 }
729 }
730
731 result = replaceFullName.toString();
732
733 } catch (Exception e) {
734 // This needs a workaround since very likely there is a character in the fullName that is reserved in regular expressions
735 logger.error("WebShowName could not be determined for NonViralName " + nonViralName.getUuid() + " (" + nonViralName.getTitleCache() + "): " + e.getMessage());
736 // e.printStackTrace();
737 result = nonViralName.getTitleCache();
738 }
739 } else {
740 logger.error("WebShowName could not be determined: TitleCache is NULL for NonViralName " + nonViralName.getUuid() + " (" + nonViralName.getTitleCache() + ")");
741 }
742 } else {
743 logger.error("WebShowName could not be determined: NonViralName is NULL for TaxonName" + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
744 }
745
746 }
747 } else {
748 logger.warn("WebShowName could not be determined: TaxonName is NULL");
749 }
750
751 // logger.error("final result: " + result);
752 } catch (Exception e) {
753 e.printStackTrace();
754 }
755 return result;
756 }
757
758 /**
759 *
760 * @param searchString
761 * @param searchedString
762 * @return
763 */
764 private static Integer countPattern(String searchString, String searchedString) {
765 Integer count = 0;
766 if (searchString != null && searchedString != null) {
767 Integer index = 0;
768 while ((index = searchedString.indexOf(searchString, index)) != -1) {
769 count++;
770 index++;
771 }
772 } else {
773 // logger.error("Either searchString or searchedString is NULL");
774 }
775 return count;
776 }
777
778 /**
779 * @param namePosition
780 * @return
781 */
782 private static boolean nameExists(List<NamePosition> namePosition) {
783 boolean result = false;
784 if (namePosition != null) {
785 if (namePosition.contains(NamePosition.nowhere)) {
786 result = false;
787 } else {
788 result = true;
789 }
790 }
791 return result;
792 }
793
794
795 private static List<NamePosition> getPosition(String name, String targetString) {
796 List<NamePosition> result = new ArrayList<NamePosition>();
797 boolean touched = false;
798 if (name != null && targetString != null) {
799 if ("".equals(name.trim())) {
800 result.add(NamePosition.nowhere);
801 } else {
802 String beginningAnchor = "^";
803 String endAnchor = "$";
804 String anyNumberOfCharacters = ".*";
805
806 String beginningRegEx = beginningAnchor + name;
807 String endRegEx = name + endAnchor;
808 String middleRegEx = anyNumberOfCharacters + name + anyNumberOfCharacters;
809 if (stringExists(beginningRegEx, targetString)) {
810 result.add(NamePosition.beginning);
811 touched = true;
812 }
813 if (stringExists(endRegEx, targetString)) {
814 result.add(NamePosition.end);
815 touched = true;
816 }
817 if (stringExists(middleRegEx, targetString)) {
818 if (result.contains(NamePosition.beginning) && result.contains(NamePosition.end)) {
819 result.add(NamePosition.alone);
820 } else {
821 result.add(NamePosition.between);
822 }
823 touched = true;
824 }
825 if (!touched) {
826 result.add(NamePosition.nowhere);
827 }
828 }
829 } else {
830 // logger.error("Either name or targetString is NULL");
831 result = null;
832 }
833 return result;
834 }
835
836
837 /**
838 * @param beginningRegEx
839 * @param targetString
840 */
841 private static boolean stringExists(String regEx, String targetString) {
842 Pattern pattern = Pattern.compile(regEx);
843 Matcher matcher = pattern.matcher(targetString);
844 if (matcher.find()) {
845 return true;
846 } else {
847 return false;
848 }
849 }
850
851 /**
852 * Returns the <code>AuthorString</code> attribute.
853 * @param taxon The {@link TaxonBase Taxon}.
854 * @return The <code>AuthorString</code> attribute.
855 * @see MethodMapper
856 */
857 @SuppressWarnings("unused")
858 private static String getAuthorString(TaxonNameBase taxonName) {
859 String result = null;
860 if (taxonName != null && taxonName != null) {
861 if (taxonName.isInstanceOf(NonViralName.class)) {
862 NonViralName nonViralName = CdmBase.deproxy(taxonName, NonViralName.class);
863 result = nonViralName.getAuthorshipCache();
864 } else {
865 logger.warn("TaxonName is not of instance NonViralName: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
866 }
867 }
868 return result;
869 }
870
871 /**
872 * Returns the <code>FullName</code> attribute.
873 * @param taxon The {@link TaxonBase Taxon}.
874 * @return The <code>FullName</code> attribute.
875 * @see MethodMapper
876 */
877 @SuppressWarnings("unused")
878 private static String getFullName(TaxonNameBase taxonName) {
879 if (taxonName != null) {
880 return taxonName.getTitleCache();
881 } else {
882 return null;
883 }
884 }
885
886 /**
887 * Returns the <code>NomRefString</code> attribute.
888 * @param taxon The {@link TaxonBase Taxon}.
889 * @return The <code>NomRefString</code> attribute.
890 * @see MethodMapper
891 */
892 @SuppressWarnings("unused")
893 private static String getNomRefString(TaxonNameBase taxonName) {
894 String result = null;
895 if (taxonName != null) {
896 try {
897 result = taxonName.getNomenclaturalMicroReference();
898 } catch (Exception e) {
899 logger.error("While getting NomRefString");
900 e.printStackTrace();
901 }
902 }
903 return result;
904 }
905
906 /**
907 * Returns the <code>DisplayName</code> attribute.
908 * @param taxon The {@link TaxonBase Taxon}.
909 * @return The <code>DisplayName</code> attribute.
910 * @see MethodMapper
911 */
912 @SuppressWarnings("unused")
913 private static String getDisplayName(TaxonNameBase taxonName) {
914 // TODO: extension?
915 if (taxonName != null) {
916 return taxonName.getFullTitleCache();
917 } else {
918 return null;
919 }
920 }
921
922 /**
923 * Returns the <code>FuzzyName</code> attribute.
924 * @param taxon The {@link TaxonBase Taxon}.
925 * @return The <code>FuzzyName</code> attribute.
926 * @see MethodMapper
927 */
928 @SuppressWarnings("unused")
929 private static String getFuzzyName(TaxonNameBase taxonName) {
930 // TODO: extension
931 return null;
932 }
933
934 /**
935 * Returns the <code>NameStatusFk</code> attribute.
936 * @param taxon The {@link TaxonBase Taxon}.
937 * @return The <code>NameStatusFk</code> attribute.
938 * @see MethodMapper
939 */
940 @SuppressWarnings("unused")
941 private static Integer getNameStatusFk(TaxonNameBase taxonName) {
942 Integer result = null;
943
944 try {
945 if (taxonName != null && (taxonName.isInstanceOf(NonViralName.class))) {
946 NonViralName nonViralName = CdmBase.deproxy(taxonName, NonViralName.class);
947 Set<NomenclaturalStatus> states = nonViralName.getStatus();
948 if (states.size() == 1) {
949 NomenclaturalStatus state = states.iterator().next();
950 NomenclaturalStatusType statusType = null;
951 if (state != null) {
952 statusType = state.getType();
953 }
954 if (statusType != null) {
955 result = PesiTransformer.nomStatus2nomStatusFk(statusType);
956 }
957 } else if (states.size() > 1) {
958 logger.error("This TaxonName has more than one Nomenclatural Status: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
959 }
960 }
961
962 } catch (Exception e) {
963 e.printStackTrace();
964 }
965 return result;
966 }
967
968 /**
969 * Returns the <code>NameStatusCache</code> attribute.
970 * @param taxon The {@link TaxonBase Taxon}.
971 * @return The <code>NameStatusCache</code> attribute.
972 * @see MethodMapper
973 */
974 @SuppressWarnings("unused")
975 private static String getNameStatusCache(TaxonNameBase taxonName) {
976 String result = null;
977
978 try {
979 if (taxonName != null && (taxonName.isInstanceOf(NonViralName.class))) {
980 NonViralName nonViralName = CdmBase.deproxy(taxonName, NonViralName.class);
981 Set<NomenclaturalStatus> states = nonViralName.getStatus();
982 if (states.size() == 1) {
983 NomenclaturalStatus state = states.iterator().next();
984 if (state != null) {
985 result = PesiTransformer.nomStatus2NomStatusCache(state.getType());
986 }
987 } else if (states.size() > 1) {
988 logger.error("This TaxonName has more than one Nomenclatural Status: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
989 }
990 }
991
992 } catch (Exception e) {
993 e.printStackTrace();
994 }
995 return result;
996 }
997
998 /**
999 * Returns the <code>TaxonStatusFk</code> attribute.
1000 * @param taxon The {@link TaxonBase Taxon}.
1001 * @return The <code>TaxonStatusFk</code> attribute.
1002 * @see MethodMapper
1003 */
1004 @SuppressWarnings("unused")
1005 private static Integer getTaxonStatusFk(TaxonNameBase taxonName) {
1006 Integer result = null;
1007
1008 try {
1009 Set taxa = taxonName.getTaxa();
1010 if (taxa.size() == 1) {
1011 result = PesiTransformer.taxonBase2statusFk((TaxonBase<?>) taxa.iterator().next());
1012 } else if (taxa.size() > 1) {
1013 logger.warn("This TaxonName has " + taxa.size() + " Taxa: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
1014 }
1015
1016 Set synonyms = taxonName.getSynonyms();
1017 if (synonyms.size() == 1) {
1018 result = PesiTransformer.taxonBase2statusFk((TaxonBase<?>) synonyms.iterator().next());
1019 } else if (synonyms.size() > 1) {
1020 logger.warn("This TaxonName has " + synonyms.size() + " Synonyms: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
1021 }
1022
1023 } catch (Exception e) {
1024 e.printStackTrace();
1025 }
1026 return result;
1027 }
1028
1029 /**
1030 * Returns the <code>TaxonStatusCache</code> attribute.
1031 * @param taxon The {@link TaxonBase Taxon}.
1032 * @return The <code>TaxonStatusCache</code> attribute.
1033 * @see MethodMapper
1034 */
1035 @SuppressWarnings("unused")
1036 private static String getTaxonStatusCache(TaxonNameBase taxonName) {
1037 String result = null;
1038
1039 try {
1040 Set taxa = taxonName.getTaxa();
1041 if (taxa.size() == 1) {
1042 result = PesiTransformer.taxonBase2statusCache((TaxonBase<?>) taxa.iterator().next());
1043 } else if (taxa.size() > 1) {
1044 logger.warn("This TaxonName has " + taxa.size() + " Taxa: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
1045 }
1046
1047 Set synonyms = taxonName.getSynonyms();
1048 if (synonyms.size() == 1) {
1049 result = PesiTransformer.taxonBase2statusCache((TaxonBase<?>) synonyms.iterator().next());
1050 } else if (synonyms.size() > 1) {
1051 logger.warn("This TaxonName has " + synonyms.size() + " Synonyms: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
1052 }
1053
1054 } catch (Exception e) {
1055 e.printStackTrace();
1056 }
1057 return result;
1058 }
1059
1060 /**
1061 * Returns the <code>TypeNameFk</code> attribute.
1062 * @param taxon The {@link TaxonBase Taxon}.
1063 * @return The <code>TypeNameFk</code> attribute.
1064 * @see MethodMapper
1065 */
1066 @SuppressWarnings("unused")
1067 private static Integer getTypeNameFk(TaxonNameBase taxonNameBase, PesiExportState state) {
1068 Integer result = null;
1069 // if (taxonNameBase != null) {
1070 // Set<NameTypeDesignation> nameTypeDesignations = taxonNameBase.getNameTypeDesignations();
1071 // if (nameTypeDesignations.size() == 1) {
1072 // NameTypeDesignation nameTypeDesignation = nameTypeDesignations.iterator().next();
1073 // if (nameTypeDesignation != null) {
1074 // TaxonNameBase typeName = nameTypeDesignation.getTypeName();
1075 // if (typeName != null) {
1076 // Set<TaxonBase> taxa = typeName.getTaxa();
1077 // if (taxa.size() == 1) {
1078 // TaxonBase singleTaxon = taxa.iterator().next();
1079 // result = state.getDbId(singleTaxon.getName());
1080 // } else if (taxa.size() > 1) {
1081 // logger.warn("This TaxonName has " + taxa.size() + " Taxa: " + taxonNameBase.getUuid() + " (" + taxonNameBase.getTitleCache() + ")");
1082 // }
1083 // }
1084 // }
1085 // } else if (nameTypeDesignations.size() > 1) {
1086 // logger.warn("This TaxonName has " + nameTypeDesignations.size() + " NameTypeDesignations: " + taxonNameBase.getUuid() + " (" + taxonNameBase.getTitleCache() + ")");
1087 // }
1088 // }
1089 // if (result != null) {
1090 // logger.error("Taxon Id: " + result);
1091 // logger.error("TaxonName: " + taxonNameBase.getUuid() + " (" + taxonNameBase.getTitleCache() +")");
1092 // }
1093 return result;
1094 }
1095
1096 /**
1097 * Returns the <code>TypeFullnameCache</code> attribute.
1098 * @param taxon The {@link TaxonBase Taxon}.
1099 * @return The <code>TypeFullnameCache</code> attribute.
1100 * @see MethodMapper
1101 */
1102 @SuppressWarnings("unused")
1103 private static String getTypeFullnameCache(TaxonNameBase taxonName) {
1104 String result = null;
1105
1106 try {
1107 if (taxonName != null) {
1108 Set<NameTypeDesignation> nameTypeDesignations = taxonName.getNameTypeDesignations();
1109 if (nameTypeDesignations.size() == 1) {
1110 NameTypeDesignation nameTypeDesignation = nameTypeDesignations.iterator().next();
1111 if (nameTypeDesignation != null) {
1112 TaxonNameBase typeName = nameTypeDesignation.getTypeName();
1113 if (typeName != null) {
1114 result = typeName.getTitleCache();
1115 }
1116 }
1117 } else if (nameTypeDesignations.size() > 1) {
1118 logger.warn("This TaxonName has " + nameTypeDesignations.size() + " NameTypeDesignations: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
1119 }
1120 }
1121
1122 } catch (Exception e) {
1123 e.printStackTrace();
1124 }
1125 return result;
1126 }
1127
1128 /**
1129 * Returns the <code>QualityStatusFk</code> attribute.
1130 * @param taxon The {@link TaxonBase Taxon}.
1131 * @return The <code>QualityStatusFk</code> attribute.
1132 * @see MethodMapper
1133 */
1134 @SuppressWarnings("unused")
1135 private static Integer getQualityStatusFk(TaxonNameBase taxonName) {
1136 // TODO: Not represented in CDM right now. Depends on import.
1137 Integer result = null;
1138 return result;
1139 }
1140
1141 /**
1142 * Returns the <code>QualityStatusCache</code> attribute.
1143 * @param taxon The {@link TaxonBase Taxon}.
1144 * @return The <code>QualityStatusCache</code> attribute.
1145 * @see MethodMapper
1146 */
1147 @SuppressWarnings("unused")
1148 private static String getQualityStatusCache(TaxonNameBase taxonName) {
1149 // TODO: Not represented in CDM right now. Depends on import.
1150 String result = null;
1151 return result;
1152 }
1153
1154 /**
1155 * Returns the <code>TypeDesignationStatusFk</code> attribute.
1156 * @param taxon The {@link TaxonBase Taxon}.
1157 * @return The <code>TypeDesignationStatusFk</code> attribute.
1158 * @see MethodMapper
1159 */
1160 @SuppressWarnings("unused")
1161 private static Integer getTypeDesignationStatusFk(TaxonNameBase taxonName) {
1162 Integer result = null;
1163
1164 try {
1165 if (taxonName != null) {
1166 Set<NameTypeDesignation> typeDesignations = taxonName.getNameTypeDesignations();
1167 if (typeDesignations.size() == 1) {
1168 Object obj = typeDesignations.iterator().next().getTypeStatus();
1169 NameTypeDesignationStatus designationStatus = CdmBase.deproxy(obj, NameTypeDesignationStatus.class);
1170 result = PesiTransformer.nameTypeDesignationStatus2TypeDesignationStatusId(designationStatus);
1171 } else if (typeDesignations.size() > 1) {
1172 logger.error("Found a TaxonName with more than one NameTypeDesignation: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
1173 }
1174 }
1175
1176 } catch (Exception e) {
1177 e.printStackTrace();
1178 }
1179 return result;
1180 }
1181
1182 /**
1183 * Returns the <code>TypeDesignationStatusCache</code> attribute.
1184 * @param taxon The {@link TaxonBase Taxon}.
1185 * @return The <code>TypeDesignationStatusCache</code> attribute.
1186 * @see MethodMapper
1187 */
1188 @SuppressWarnings("unused")
1189 private static String getTypeDesignationStatusCache(TaxonNameBase taxonName) {
1190 String result = null;
1191
1192 try {
1193 if (taxonName != null) {
1194 Set<NameTypeDesignation> typeDesignations = taxonName.getNameTypeDesignations();
1195 if (typeDesignations.size() == 1) {
1196 Object obj = typeDesignations.iterator().next().getTypeStatus();
1197 NameTypeDesignationStatus designationStatus = CdmBase.deproxy(obj, NameTypeDesignationStatus.class);
1198 result = PesiTransformer.nameTypeDesignationStatus2TypeDesignationStatusCache(designationStatus);
1199 } else if (typeDesignations.size() > 1) {
1200 logger.error("Found a TaxonName with more than one NameTypeDesignation: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
1201 }
1202 }
1203
1204 } catch (Exception e) {
1205 e.printStackTrace();
1206 }
1207 return result;
1208 }
1209
1210 /**
1211 * Returns the <code>FossilStatusFk</code> attribute.
1212 * @param taxon The {@link TaxonBase Taxon}.
1213 * @return The <code>FossilStatusFk</code> attribute.
1214 * @see MethodMapper
1215 */
1216 @SuppressWarnings("unused")
1217 private static Integer getFossilStatusFk(TaxonNameBase taxonNameBase) {
1218 Integer result = null;
1219 // Taxon taxon;
1220 // if (taxonBase.isInstanceOf(Taxon.class)) {
1221 // taxon = CdmBase.deproxy(taxonBase, Taxon.class);
1222 // Set<TaxonDescription> specimenDescription = taxon.;
1223 // result = PesiTransformer.fossil2FossilStatusId(fossil);
1224 // }
1225 return result;
1226 }
1227
1228 /**
1229 * Returns the <code>FossilStatusCache</code> attribute.
1230 * @param taxon The {@link TaxonBase Taxon}.
1231 * @return The <code>FossilStatusCache</code> attribute.
1232 * @see MethodMapper
1233 */
1234 @SuppressWarnings("unused")
1235 private static String getFossilStatusCache(TaxonNameBase taxonName) {
1236 // TODO
1237 String result = null;
1238 return result;
1239 }
1240
1241 /**
1242 * Returns the <code>IdInSource</code> attribute.
1243 * @param taxon The {@link TaxonBase Taxon}.
1244 * @return The <code>IdInSource</code> attribute.
1245 * @see MethodMapper
1246 */
1247 @SuppressWarnings("unused")
1248 private static String getIdInSource(TaxonNameBase taxonName) {
1249 return null;
1250 // String result = "Nominal Taxon from TAX_ID: ";
1251 // boolean set = false;
1252 //
1253 // try {
1254 // if (taxon != null) {
1255 // TaxonNameBase taxonName = taxon.getName();
1256 // Set taxa = taxonName.getTaxa();
1257 // if (taxa.size() == 1) {
1258 // IdentifiableEntity singleTaxon = (IdentifiableEntity) taxa.iterator().next();
1259 // if (singleTaxon != null) {
1260 // Set<IdentifiableSource> sources = singleTaxon.getSources();
1261 // if (sources.size() == 1) {
1262 // IdentifiableSource source = sources.iterator().next();
1263 // if (source != null) {
1264 // result += source.getIdInSource();
1265 // set = true;
1266 // }
1267 // } else if (sources.size() > 1) {
1268 // logger.warn("Taxon has multiple IdentifiableSources: " + singleTaxon.getUuid() + " (" + singleTaxon.getTitleCache() + ")");
1269 // int count = 1;
1270 // for (IdentifiableSource source : sources) {
1271 // result += source.getIdInSource();
1272 // if (count < sources.size()) {
1273 // result += "; ";
1274 // }
1275 // count++;
1276 // set = true;
1277 // }
1278 // } else {
1279 // result = null;
1280 // }
1281 // }
1282 // } else if (taxa.size() > 1) {
1283 // logger.warn("This TaxonName has " + taxa.size() + " Taxa: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() +")");
1284 // }
1285 // }
1286 //
1287 // } catch (Exception e) {
1288 // e.printStackTrace();
1289 // }
1290 //
1291 // if (set) {
1292 // return result;
1293 // } else {
1294 // return null;
1295 // }
1296 }
1297
1298 /**
1299 * Returns the <code>GUID</code> attribute.
1300 * @param taxon The {@link TaxonBase Taxon}.
1301 * @return The <code>GUID</code> attribute.
1302 * @see MethodMapper
1303 */
1304 @SuppressWarnings("unused")
1305 private static String getGUID(TaxonNameBase taxonName) {
1306 // TODO
1307 String result = null;
1308 return result;
1309 }
1310
1311 /**
1312 * Returns the <code>DerivedFromGuid</code> attribute.
1313 * @param taxon The {@link TaxonBase Taxon}.
1314 * @return The <code>DerivedFromGuid</code> attribute.
1315 * @see MethodMapper
1316 */
1317 @SuppressWarnings("unused")
1318 private static String getDerivedFromGuid(TaxonNameBase taxonName) {
1319 // TODO
1320 String result = null;
1321 return result;
1322 }
1323
1324 /**
1325 * Returns the <code>OriginalDB</code> attribute.
1326 * @param taxon The {@link TaxonBase Taxon}.
1327 * @return The <code>OriginalDB</code> attribute.
1328 * @see MethodMapper
1329 */
1330 @SuppressWarnings("unused")
1331 private static String getOriginalDB(TaxonNameBase taxonName) {
1332 String result = "";
1333 try {
1334 IdentifiableEntity taxonBase = null;
1335 Set taxa = taxonName.getTaxa();
1336 if (taxa.size() == 1) {
1337 taxonBase = (IdentifiableEntity) taxa.iterator().next();
1338 } else if (taxa.size() > 1) {
1339 logger.warn("This TaxonName has " + taxa.size() + " Taxa: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() +")");
1340 }
1341 Set synonyms = taxonName.getSynonyms();
1342 if (synonyms.size() == 1) {
1343 taxonBase = (IdentifiableEntity) synonyms.iterator().next();
1344 } else if (synonyms.size() > 1) {
1345 logger.warn("This TaxonName has " + synonyms.size() + " Synonyms: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() +")");
1346 }
1347
1348 if (taxonBase != null) {
1349 Set<IdentifiableSource> sources = taxonBase.getSources();
1350 if (sources.size() == 1) {
1351 IdentifiableSource source = sources.iterator().next();
1352 if (source != null) {
1353 ReferenceBase citation = source.getCitation();
1354 if (citation != null) {
1355 result = PesiTransformer.databaseString2Abbreviation(citation.getTitleCache());
1356 }
1357 }
1358 } else if (sources.size() > 1) {
1359 logger.warn("Taxon has multiple IdentifiableSources: " + taxonBase.getUuid() + " (" + taxonBase.getTitleCache() + ")");
1360 int count = 1;
1361 for (IdentifiableSource source : sources) {
1362 result += PesiTransformer.databaseString2Abbreviation(source.getCitation().getTitleCache());
1363 if (count < sources.size()) {
1364 result += "; ";
1365 }
1366 count++;
1367 }
1368 } else {
1369 result = null;
1370 }
1371 }
1372
1373 } catch (Exception e) {
1374 e.printStackTrace();
1375 }
1376 if ("".equals(result)) {
1377 return null;
1378 } else {
1379 return result;
1380 }
1381 }
1382
1383 /**
1384 * Returns the <code>LastAction</code> attribute.
1385 * @param taxon The {@link TaxonBase Taxon}.
1386 * @return The <code>LastAction</code> attribute.
1387 * @see MethodMapper
1388 */
1389 @SuppressWarnings("unused")
1390 private static String getLastAction(TaxonNameBase taxonName) {
1391 // TODO
1392 return null;
1393 }
1394
1395 /**
1396 * Returns the <code>LastActionDate</code> attribute.
1397 * @param taxon The {@link TaxonBase Taxon}.
1398 * @return The <code>LastActionDate</code> attribute.
1399 * @see MethodMapper
1400 */
1401 @SuppressWarnings("unused")
1402 private static DateTime getLastActionDate(TaxonNameBase taxonNameBase) {
1403 DateTime result = null;
1404
1405 try {
1406 if (taxonNameBase != null) {
1407 VersionableEntity taxonBase = null;
1408 Set taxa = taxonNameBase.getTaxa();
1409 if (taxa.size() == 1) {
1410 taxonBase = (VersionableEntity) taxa.iterator().next();
1411 } else if (taxa.size() > 1) {
1412 logger.warn("This TaxonName has " + taxa.size() + " Taxa: " + taxonNameBase.getUuid() + " (" + taxonNameBase.getTitleCache() + ")");
1413 }
1414 Set synonyms = taxonNameBase.getSynonyms();
1415 if (synonyms.size() == 1) {
1416 taxonBase = (VersionableEntity) synonyms.iterator().next();
1417 } else if (synonyms.size() > 1) {
1418 logger.warn("This TaxonName has " + synonyms.size() + " Synonyms: " + taxonNameBase.getUuid() + " (" + taxonNameBase.getTitleCache() + ")");
1419 }
1420
1421 if (taxonBase != null) {
1422 DateTime updated = taxonBase.getUpdated();
1423 if (updated != null) {
1424 // logger.error("Taxon Updated: " + updated);
1425 result = new DateTime(updated.toDate()); // Unfortunately the time information gets lost here.
1426 }
1427 }
1428 }
1429
1430 } catch (Exception e) {
1431 e.printStackTrace();
1432 }
1433 return result;
1434 }
1435
1436 /**
1437 * Returns the <code>ExpertName</code> attribute.
1438 * @param taxon The {@link TaxonBase Taxon}.
1439 * @return The <code>ExpertName</code> attribute.
1440 * @see MethodMapper
1441 */
1442 @SuppressWarnings("unused")
1443 private static String getExpertName(TaxonNameBase taxonName) {
1444 // TODO
1445 return null;
1446 }
1447
1448 /**
1449 * Returns the <code>ExpertFk</code> attribute.
1450 * @param taxon The {@link TaxonBase Taxon}.
1451 * @return The <code>ExpertFk</code> attribute.
1452 * @see MethodMapper
1453 */
1454 @SuppressWarnings("unused")
1455 private static String getExpertFk(TaxonNameBase taxonName) {
1456 // TODO
1457 return null;
1458 }
1459
1460 @SuppressWarnings("unused")
1461 private static Integer getSourceFk(TaxonNameBase taxonName, PesiExportState state) {
1462 Integer result = null;
1463
1464 try {
1465 TaxonBase taxonBase = null;
1466 Set taxa = taxonName.getTaxa();
1467 if (taxa.size() == 1) {
1468 taxonBase = CdmBase.deproxy(taxa.iterator().next(), TaxonBase.class);
1469 } else if (taxa.size() > 1) {
1470 logger.warn("This TaxonName has " + taxa.size() + " Taxa: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
1471 }
1472
1473 Set synonyms = taxonName.getSynonyms();
1474 if (synonyms.size() == 1) {
1475 taxonBase = CdmBase.deproxy(synonyms.iterator().next(), TaxonBase.class);
1476 } else if (synonyms.size() > 1) {
1477 logger.warn("This TaxonName has " + synonyms.size() + " Synonyms: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
1478 }
1479
1480 if (taxonBase != null) {
1481 result = state.getDbId(taxonBase.getSec());
1482 }
1483 } catch (Exception e) {
1484 e.printStackTrace();
1485 }
1486 return result;
1487 }
1488
1489 /**
1490 * Returns the CDM to PESI specific export mappings.
1491 * @return The {@link PesiExportMapping PesiExportMapping}.
1492 */
1493 private PesiExportMapping getMapping() {
1494 PesiExportMapping mapping = new PesiExportMapping(dbTableName);
1495
1496 mapping.addMapper(IdMapper.NewInstance("TaxonId"));
1497 mapping.addMapper(MethodMapper.NewInstance("SourceFK", this.getClass(), "getSourceFk", standardMethodParameter, PesiExportState.class));
1498 // mapping.addMapper(MethodMapper.NewInstance("KingdomFk", this.getClass(), "getKingdomFk", standardMethodParameter, PesiExportState.class));
1499 // mapping.addMapper(MethodMapper.NewInstance("RankFk", this));
1500 // mapping.addMapper(MethodMapper.NewInstance("RankCache", this));
1501 mapping.addMapper(MethodMapper.NewInstance("GenusOrUninomial", this));
1502 mapping.addMapper(MethodMapper.NewInstance("InfraGenericEpithet", this));
1503 mapping.addMapper(MethodMapper.NewInstance("SpecificEpithet", this));
1504 mapping.addMapper(MethodMapper.NewInstance("InfraSpecificEpithet", this));
1505 mapping.addMapper(MethodMapper.NewInstance("WebSearchName", this));
1506 mapping.addMapper(MethodMapper.NewInstance("WebShowName", this));
1507 mapping.addMapper(MethodMapper.NewInstance("AuthorString", this));
1508 mapping.addMapper(MethodMapper.NewInstance("FullName", this));
1509 mapping.addMapper(MethodMapper.NewInstance("NomRefString", this));
1510 mapping.addMapper(MethodMapper.NewInstance("DisplayName", this));
1511 mapping.addMapper(MethodMapper.NewInstance("FuzzyName", this));
1512 mapping.addMapper(MethodMapper.NewInstance("NameStatusFk", this));
1513 mapping.addMapper(MethodMapper.NewInstance("NameStatusCache", this));
1514 mapping.addMapper(MethodMapper.NewInstance("TaxonStatusFk", this));
1515 mapping.addMapper(MethodMapper.NewInstance("TaxonStatusCache", this));
1516 mapping.addMapper(MethodMapper.NewInstance("TypeNameFk", this.getClass(), "getTypeNameFk", standardMethodParameter, PesiExportState.class));
1517 mapping.addMapper(MethodMapper.NewInstance("TypeFullnameCache", this));
1518 mapping.addMapper(MethodMapper.NewInstance("QualityStatusFk", this));
1519 mapping.addMapper(MethodMapper.NewInstance("QualityStatusCache", this));
1520 mapping.addMapper(MethodMapper.NewInstance("TypeDesignationStatusFk", this));
1521 mapping.addMapper(MethodMapper.NewInstance("TypeDesignationStatusCache", this));
1522 // mapping.addMapper(MethodMapper.NewInstance("TreeIndex", this.getClass(), "getTreeIndex", standardMethodParameter, PesiExportState.class));
1523 mapping.addMapper(MethodMapper.NewInstance("FossilStatusFk", this));
1524 mapping.addMapper(MethodMapper.NewInstance("FossilStatusCache", this));
1525 mapping.addMapper(MethodMapper.NewInstance("IdInSource", this));
1526 mapping.addMapper(MethodMapper.NewInstance("GUID", this)); // TODO
1527 mapping.addMapper(MethodMapper.NewInstance("DerivedFromGuid", this)); // TODO
1528 mapping.addMapper(MethodMapper.NewInstance("OriginalDB", this));
1529 mapping.addMapper(MethodMapper.NewInstance("LastAction", this));
1530 // mapping.addMapper(DbTimePeriodMapper.NewInstance("updated", "LastActionDate"));
1531 mapping.addMapper(MethodMapper.NewInstance("LastActionDate", this));
1532 mapping.addMapper(MethodMapper.NewInstance("ExpertName", this)); // TODO
1533 mapping.addMapper(MethodMapper.NewInstance("ExpertFk", this)); // TODO
1534
1535 return mapping;
1536 }
1537 }