latest changes for PESI description export and transformer
[cdmlib-apps.git] / cdm-pesi / src / main / java / eu / etaxonomy / cdm / io / pesi / out / PesiRelTaxonExport.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
20 import org.apache.log4j.Logger;
21 import org.springframework.stereotype.Component;
22 import org.springframework.transaction.TransactionStatus;
23
24 import eu.etaxonomy.cdm.io.common.Source;
25 import eu.etaxonomy.cdm.io.common.mapping.out.MethodMapper;
26 import eu.etaxonomy.cdm.model.common.CdmBase;
27 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
28 import eu.etaxonomy.cdm.model.common.RelationshipBase;
29 import eu.etaxonomy.cdm.model.name.NameRelationship;
30 import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
31 import eu.etaxonomy.cdm.model.name.Rank;
32 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
33 import eu.etaxonomy.cdm.model.taxon.Classification;
34 import eu.etaxonomy.cdm.model.taxon.Synonym;
35 import eu.etaxonomy.cdm.model.taxon.SynonymRelationship;
36 import eu.etaxonomy.cdm.model.taxon.Taxon;
37 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
38 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
39 import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
40
41 /**
42 * The export class for relations between {@link eu.etaxonomy.cdm.model.taxon.TaxonBase TaxonBases}.<p>
43 * Inserts into DataWarehouse database table <code>RelTaxon</code>.
44 * @author e.-m.lee
45 * @date 23.02.2010
46 *
47 */
48 @Component
49 public class PesiRelTaxonExport extends PesiExportBase {
50 private static final Logger logger = Logger.getLogger(PesiRelTaxonExport.class);
51 private static final Class<? extends CdmBase> standardMethodParameter = RelationshipBase.class;
52
53 private static int modCount = 1000;
54 private static final String dbTableName = "RelTaxon";
55 private static final String pluralString = "Relationships";
56 private static PreparedStatement synonymsStmt;
57 private HashMap<Rank, Rank> rank2endRankMap = new HashMap<Rank, Rank>();
58 private List<Rank> rankList = new ArrayList<Rank>();
59 private PesiExportMapping mapping;
60 private int count = 0;
61 private static NomenclaturalCode nomenclaturalCode2;
62
63 public PesiRelTaxonExport() {
64 super();
65 }
66
67 /* (non-Javadoc)
68 * @see eu.etaxonomy.cdm.io.common.DbExportBase#getStandardMethodParameter()
69 */
70 @Override
71 public Class<? extends CdmBase> getStandardMethodParameter() {
72 return standardMethodParameter;
73 }
74
75 /* (non-Javadoc)
76 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doCheck(eu.etaxonomy.cdm.io.common.IoStateBase)
77 */
78 @Override
79 protected boolean doCheck(PesiExportState state) {
80 boolean result = true;
81 return result;
82 }
83
84 /* (non-Javadoc)
85 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doInvoke(eu.etaxonomy.cdm.io.common.IoStateBase)
86 */
87 @Override
88 protected void doInvoke(PesiExportState state) {
89 try {
90 logger.info("*** Started Making " + pluralString + " ...");
91
92 Connection connection = state.getConfig().getDestination().getConnection();
93 String synonymsSql = "UPDATE Taxon SET KingdomFk = ?, RankFk = ?, RankCache = ? WHERE TaxonId = ?";
94 synonymsStmt = connection.prepareStatement(synonymsSql);
95
96 // Stores whether this invoke was successful or not.
97 boolean success = true;
98
99 // PESI: Clear the database table RelTaxon.
100 doDelete(state);
101
102 // Get specific mappings: (CDM) Relationship -> (PESI) RelTaxon
103 mapping = getMapping();
104
105 // Initialize the db mapper
106 mapping.initialize(state);
107
108 TransactionStatus txStatus = null;
109 List<Classification> classificationList = null;
110
111 // Specify starting ranks for tree traversing
112 rankList.add(Rank.KINGDOM());
113 rankList.add(Rank.GENUS());
114
115 // Specify where to stop traversing (value) when starting at a specific Rank (key)
116 rank2endRankMap.put(Rank.GENUS(), null); // Since NULL does not match an existing Rank, traverse all the way down to the leaves
117 rank2endRankMap.put(Rank.KINGDOM(), Rank.GENUS()); // excludes rank genus
118
119 // Retrieve list of classifications
120 txStatus = startTransaction(true);
121 logger.info("Started transaction. Fetching all classifications...");
122 classificationList = getClassificationService().listClassifications(null, 0, null, null);
123 commitTransaction(txStatus);
124 logger.debug("Committed transaction.");
125
126 logger.info("Fetched " + classificationList.size() + " classification(s).");
127
128 for (Classification classification : classificationList) {
129 for (Rank rank : rankList) {
130
131 txStatus = startTransaction(true);
132 logger.info("Started transaction to fetch all rootNodes specific to Rank " + rank.getLabel() + " ...");
133
134 List<TaxonNode> rankSpecificRootNodes = getClassificationService().loadRankSpecificRootNodes(classification, rank, null);
135 logger.info("Fetched " + rankSpecificRootNodes.size() + " RootNodes for Rank " + rank.getLabel());
136
137 commitTransaction(txStatus);
138 logger.debug("Committed transaction.");
139
140 for (TaxonNode rootNode : rankSpecificRootNodes) {
141 txStatus = startTransaction(false);
142 Rank endRank = rank2endRankMap.get(rank);
143 if (endRank != null) {
144 logger.info("Started transaction to traverse childNodes of rootNode (" + rootNode.getUuid() + ") till Rank " + endRank.getLabel() + " ...");
145 } else {
146 logger.info("Started transaction to traverse childNodes of rootNode (" + rootNode.getUuid() + ") till leaves are reached ...");
147 }
148
149 TaxonNode newNode = getTaxonNodeService().load(rootNode.getUuid());
150
151 if (isPesiTaxon(newNode.getTaxon())){
152
153 TaxonNode parentNode = newNode.getParent();
154
155 success &=traverseTree(newNode, parentNode, endRank, state);
156
157 commitTransaction(txStatus);
158 logger.debug("Committed transaction.");
159 }else{
160 logger.debug("Taxon is not in PESI");
161 }
162
163 }
164 }
165 }
166
167 logger.warn("*** Finished Making " + pluralString + " ..." + getSuccessString(success));
168
169 if (!success){
170 state.setUnsuccessfull();
171 }
172 return;
173 } catch (SQLException e) {
174 e.printStackTrace();
175 logger.error(e.getMessage());
176 state.setUnsuccessfull();
177 return;
178 }
179 }
180
181 /**
182 * Traverses the classification recursively and stores determined values for every Taxon.
183 * @param childNode
184 * @param parentNode
185 * @param treeIndex
186 * @param fetchLevel
187 * @param state
188 */
189 private boolean traverseTree(TaxonNode childNode, TaxonNode parentNode, Rank fetchLevel, PesiExportState state) {
190 boolean success = true;
191 // Traverse all branches from this childNode until specified fetchLevel is reached.
192 TaxonBase<?> childTaxon = childNode.getTaxon();
193 if (childTaxon != null) {
194 if (isPesiTaxon(childTaxon)){
195 if (childTaxon.getName() != null) {
196 Rank childTaxonNameRank = childTaxon.getName().getRank();
197 if (childTaxonNameRank != null) {
198 if (! childTaxonNameRank.equals(fetchLevel)) {
199
200 success &= saveData(childNode, parentNode, state);
201
202 for (TaxonNode newNode : childNode.getChildNodes()) {
203 success &= traverseTree(newNode, childNode, fetchLevel, state);
204 }
205
206 } else {
207 // logger.error("Target Rank " + fetchLevel.getLabel() + " reached");
208 return success;
209 }
210 } else {
211 logger.warn("Rank is NULL. FetchLevel can not be checked: " + childTaxon.getUuid() + " (" + childTaxon.getTitleCache() + ")");
212 }
213 } else {
214 logger.error("TaxonName is NULL for taxon: " + childTaxon.getUuid());
215 }
216 }else{
217 logger.debug("Taxon is not a PESI taxon: " + childTaxon.getUuid());
218 }
219
220 } else {
221 logger.error("Taxon is NULL for TaxonNode: " + childNode.getUuid());
222 }
223 return success;
224 }
225
226 /**
227 * Stores values in database for every recursive round.
228 * @param childNode
229 * @param parentNode
230 * @param treeIndex
231 * @param state
232 * @param currentTaxonFk
233 */
234 private boolean saveData(TaxonNode childNode, TaxonNode parentNode, PesiExportState state) {
235 boolean success = true;
236 Taxon childNodeTaxon = childNode.getTaxon();
237 if (childNodeTaxon != null) {
238 // TaxonRelationships
239 success &= saveTaxonRelationships(state, childNodeTaxon);
240 // TaxonNameRelationships
241 success &= saveNameRelationships(state, childNodeTaxon);
242 // SynonymRelationships
243 success &= saveSynonymAndSynNameRelationships(state, childNodeTaxon);
244 }
245 return success;
246
247 }
248
249 private boolean saveSynonymAndSynNameRelationships(PesiExportState state, Taxon childNodeTaxon) {
250 boolean success = true;
251 for (SynonymRelationship synRel : childNodeTaxon.getSynonymRelations()) { // synonyms of accepted taxon
252 Synonym synonym = synRel.getSynonym();
253 TaxonNameBase<?,?> synonymTaxonName = synonym.getName();
254 if (! isPesiTaxon(synonym)){
255 logger.warn("Synonym " + synonym.getId() + " of synonym relation " + synRel.getId() + " is not a PESI taxon. Can't export relationship");
256 continue;
257 }
258
259 // Store synonym data in Taxon table
260 invokeSynonyms(state, synonymTaxonName);
261
262
263
264 Set<SynonymRelationship> synonymRelations = synonym.getSynonymRelations();
265 state.setCurrentFromObject(synonym);
266 for (SynonymRelationship synonymRelationship : synonymRelations) { //needed? Maybe to make sure that there are no partial synonym relations missed ??
267 try {
268 if (neededValuesNotNull(synonymRelationship, state)) {
269 doCount(count++, modCount, pluralString);
270 success &= mapping.invoke(synonymRelationship);
271
272 }
273 } catch (SQLException e) {
274 logger.error("SynonymRelationship (" + synonymRelationship.getUuid() + ") could not be stored : " + e.getMessage());
275 }
276 }
277
278 // SynonymNameRelationship
279 success &= saveNameRelationships(state, synonym);
280 }
281 return success;
282 }
283
284 private boolean saveNameRelationships(PesiExportState state, TaxonBase taxonBase) {
285 boolean success = true;
286 TaxonNameBase<?,?> childNodeTaxonName = taxonBase.getName();
287
288 //from relations
289 Set<NameRelationship> nameRelations = childNodeTaxonName.getRelationsFromThisName();
290 state.setCurrentFromObject(taxonBase);
291 boolean isFrom = true;
292 success &= saveOneSideNameRelation(state, isFrom, nameRelations);
293
294 //toRelations
295 nameRelations = childNodeTaxonName.getRelationsToThisName();
296 state.setCurrentToObject(taxonBase);
297 isFrom = false;
298 success &= saveOneSideNameRelation(state, isFrom, nameRelations);
299
300 return success;
301 }
302
303 private boolean saveOneSideNameRelation(PesiExportState state, boolean isFrom, Set<NameRelationship> nameRelations) {
304 boolean success = true;
305 for (NameRelationship nameRelation : nameRelations) {
306 try {
307 TaxonNameBase<?,?> relatedName = isFrom ? nameRelation.getToName(): nameRelation.getFromName();
308 if ( isPurePesiName(relatedName)){
309 success &= checkAndInvokeNameRelation(state, nameRelation, relatedName, isFrom);
310 }else{
311 for (TaxonBase<?> relatedTaxon : getPesiTaxa(relatedName)){
312 success &= checkAndInvokeNameRelation(state, nameRelation, relatedTaxon, isFrom);
313 }
314 }
315 } catch (SQLException e) {
316 logger.error("NameRelationship " + nameRelation.getUuid() + " for " + nameRelation.getFromName().getTitleCache() + " and " + nameRelation.getToName().getTitleCache() + " could not be created: " + e.getMessage());
317 success = false;
318 }
319 }
320 return success;
321 }
322
323 private boolean checkAndInvokeNameRelation(PesiExportState state, NameRelationship nameRelation, IdentifiableEntity<?> relatedObject, boolean isFrom) throws SQLException {
324 boolean success = true;
325 if (isFrom){
326 state.setCurrentToObject(relatedObject);
327 }else{
328 state.setCurrentFromObject(relatedObject);
329 }
330 if (neededValuesNotNull(nameRelation, state)) {
331 doCount(count++, modCount, pluralString);
332 success &= mapping.invoke(nameRelation);
333 }
334 return success;
335 }
336
337 private boolean saveTaxonRelationships(PesiExportState state, Taxon childNodeTaxon) {
338 boolean success = true;
339 Taxon taxon = childNodeTaxon;
340 Set<TaxonRelationship> taxonRelations = taxon.getRelationsToThisTaxon();
341 for (TaxonRelationship taxonRelationship : taxonRelations) {
342 try {
343 if (neededValuesNotNull(taxonRelationship, state)) {
344 doCount(count++, modCount, pluralString);
345 success &= mapping.invoke(taxonRelationship);
346 }
347 } catch (SQLException e) {
348 logger.error("TaxonRelationship could not be created for this TaxonRelation (" + taxonRelationship.getUuid() + "): " + e.getMessage());
349 }
350 }
351 return success;
352 }
353
354 /**
355 * Determines synonym related data and saves them.
356 * @param state
357 * @param sr
358 */
359 private static void invokeSynonyms(PesiExportState state, TaxonNameBase synonymTaxonName) {
360 // Store KingdomFk and Rank information in Taxon table
361 Integer kingdomFk = PesiTransformer.nomenClaturalCode2Kingdom(synonymTaxonName.getNomenclaturalCode());
362 Integer synonymFk = state.getDbId(synonymTaxonName);
363
364 saveSynonymData(synonymTaxonName, synonymTaxonName.getNomenclaturalCode(), kingdomFk, synonymFk);
365 }
366
367 /**
368 * Stores synonym data.
369 * @param taxonName
370 * @param nomenclaturalCode
371 * @param kingdomFk
372 * @param synonymParentTaxonFk
373 * @param currentTaxonFk
374 */
375 private static boolean saveSynonymData(TaxonNameBase taxonName,
376 NomenclaturalCode nomenclaturalCode, Integer kingdomFk,
377 Integer currentSynonymFk) {
378 try {
379 if (kingdomFk != null) {
380 synonymsStmt.setInt(1, kingdomFk);
381 } else {
382 synonymsStmt.setObject(1, null);
383 }
384
385 Integer rankFk = getRankFk(taxonName, nomenclaturalCode);
386 if (rankFk != null) {
387 synonymsStmt.setInt(2, rankFk);
388 } else {
389 synonymsStmt.setObject(2, null);
390 }
391 synonymsStmt.setString(3, getRankCache(taxonName, nomenclaturalCode));
392
393 if (currentSynonymFk != null) {
394 synonymsStmt.setInt(4, currentSynonymFk);
395 } else {
396 synonymsStmt.setObject(4, null);
397 }
398 synonymsStmt.executeUpdate();
399 return true;
400 } catch (SQLException e) {
401 logger.error("SQLException during invoke for taxonName - " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + "): " + e.getMessage());
402 e.printStackTrace();
403 return false;
404 }
405 }
406
407 /**
408 * Checks whether needed values for an entity are NULL.
409 * @return
410 */
411 private boolean neededValuesNotNull(RelationshipBase<?, ?, ?> relationship, PesiExportState state) {
412 boolean result = true;
413 if (getTaxonFk1(relationship, state) == null) {
414 logger.warn("TaxonFk1 is NULL, but is not allowed to be. Therefore no record was written to export database for this relationship: " + relationship.getUuid());
415 result = false;
416 }
417 if (getTaxonFk2(relationship, state) == null) {
418 logger.warn("TaxonFk2 is NULL, but is not allowed to be. Therefore no record was written to export database for this relationship: " + relationship.getUuid());
419 result = false;
420 }
421 return result;
422 }
423
424 /**
425 * Deletes all entries of database tables related to <code>RelTaxon</code>.
426 * @param state The {@link PesiExportState PesiExportState}.
427 * @return Whether the delete operation was successful or not.
428 */
429 protected boolean doDelete(PesiExportState state) {
430 PesiExportConfigurator pesiConfig = (PesiExportConfigurator) state.getConfig();
431
432 String sql;
433 Source destination = pesiConfig.getDestination();
434
435 // Clear RelTaxon
436 sql = "DELETE FROM " + dbTableName;
437 destination.setQuery(sql);
438 destination.update(sql);
439 return true;
440 }
441
442 /* (non-Javadoc)
443 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IoStateBase)
444 */
445 @Override
446 protected boolean isIgnore(PesiExportState state) {
447 return ! state.getConfig().isDoRelTaxa();
448 }
449
450 /**
451 * Returns the <code>TaxonFk1</code> attribute. It corresponds to a CDM <code>TaxonRelationship</code>.
452 * @param relationship The {@link RelationshipBase Relationship}.
453 * @param state The {@link PesiExportState PesiExportState}.
454 * @return The <code>TaxonFk1</code> attribute.
455 * @see MethodMapper
456 */
457 private static Integer getTaxonFk1(RelationshipBase<?, ?, ?> relationship, PesiExportState state) {
458 return getObjectFk(relationship, state, true);
459 }
460
461 /**
462 * Returns the <code>TaxonFk2</code> attribute. It corresponds to a CDM <code>SynonymRelationship</code>.
463 * @param relationship The {@link RelationshipBase Relationship}.
464 * @param state The {@link PesiExportState PesiExportState}.
465 * @return The <code>TaxonFk2</code> attribute.
466 * @see MethodMapper
467 */
468 private static Integer getTaxonFk2(RelationshipBase<?, ?, ?> relationship, PesiExportState state) {
469 return getObjectFk(relationship, state, false);
470 }
471
472 /**
473 * Returns the <code>RelTaxonQualifierFk</code> attribute.
474 * @param relationship The {@link RelationshipBase Relationship}.
475 * @return The <code>RelTaxonQualifierFk</code> attribute.
476 * @see MethodMapper
477 */
478 @SuppressWarnings("unused")
479 private static Integer getRelTaxonQualifierFk(RelationshipBase<?, ?, ?> relationship) {
480 return PesiTransformer.taxonRelation2RelTaxonQualifierFk(relationship);
481 }
482
483 /**
484 * Returns the <code>RelQualifierCache</code> attribute.
485 * @param relationship The {@link RelationshipBase Relationship}.
486 * @return The <code>RelQualifierCache</code> attribute.
487 * @see MethodMapper
488 */
489 @SuppressWarnings("unused")
490 private static String getRelQualifierCache(RelationshipBase<?, ?, ?> relationship) {
491 String result = null;
492 NomenclaturalCode code = null;
493 if (relationship.isInstanceOf(TaxonRelationship.class)){
494 code = CdmBase.deproxy(relationship, TaxonRelationship.class).getToTaxon().getName().getNomenclaturalCode();
495 }else if (relationship.isInstanceOf(SynonymRelationship.class)){
496 code = CdmBase.deproxy(relationship, SynonymRelationship.class).getAcceptedTaxon().getName().getNomenclaturalCode();
497 }else if (relationship.isInstanceOf(NameRelationship.class)){
498 code = CdmBase.deproxy(relationship, NameRelationship.class).getFromName().getNomenclaturalCode();
499 }
500 if (code != null) {
501 result = PesiTransformer.taxonRelation2RelTaxonQualifierCache(relationship, code);
502 } else {
503 logger.error("NomenclaturalCode is NULL while creating the following relationship: " + relationship.getUuid());
504 }
505 return result;
506 }
507
508 /**
509 * Returns the <code>Notes</code> attribute.
510 * @param relationship The {@link RelationshipBase Relationship}.
511 * @return The <code>Notes</code> attribute.
512 * @see MethodMapper
513 */
514 @SuppressWarnings("unused")
515 private static String getNotes(RelationshipBase<?, ?, ?> relationship) {
516 // TODO
517 return null;
518 }
519
520 /**
521 * Returns the database key of an object in the given relationship.
522 * @param relationship {@link RelationshipBase RelationshipBase}.
523 * @param state {@link PesiExportState PesiExportState}.
524 * @param isFrom A boolean value indicating whether the database key of the parent or child in this relationship is searched. <code>true</code> means the child is searched. <code>false</code> means the parent is searched.
525 * @return The database key of an object in the given relationship.
526 */
527 private static Integer getObjectFk(RelationshipBase<?, ?, ?> relationship, PesiExportState state, boolean isFrom) {
528 TaxonBase<?> taxonBase = null;
529 if (relationship.isInstanceOf(TaxonRelationship.class)) {
530 TaxonRelationship tr = (TaxonRelationship)relationship;
531 taxonBase = (isFrom) ? tr.getFromTaxon(): tr.getToTaxon();
532 } else if (relationship.isInstanceOf(SynonymRelationship.class)) {
533 SynonymRelationship sr = (SynonymRelationship)relationship;
534 taxonBase = (isFrom) ? sr.getSynonym() : sr.getAcceptedTaxon();
535 } else if (relationship.isInstanceOf(NameRelationship.class)) {
536 if (isFrom){
537 return state.getDbId(state.getCurrentFromObject());
538 }else{
539 return state.getDbId(state.getCurrentToObject());
540 }
541 }
542 if (taxonBase != null) {
543 if (! isPesiTaxon(taxonBase)){
544 logger.warn("Related taxonBase is not a PESI taxon. Taxon: " + taxonBase.getId() + "/" + taxonBase.getUuid() + "; TaxonRel: " + relationship.getId() + "(" + relationship.getType().getTitleCache() + ")");
545 return null;
546 }else{
547 return state.getDbId(taxonBase);
548 }
549
550 }
551 logger.warn("No taxon found in state for relationship: " + relationship.toString());
552 return null;
553 }
554
555 /**
556 * Returns the <code>RankFk</code> attribute.
557 * @param taxonName The {@link TaxonNameBase TaxonName}.
558 * @param nomenclaturalCode The {@link NomenclaturalCode NomenclaturalCode}.
559 * @return The <code>RankFk</code> attribute.
560 * @see MethodMapper
561 */
562 private static Integer getRankFk(TaxonNameBase taxonName, NomenclaturalCode nomenclaturalCode) {
563 Integer result = null;
564 if (nomenclaturalCode != null) {
565 if (taxonName != null && taxonName.getRank() == null) {
566 logger.warn("Rank is null: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
567 }
568 result = PesiTransformer.rank2RankId(taxonName.getRank(), PesiTransformer.nomenClaturalCode2Kingdom(nomenclaturalCode));
569 if (result == null) {
570 logger.warn("Rank could not be determined for PESI-Kingdom-Id " + PesiTransformer.nomenClaturalCode2Kingdom(nomenclaturalCode) + " and TaxonName " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
571 }
572 }
573 return result;
574 }
575
576 /**
577 * Returns the <code>RankCache</code> attribute.
578 * @param taxonName The {@link TaxonNameBase TaxonName}.
579 * @param nomenclaturalCode The {@link NomenclaturalCode NomenclaturalCode}.
580 * @return The <code>RankCache</code> attribute.
581 * @see MethodMapper
582 */
583 private static String getRankCache(TaxonNameBase taxonName, NomenclaturalCode nomenclaturalCode) {
584 String result = null;
585 if (nomenclaturalCode != null) {
586 result = PesiTransformer.rank2RankCache(taxonName.getRank(), PesiTransformer.nomenClaturalCode2Kingdom(nomenclaturalCode));
587 }
588 return result;
589 }
590
591 /**
592 * Returns the CDM to PESI specific export mappings.
593 * @return The {@link PesiExportMapping PesiExportMapping}.
594 */
595 private PesiExportMapping getMapping() {
596 PesiExportMapping mapping = new PesiExportMapping(dbTableName);
597
598 mapping.addMapper(MethodMapper.NewInstance("TaxonFk1", this.getClass(), "getTaxonFk1", standardMethodParameter, PesiExportState.class));
599 mapping.addMapper(MethodMapper.NewInstance("TaxonFk2", this.getClass(), "getTaxonFk2", standardMethodParameter, PesiExportState.class));
600 mapping.addMapper(MethodMapper.NewInstance("RelTaxonQualifierFk", this));
601 mapping.addMapper(MethodMapper.NewInstance("RelQualifierCache", this));
602 mapping.addMapper(MethodMapper.NewInstance("Notes", this));
603
604 return mapping;
605 }
606
607 }