Project

General

Profile

Download (51.7 KB) Statistics
| Branch: | Tag: | Revision:
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.List;
17
import java.util.Set;
18
import java.util.regex.Matcher;
19
import java.util.regex.Pattern;
20

    
21
import org.apache.log4j.Logger;
22
import org.joda.time.DateTime;
23
import org.springframework.stereotype.Component;
24
import org.springframework.transaction.TransactionStatus;
25

    
26
import eu.etaxonomy.cdm.io.berlinModel.out.mapper.IdMapper;
27
import eu.etaxonomy.cdm.io.berlinModel.out.mapper.MethodMapper;
28
import eu.etaxonomy.cdm.io.common.Source;
29
import eu.etaxonomy.cdm.model.common.CdmBase;
30
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
31
import eu.etaxonomy.cdm.model.common.IdentifiableSource;
32
import eu.etaxonomy.cdm.model.common.VersionableEntity;
33
import eu.etaxonomy.cdm.model.name.NameTypeDesignation;
34
import eu.etaxonomy.cdm.model.name.NameTypeDesignationStatus;
35
import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
36
import eu.etaxonomy.cdm.model.name.NomenclaturalStatus;
37
import eu.etaxonomy.cdm.model.name.NomenclaturalStatusType;
38
import eu.etaxonomy.cdm.model.name.NonViralName;
39
import eu.etaxonomy.cdm.model.name.Rank;
40
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
41
import eu.etaxonomy.cdm.model.reference.ReferenceBase;
42
import eu.etaxonomy.cdm.model.taxon.Synonym;
43
import eu.etaxonomy.cdm.model.taxon.Taxon;
44
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
45
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
46
import eu.etaxonomy.cdm.model.taxon.TaxonomicTree;
47

    
48
/**
49
 * @author a.mueller
50
 * @author e.-m.lee
51
 * @date 23.02.2010
52
 *
53
 */
54
@Component
55
@SuppressWarnings("unchecked")
56
public class PesiTaxonExport extends PesiExportBase {
57
	private static final Logger logger = Logger.getLogger(PesiTaxonExport.class);
58
	private static final Class<? extends CdmBase> standardMethodParameter = TaxonNameBase.class;
59

    
60
	private static int modCount = 1000;
61
	private static final String dbTableName = "Taxon";
62
	private static final String pluralString = "Taxa";
63
	private PreparedStatement parentTaxonFk_TreeIndex_KingdomFkStmt;
64
	private PreparedStatement synonymsStmt;
65
	
66
	enum NamePosition {
67
		beginning,
68
		end,
69
		between,
70
		alone,
71
		nowhere
72
	}
73
	
74
	public class Data {
75
		Integer kingdomId = null;
76
		Integer parentTaxonId = null;
77
		String treeIndex = null;
78
		String nomenclaturalCode = null;
79

    
80
		/**
81
		 * @return the nomenclaturalCode
82
		 */
83
		protected String getNomenclaturalCode() {
84
			return nomenclaturalCode;
85
		}
86
		/**
87
		 * @param nomenclaturalCode the nomenclaturalCode to set
88
		 */
89
		protected void setNomenclaturalCode(String nomenclaturalCode) {
90
			this.nomenclaturalCode = nomenclaturalCode;
91
		}
92
		
93
		/**
94
		 * @return the kingdomId
95
		 */
96
		protected Integer getKingdomId() {
97
			return kingdomId;
98
		}
99
		/**
100
		 * @param kingdomId the kingdomId to set
101
		 */
102
		protected void setKingdomId(Integer kingdomId) {
103
			this.kingdomId = kingdomId;
104
		}
105
		
106
		/**
107
		 * @return the parentTaxonId
108
		 */
109
		protected Integer getParentTaxonId() {
110
			return parentTaxonId;
111
		}
112
		/**
113
		 * @param parentTaxonid the parentTaxonid to set
114
		 */
115
		protected void setParentTaxonId(Integer parentTaxonId) {
116
			this.parentTaxonId = parentTaxonId;
117
		}
118
		
119
		/**
120
		 * @return the treeIndex
121
		 */
122
		protected String getTreeIndex() {
123
			return treeIndex;
124
		}
125
		/**
126
		 * @param treeIndex the treeIndex to set
127
		 */
128
		protected void setTreeIndex(String treeIndex) {
129
			this.treeIndex = treeIndex;
130
		}
131
	}
132

    
133
	public PesiTaxonExport() {
134
		super();
135
	}
136

    
137
	/* (non-Javadoc)
138
	 * @see eu.etaxonomy.cdm.io.common.DbExportBase#getStandardMethodParameter()
139
	 */
140
	@Override
141
	public Class<? extends CdmBase> getStandardMethodParameter() {
142
		return standardMethodParameter;
143
	}
144

    
145
	/* (non-Javadoc)
146
	 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doCheck(eu.etaxonomy.cdm.io.common.IoStateBase)
147
	 */
148
	@Override
149
	protected boolean doCheck(PesiExportState state) {
150
		boolean result = true;
151
		return result;
152
	}
153

    
154
	/* (non-Javadoc)
155
	 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doInvoke(eu.etaxonomy.cdm.io.common.IoStateBase)
156
	 */
157
	@SuppressWarnings("deprecation")
158
	@Override
159
	protected boolean doInvoke(PesiExportState state) {
160
		try {
161
			logger.error("*** Started Making " + pluralString + " ...");
162

    
163
			// Prepare TreeIndex-And-KingdomFk-Statement
164
			Connection con = state.getConfig().getDestination().getConnection();
165
			String parentTaxonFk_TreeIndex_KingdomFkSql = "UPDATE Taxon SET ParentTaxonFk = ?, TreeIndex = ?, " +
166
					"KingdomFk = ?, RankFk = ?, RankCache = ? WHERE TaxonId = ?"; 
167
			parentTaxonFk_TreeIndex_KingdomFkStmt = con.prepareStatement(parentTaxonFk_TreeIndex_KingdomFkSql);
168

    
169
			String synonymsSql = "UPDATE Taxon SET ParentTaxonFk = ?, KingdomFk = ?, RankFk = ?, RankCache = ? WHERE TaxonId = ?"; 
170
			synonymsStmt = con.prepareStatement(synonymsSql);
171

    
172
			// Get the limit for objects to save within a single transaction.
173
			int limit = state.getConfig().getLimitSave();
174

    
175
			// Stores whether this invoke was successful or not.
176
			boolean success = true;
177
	
178
			// PESI: Clear the database table Taxon.
179
			doDelete(state);
180
			
181
			// CDM: Get the number of all available taxa.
182
//			int maxCount = getTaxonService().count(null);
183
//			logger.error("Total amount of " + maxCount + " " + pluralString + " will be exported.");
184

    
185
			// Get specific mappings: (CDM) Taxon -> (PESI) Taxon
186
			PesiExportMapping mapping = getMapping();
187
	
188
			// Initialize the db mapper
189
			mapping.initialize(state);
190
	
191
			int count = 0;
192
			int pastCount = 0;
193
			TransactionStatus txStatus = null;
194
			List<TaxonNameBase> list = null;
195

    
196
			// 1st Round: Make Taxa
197
/*			logger.error("PHASE 1...");
198
			// Start transaction
199
			txStatus = startTransaction(true);
200
			logger.error("Started new transaction. Fetching some " + pluralString + " (max: " + limit + ") ...");
201
			while ((list = getNameService().list(null, limit, count, null, null)).size() > 0) {
202

    
203
				logger.error("Fetched " + list.size() + " " + pluralString + ". Exporting...");
204
				for (TaxonNameBase taxonName : list) {
205
					doCount(count++, modCount, pluralString);
206
					success &= mapping.invoke(taxonName);
207
					
208
					// Check whether some rules are violated
209
//						if (rank == null) {
210
//							logger.error("Rank was not determined: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
211
//						} else {
212
//							if (infraSpecificEpithet == null && rank.intValue() == 190) {
213
//								logger.error("InfraSpecificEpithet was not determined although it should exist for rank 190: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
214
//							}
215
//							if (specificEpithet != null && rank.intValue() < 220) {
216
//								logger.error("SpecificEpithet was determined for rank " + rank + " although it should only exist for ranks higher or equal to 220: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
217
//							}
218
//							if (infraSpecificEpithet != null && rank.intValue() < 230) {
219
//								logger.error("InfraSpecificEpithet was determined for rank " + rank + " although it should only exist for ranks higher or equal to 230: "  + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
220
//							}
221
//						}
222
//						if (infraSpecificEpithet != null && specificEpithet == null) {
223
//							logger.error("An infraSpecificEpithet was determined, but a specificEpithet was not determined: "  + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
224
//						}
225
//						if (genusOrUninomial == null) {
226
//							logger.error("GenusOrUninomial was not determined: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
227
//						}
228
//						
229
//						rank = null;
230
//						infraSpecificEpithet = null;
231
//						genusOrUninomial = null;
232
//						specificEpithet = null;
233

    
234
				}
235

    
236
				// Commit transaction
237
				commitTransaction(txStatus);
238
				logger.error("Committed transaction.");
239
				logger.error("Exported " + (count - pastCount) + " " + pluralString + ". Total: " + count);
240
				pastCount = count;
241

    
242
				// Start transaction
243
				txStatus = startTransaction(true);
244
				logger.error("Started new transaction. Fetching some " + pluralString + " (max: " + limit + ") ...");
245
			}
246
			if (list.size() == 0) {
247
				logger.error("No " + pluralString + " left to fetch.");
248
			}
249
			// Commit transaction
250
			commitTransaction(txStatus);
251
			logger.error("Committed transaction.");*/
252

    
253
			count = 0;
254
			pastCount = 0;
255
			List<TaxonomicTree> taxonomicTreeList = null;
256
			// 2nd Round: Add ParentTaxonFk to each Taxon
257
			logger.error("PHASE 2...");
258
			// Start transaction
259
			txStatus = startTransaction(true);
260
			logger.error("Started new transaction. Fetching some " + pluralString + " (max: " + limit + ") ...");
261
			Integer taxonomicTreeLimit = 1;
262
			Integer taxonomicTreeStart = 0;
263
			StringBuffer treeIndex = new StringBuffer();
264
			while ((taxonomicTreeList = getTaxonTreeService().listTaxonomicTrees(taxonomicTreeLimit, taxonomicTreeStart, null, null)).size() > 0) {
265
				logger.error("Fetched " + taxonomicTreeList.size() + " Taxonomic Tree.");
266

    
267
				for (TaxonomicTree taxonomicTree : taxonomicTreeList) {
268
					logger.error("Number of Root Nodes for this Taxonomic Tree: " + taxonomicTree.getRootNodes().size());
269
					
270
					for (TaxonNode rootNode : taxonomicTree.getRootNodes()) {
271
						logger.error("Number of Child Nodes for this Root Node: " + rootNode.getChildNodes().size() + ". Traversing branches...");
272
						
273
						for (TaxonNode rootChild : rootNode.getChildNodes()) {
274
							// Traverse all branches from this rootChild
275
							treeIndex.append("#");
276
							traverseTree(rootChild, rootNode, treeIndex, rootChild.getTaxon().getName().getRank(), state);
277
						}
278
					}
279
				}
280

    
281
				// Commit transaction
282
				commitTransaction(txStatus);
283
				logger.error("Committed transaction.");
284

    
285
				// Start transaction
286
				txStatus = startTransaction(true);
287
				logger.error("Started new transaction. Fetching some " + pluralString + " (max: " + limit + ") ...");
288
				
289
				// Pick next Taxonomic Tree
290
				taxonomicTreeStart++;
291
			}
292
			if (taxonomicTreeList.size() == 0) {
293
				logger.error("No " + pluralString + " left to fetch.");
294
			}
295
			// Commit transaction
296
			commitTransaction(txStatus);
297
			logger.error("Committed transaction.");
298

    
299
			logger.error("*** Finished Making " + pluralString + " ..." + getSuccessString(success));
300

    
301
			return success;
302
		} catch (SQLException e) {
303
			e.printStackTrace();
304
			logger.error(e.getMessage());
305
			return false;
306
		}
307
	}
308

    
309
	/**
310
	 * Traverse the TaxonTree and store determined values for every Taxon.
311
	 * @param rootChild
312
	 */
313
	private void traverseTree(TaxonNode childNode, TaxonNode parentNode, StringBuffer treeIndex, Rank kingdomRank, PesiExportState state) {
314
		if (childNode.getTaxon() != null) {
315
			if (state.getDbId(childNode.getTaxon().getName()) != null) {
316
				treeIndex.append(state.getDbId(childNode.getTaxon().getName()));
317
				treeIndex.append("#");
318

    
319
				saveData(childNode, parentNode, treeIndex, state, state.getDbId(childNode.getTaxon().getName()));
320

    
321
				for (TaxonNode newNode : childNode.getChildNodes()) {
322
					traverseTree(newNode, childNode, treeIndex, kingdomRank, state);
323
				}
324
			} else {
325
				logger.error("TaxonName can not be found in State: " + childNode.getTaxon().getName().getUuid() + " (" + childNode.getTaxon().getName().getTitleCache());
326
			}
327
		} else {
328
			logger.error("Taxon is NULL for TaxonNode: " + childNode.getUuid());
329
		}
330
	}
331

    
332
	/**
333
	 * Store values in database for every recursive round.
334
	 * @param childNode
335
	 * @param parentNode
336
	 * @param treeIndex
337
	 * @param state
338
	 * @param currentTaxonFk
339
	 */
340
	private void saveData(TaxonNode childNode, TaxonNode parentNode, StringBuffer treeIndex, PesiExportState state, Integer currentTaxonFk) {
341
		// We are differentiating kingdoms by the nomenclatural code for now.
342
		// This needs to be handled in a better way as soon as we know how to differentiate between more kingdoms.
343
		if (childNode.getTaxon() != null && childNode.getTaxon().getName() != null) {
344
			if (parentNode.getTaxon() != null && parentNode.getTaxon().getName() != null) {
345
					invokeParentTaxonFkAndTreeIndexAndKindomFk(childNode.getTaxon().getName(), 
346
							childNode.getTaxon().getName().getNomenclaturalCode(), 
347
							PesiTransformer.nomenClaturalCode2Kingdom(childNode.getTaxon().getName().getNomenclaturalCode()), 
348
							state.getDbId(parentNode.getTaxon().getName()), 
349
							currentTaxonFk, 
350
							treeIndex);
351
			}
352
		}
353
		
354
		// Synonyms of the current Taxon: Don't store treeIndex for Synonyms
355
		for (Synonym synonym : childNode.getTaxon().getSynonyms()) {
356
			invokeSynonyms(synonym.getName(), 
357
					childNode.getTaxon().getName().getNomenclaturalCode(), 
358
					PesiTransformer.nomenClaturalCode2Kingdom(childNode.getTaxon().getName().getNomenclaturalCode()), 
359
					currentTaxonFk, 
360
					state.getDbId(synonym.getName()));
361
		}
362
	}
363

    
364
	/**
365
	 * Store synonym values.
366
	 * @param taxonName
367
	 * @param nomenclaturalCode
368
	 * @param kingdomFk
369
	 * @param synonymParentTaxonFk
370
	 * @param currentTaxonFk
371
	 */
372
	private boolean invokeSynonyms(TaxonNameBase taxonName,
373
			NomenclaturalCode nomenclaturalCode, Integer kingdomFk,
374
			Integer synonymParentTaxonFk, Integer currentSynonymFk) {
375
		try {
376
			synonymsStmt.setInt(1, synonymParentTaxonFk);
377
			synonymsStmt.setInt(2, kingdomFk);
378
			synonymsStmt.setInt(3, getRankFk(taxonName, nomenclaturalCode));
379
			synonymsStmt.setString(4, getRankCache(taxonName, nomenclaturalCode));
380
			synonymsStmt.setInt(5, currentSynonymFk);
381
			synonymsStmt.executeUpdate();
382
			return true;
383
		} catch (SQLException e) {
384
			logger.error("SQLException during invoke for taxonName - " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + "): " + e.getMessage());
385
			e.printStackTrace();
386
			return false;
387
		}
388
	}
389

    
390
	/**
391
	 * 
392
	 * @param taxonNameBase
393
	 * @param state
394
	 * @param stmt
395
	 * @return
396
	 */
397
	protected boolean invokeParentTaxonFkAndTreeIndexAndKindomFk(TaxonNameBase taxonName, NomenclaturalCode nomenclaturalCode, Integer kingdomFk, Integer parentTaxonFk, Integer currentTaxonFk, StringBuffer treeIndex) {
398
		try {
399
			parentTaxonFk_TreeIndex_KingdomFkStmt.setInt(1, parentTaxonFk);
400
			parentTaxonFk_TreeIndex_KingdomFkStmt.setString(2, treeIndex.toString());
401
			parentTaxonFk_TreeIndex_KingdomFkStmt.setInt(3, kingdomFk);
402
			parentTaxonFk_TreeIndex_KingdomFkStmt.setInt(4, getRankFk(taxonName, nomenclaturalCode));
403
			parentTaxonFk_TreeIndex_KingdomFkStmt.setString(5, getRankCache(taxonName, nomenclaturalCode));
404
			parentTaxonFk_TreeIndex_KingdomFkStmt.setInt(6, currentTaxonFk);
405
			parentTaxonFk_TreeIndex_KingdomFkStmt.executeUpdate();
406
			return true;
407
		} catch (SQLException e) {
408
			logger.error("SQLException during treeIndex invoke for taxonName - " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + "): " + e.getMessage());
409
			e.printStackTrace();
410
			return false;
411
		}
412
	}
413

    
414
	/**
415
	 * Deletes all entries of database tables related to <code>Taxon</code>.
416
	 * @param state The PesiExportState
417
	 * @return Whether the delete operation was successful or not.
418
	 */
419
	protected boolean doDelete(PesiExportState state) {
420
		PesiExportConfigurator pesiConfig = (PesiExportConfigurator) state.getConfig();
421
		
422
		String sql;
423
		Source destination =  pesiConfig.getDestination();
424

    
425
		// Clear Taxon
426
		sql = "DELETE FROM " + dbTableName;
427
		destination.setQuery(sql);
428
		destination.update(sql);
429
		return true;
430
	}
431

    
432
	/* (non-Javadoc)
433
	 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IoStateBase)
434
	 */
435
	@Override
436
	protected boolean isIgnore(PesiExportState state) {
437
		return ! state.getConfig().isDoTaxa();
438
	}
439

    
440
	/**
441
	 * Returns the <code>RankFk</code> attribute.
442
	 * @param taxon The {@link TaxonBase Taxon}.
443
	 * @return The <code>RankFk</code> attribute.
444
	 * @see MethodMapper
445
	 */
446
	private static Integer getRankFk(TaxonNameBase taxonName, NomenclaturalCode nomenclaturalCode) {
447
		Integer result = null;
448
		if (nomenclaturalCode != null) {
449
			if (taxonName != null && taxonName.getRank() == null) {
450
				logger.warn("Rank is null: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
451
			}
452
			result = PesiTransformer.rank2RankId(taxonName.getRank(), PesiTransformer.nomenClaturalCode2Kingdom(nomenclaturalCode));
453
			if (result == null) {
454
				logger.warn("Rank " + taxonName.getRank().getLabel() + " could not be determined for PESI-Kingdom-Id " + PesiTransformer.nomenClaturalCode2Kingdom(nomenclaturalCode));
455
			}
456
		}
457
		return result;
458
	}
459

    
460
	/**
461
	 * Returns the <code>RankCache</code> attribute.
462
	 * @param taxon The {@link TaxonBase Taxon}.
463
	 * @return The <code>RankCache</code> attribute.
464
	 * @see MethodMapper
465
	 */
466
	private static String getRankCache(TaxonNameBase taxonName, NomenclaturalCode nomenclaturalCode) {
467
		String result = null;
468
		if (nomenclaturalCode != null) {
469
			result = PesiTransformer.rank2RankCache(taxonName.getRank(), PesiTransformer.nomenClaturalCode2Kingdom(nomenclaturalCode));
470
		}
471
		return result;
472
	}
473

    
474
	/**
475
	 * 
476
	 * @param taxon The {@link TaxonBase Taxon}.
477
	 * @return Whether it's genus or uninomial.
478
	 * @see MethodMapper
479
	 */
480
	@SuppressWarnings("unused")
481
	private static String getGenusOrUninomial(TaxonNameBase taxonName) {
482
		String result = null;
483
		if (taxonName != null && (taxonName.isInstanceOf(NonViralName.class))) {
484
			NonViralName nonViralName = CdmBase.deproxy(taxonName, NonViralName.class);
485
			result = nonViralName.getGenusOrUninomial();
486
		}
487
		return result;
488
	}
489

    
490
	/**
491
	 * Returns the <code>InfraGenericEpithet</code> attribute.
492
	 * @param taxon The {@link TaxonBase Taxon}.
493
	 * @return The <code>InfraGenericEpithet</code> attribute.
494
	 * @see MethodMapper
495
	 */
496
	@SuppressWarnings("unused")
497
	private static String getInfraGenericEpithet(TaxonNameBase taxonName) {
498
		String result = null;
499
		if (taxonName != null && (taxonName.isInstanceOf(NonViralName.class))) {
500
			NonViralName nonViralName = CdmBase.deproxy(taxonName, NonViralName.class);
501
			result = nonViralName.getInfraGenericEpithet();
502
		}
503
		return result;
504
	}
505

    
506
	/**
507
	 * Returns the <code>SpecificEpithet</code> attribute.
508
	 * @param taxon The {@link TaxonBase Taxon}.
509
	 * @return The <code>SpecificEpithet</code> attribute.
510
	 * @see MethodMapper
511
	 */
512
	@SuppressWarnings("unused")
513
	private static String getSpecificEpithet(TaxonNameBase taxonName) {
514
		String result = null;
515
		if (taxonName != null && (taxonName.isInstanceOf(NonViralName.class))) {
516
			NonViralName nonViralName = CdmBase.deproxy(taxonName, NonViralName.class);
517
			result = nonViralName.getSpecificEpithet();
518
		}
519
		return result;
520
	}
521

    
522
	/**
523
	 * Returns the <code>InfraSpecificEpithet</code> attribute.
524
	 * @param taxon The {@link TaxonBase Taxon}.
525
	 * @return The <code>InfraSpecificEpithet</code> attribute.
526
	 * @see MethodMapper
527
	 */
528
	@SuppressWarnings("unused")
529
	private static String getInfraSpecificEpithet(TaxonNameBase taxonName) {
530
		String result = null;
531
		if (taxonName != null && (taxonName.isInstanceOf(NonViralName.class))) {
532
			NonViralName nonViralName = CdmBase.deproxy(taxonName, NonViralName.class);
533
			result = nonViralName.getInfraSpecificEpithet();
534
		}
535
		return result;
536
	}
537

    
538
	/**
539
	 * Returns the <code>WebSearchName</code> attribute.
540
	 * @param taxon The {@link TaxonBase Taxon}.
541
	 * @return The <code>WebSearchName</code> attribute.
542
	 * @see MethodMapper
543
	 */
544
	@SuppressWarnings("unused")
545
	private static String getWebSearchName(TaxonNameBase taxonName) {
546
		String result = null;
547
		if (taxonName != null && (taxonName.isInstanceOf(NonViralName.class))) {
548
			NonViralName nonViralName = CdmBase.deproxy(taxonName, NonViralName.class);
549
			result = nonViralName.getNameCache();
550
		}
551
		return result;
552
	}
553
	
554
	/**
555
	 * Returns the <code>WebShowName</code> attribute.
556
	 * @param taxon The {@link TaxonBase Taxon}.
557
	 * @return The <code>WebShowName</code> attribute.
558
	 * @see MethodMapper
559
	 */
560
	@SuppressWarnings("unused")
561
	private static String getWebShowName(TaxonNameBase taxonName) {
562
		String result = null;
563
		try {
564
			if (taxonName != null) {
565
				if (taxonName != null && taxonName.isInstanceOf(NonViralName.class)) {
566
					NonViralName nonViralName = CdmBase.deproxy(taxonName, NonViralName.class);
567
					String singleWhitespace = "\\s";
568
					String multipleWhitespaces = "\\s*";
569
					String whitespaceOrNothing = "\\s?";
570
					String singleBlank = " ";
571
					String anyNumberOfCharacters = ".*";
572
					String backSlashRegEx = "\\";
573
	//				String periodRegEx = "\\.";
574
	//				String asterixRegEx = "\\*";
575
					String questionMarkRegEx = "\\?";
576
	//				String plusRegEx = "\\+";
577
	//				String squareBracketRegEx = "\\[";
578
	//				String curlyBracketRegEx = "\\{";
579
	//				String pipeRegEx = "\\|";
580
	//				String accentRegEx = "\\^";
581
	//				String dollarSignRegEx = "\\$";
582
					String openingParenthesisRegEx = "\\(";
583
					String closingParenthesisRegEx = "\\)";
584
					String openParenthesis = "(";
585
					String closeParenthesis = ")";
586
					String italicBeginTag = "<i>";
587
					String italicEndTag = "</i>";
588
					String endAnchor = "$";
589
					
590
					String questionMarkReplacement = backSlashRegEx + questionMarkRegEx;
591
	//				String backSlashReplacement = backSlashRegEx + backSlashRegEx;
592
	//				String periodReplacement = backSlashRegEx + periodRegEx;
593
	//				String asterixReplacement = backSlashRegEx + asterixRegEx;
594
	//				String plusReplacement = backSlashRegEx + plusRegEx;
595
	//				String squareBracketReplacement = backSlashRegEx + squareBracketRegEx;
596
	//				String curlyBracketReplacement = backSlashRegEx + curlyBracketRegEx;
597
	//				String pipeReplacement = backSlashRegEx + pipeRegEx;
598
	//				String accentReplacement = backSlashRegEx + accentRegEx;
599
	//				String dollarSignReplacement = backSlashRegEx + dollarSignRegEx;
600
	
601
					if (nonViralName != null) {
602
						if (nonViralName.getTitleCache() != null) {
603
							try {
604
								String fullName = nonViralName.getTitleCache();
605
								
606
								// This deals with question marks that are reserved in regular expressions
607
								fullName = fullName.replaceAll(questionMarkRegEx, questionMarkReplacement);
608

    
609
								String genusOrUninomial = nonViralName.getGenusOrUninomial();
610
								String infraGenericEpithet = nonViralName.getInfraGenericEpithet();
611
								if (infraGenericEpithet != null) {
612
									infraGenericEpithet = openParenthesis + infraGenericEpithet + closeParenthesis;
613
								}
614
								String specificEpithet = nonViralName.getSpecificEpithet();
615
								String infraSpecificEpithet = nonViralName.getInfraSpecificEpithet();
616
								
617
								boolean rankExists = false;
618

    
619
								StringBuffer replaceFullName = new StringBuffer(fullName);
620
								List<NamePosition> genusOrUninomialPosition = getPosition(genusOrUninomial, fullName);
621
								List<NamePosition> infraGenericEpithetPosition = getPosition(infraGenericEpithet, fullName);
622
								List<NamePosition> specificEpithetPosition = getPosition(specificEpithet, fullName);
623
								List<NamePosition> authorshipPosition = getPosition(specificEpithet, fullName);
624
								if (nameExists(genusOrUninomialPosition) || nameExists(infraGenericEpithetPosition) || nameExists(specificEpithetPosition)) {
625
									replaceFullName.insert(0, italicBeginTag);
626
									
627
									if (nameExists(specificEpithetPosition)) {
628
										if ((specificEpithet.equals(infraSpecificEpithet) && countPattern(infraSpecificEpithet, fullName) == 2) |
629
												(! specificEpithet.equals(infraSpecificEpithet) && countPattern(infraSpecificEpithet, fullName) == 1)) {
630
											// infraSpecificEpithet exists
631

    
632
											// Determine position of infraSpecificEpithet
633
											int infraSpecificEpithetLocation = replaceFullName.lastIndexOf(infraSpecificEpithet);
634
											int infraSpecificEpithetBeginLocation = infraSpecificEpithetLocation;
635
											int infraSpecificEpithetEndLocation = infraSpecificEpithetLocation + infraSpecificEpithet.length();
636
											
637
											// Check whether rank information exists between specificEpithet and infraSpecificEpithet
638
											String rankExistsRegEx = specificEpithet + singleWhitespace + anyNumberOfCharacters + singleWhitespace + infraSpecificEpithet;
639
											List<NamePosition> rankPosition = getPosition(rankExistsRegEx, fullName);
640
											if (rankPosition != null && nameExists(rankPosition)) {
641
												// Rank information exists
642

    
643
												// Insert italicBeginTag
644
												replaceFullName.insert(infraSpecificEpithetBeginLocation, italicBeginTag);
645

    
646
												// Check position of infraSpecificEpithet
647
												List<NamePosition> infraSpecificEpithetPosition = getPosition(infraSpecificEpithet, fullName);
648
												if (infraSpecificEpithetPosition != null) {
649
													if (infraSpecificEpithetPosition.contains(NamePosition.end)) {
650
														// Append italicEndTag
651
														replaceFullName.append(italicEndTag);
652
													} else {
653
														// Insert italicEndTag
654
														replaceFullName.insert(infraSpecificEpithetEndLocation + italicBeginTag.length(), italicEndTag);
655
													}
656
												}
657
											}
658
										}
659
										
660
										int specificEpithetLocation = replaceFullName.indexOf(specificEpithet) + specificEpithet.length();
661
										if (specificEpithetPosition.contains(NamePosition.end)) {
662
											replaceFullName.append(italicEndTag);
663
										} else {
664
											replaceFullName.insert(specificEpithetLocation, italicEndTag);
665
										}
666
									} else if (nameExists(infraGenericEpithetPosition)) {
667
										int infraGenericEpithetLocation = replaceFullName.indexOf(infraGenericEpithet) + 
668
												openParenthesis.length() + infraGenericEpithet.length() + closeParenthesis.length();
669
										if (infraGenericEpithetPosition.contains(NamePosition.end)) {
670
											replaceFullName.append(italicEndTag);
671
										} else {
672
											replaceFullName.insert(infraGenericEpithetLocation, italicEndTag);
673
										}
674
									} else if (nameExists(genusOrUninomialPosition)) {
675
										replaceFullName.insert(genusOrUninomial.length() + italicBeginTag.length(), italicEndTag);
676
									}
677
								}
678
								
679
								result = replaceFullName.toString();
680

    
681
							} catch (Exception e) {
682
								// This needs a workaround since very likely there is a character in the fullName that is reserved in regular expressions
683
								logger.error("WebShowName could not be determined for NonViralName " + nonViralName.getUuid() + " (" + nonViralName.getTitleCache() + "): " + e.getMessage());
684
//								e.printStackTrace();
685
								result = nonViralName.getTitleCache();
686
							}
687
						} else {
688
							logger.error("WebShowName could not be determined: TitleCache is NULL for NonViralName " + nonViralName.getUuid() + " (" + nonViralName.getTitleCache() + ")");
689
						}
690
					} else {
691
						logger.error("WebShowName could not be determined: NonViralName is NULL for TaxonName" + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
692
					}
693
					
694
				}
695
			} else {
696
				logger.warn("WebShowName could not be determined: TaxonName is NULL");
697
			}
698
		
699
//		logger.error("final result: " + result);
700
		} catch (Exception e) {
701
			e.printStackTrace();
702
		}
703
		return result;
704
	}
705

    
706
	/**
707
	 * 
708
	 * @param searchString
709
	 * @param searchedString
710
	 * @return
711
	 */
712
	private static Integer countPattern(String searchString, String searchedString) {
713
		Integer count = 0;
714
		if (searchString != null && searchedString != null) {
715
			Integer index = 0;
716
			while ((index = searchedString.indexOf(searchString, index)) != -1) {
717
				count++;
718
				index++;
719
			}
720
		} else {
721
//			logger.error("Either searchString or searchedString is NULL");
722
		}
723
		return count;
724
	}
725
	
726
	/**
727
	 * @param namePosition
728
	 * @return
729
	 */
730
	private static boolean nameExists(List<NamePosition> namePosition) {
731
		boolean result = false;
732
		if (namePosition != null) {
733
			if (namePosition.contains(NamePosition.nowhere)) {
734
				result = false;
735
			} else {
736
				result = true;
737
			}
738
		}
739
		return result;
740
	}
741

    
742
	
743
	private static List<NamePosition> getPosition(String name, String targetString) {
744
		List<NamePosition> result = new ArrayList<NamePosition>();
745
		boolean touched = false;
746
		if (name != null && targetString != null) {
747
			if ("".equals(name.trim())) {
748
				result.add(NamePosition.nowhere);
749
			} else {
750
				String beginningAnchor = "^";
751
				String endAnchor = "$";
752
				String anyNumberOfCharacters = ".*";
753
				
754
				String beginningRegEx = beginningAnchor + name;
755
				String endRegEx = name + endAnchor;
756
				String middleRegEx = anyNumberOfCharacters + name + anyNumberOfCharacters;
757
				if (stringExists(beginningRegEx, targetString)) {
758
					result.add(NamePosition.beginning);
759
					touched = true;
760
				}
761
				if (stringExists(endRegEx, targetString)) {
762
					result.add(NamePosition.end);
763
					touched = true;
764
				}
765
				if (stringExists(middleRegEx, targetString)) {
766
					if (result.contains(NamePosition.beginning) && result.contains(NamePosition.end)) {
767
						result.add(NamePosition.alone);
768
					} else {
769
						result.add(NamePosition.between);
770
					}
771
					touched = true;
772
				}
773
				if (!touched) {
774
					result.add(NamePosition.nowhere);
775
				}
776
			}
777
		} else {
778
//			logger.error("Either name or targetString is NULL");
779
			result = null;
780
		}
781
		return result;
782
	}
783
	
784

    
785
	/**
786
	 * @param beginningRegEx
787
	 * @param targetString
788
	 */
789
	private static boolean stringExists(String regEx, String targetString) {
790
		Pattern pattern = Pattern.compile(regEx);
791
		Matcher matcher = pattern.matcher(targetString);
792
		if (matcher.find()) {
793
			return true;
794
		} else {
795
			return false;
796
		}
797
	}
798

    
799
	/**
800
	 * Returns the <code>AuthorString</code> attribute.
801
	 * @param taxon The {@link TaxonBase Taxon}.
802
	 * @return The <code>AuthorString</code> attribute.
803
	 * @see MethodMapper
804
	 */
805
	@SuppressWarnings("unused")
806
	private static String getAuthorString(TaxonNameBase taxonName) {
807
		String result = null;
808
		if (taxonName != null && taxonName != null) {
809
			if (taxonName.isInstanceOf(NonViralName.class)) {
810
				NonViralName nonViralName = CdmBase.deproxy(taxonName, NonViralName.class);
811
				result = nonViralName.getAuthorshipCache();
812
			} else {
813
				logger.warn("TaxonName is not of instance NonViralName: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
814
			}
815
		}
816
		return result;
817
	}
818

    
819
	/**
820
	 * Returns the <code>FullName</code> attribute.
821
	 * @param taxon The {@link TaxonBase Taxon}.
822
	 * @return The <code>FullName</code> attribute.
823
	 * @see MethodMapper
824
	 */
825
	@SuppressWarnings("unused")
826
	private static String getFullName(TaxonNameBase taxonName) {
827
		if (taxonName != null) {
828
			return taxonName.getTitleCache();
829
		} else {
830
			return null;
831
		}
832
	}
833

    
834
	/**
835
	 * Returns the <code>NomRefString</code> attribute.
836
	 * @param taxon The {@link TaxonBase Taxon}.
837
	 * @return The <code>NomRefString</code> attribute.
838
	 * @see MethodMapper
839
	 */
840
	@SuppressWarnings("unused")
841
	private static String getNomRefString(TaxonNameBase taxonName) {
842
		String result = null;
843
		if (taxonName != null) {
844
			try {
845
				result = taxonName.getNomenclaturalMicroReference();
846
			} catch (Exception e) {
847
				logger.error("While getting NomRefString");
848
				e.printStackTrace();
849
			}
850
		}
851
		return result;
852
	}
853
	
854
	/**
855
	 * Returns the <code>DisplayName</code> attribute.
856
	 * @param taxon The {@link TaxonBase Taxon}.
857
	 * @return The <code>DisplayName</code> attribute.
858
	 * @see MethodMapper
859
	 */
860
	@SuppressWarnings("unused")
861
	private static String getDisplayName(TaxonNameBase taxonName) {
862
		// TODO: extension?
863
		if (taxonName != null) {
864
			return taxonName.getFullTitleCache();
865
		} else {
866
			return null;
867
		}
868
	}
869
	
870
	/**
871
	 * Returns the <code>FuzzyName</code> attribute.
872
	 * @param taxon The {@link TaxonBase Taxon}.
873
	 * @return The <code>FuzzyName</code> attribute.
874
	 * @see MethodMapper
875
	 */
876
	@SuppressWarnings("unused")
877
	private static String getFuzzyName(TaxonNameBase taxonName) {
878
		// TODO: extension
879
		return null;
880
	}
881

    
882
	/**
883
	 * Returns the <code>NameStatusFk</code> attribute.
884
	 * @param taxon The {@link TaxonBase Taxon}.
885
	 * @return The <code>NameStatusFk</code> attribute.
886
	 * @see MethodMapper
887
	 */
888
	@SuppressWarnings("unused")
889
	private static Integer getNameStatusFk(TaxonNameBase taxonName) {
890
		Integer result = null;
891
		
892
		try {
893
		if (taxonName != null && (taxonName.isInstanceOf(NonViralName.class))) {
894
			NonViralName nonViralName = CdmBase.deproxy(taxonName, NonViralName.class);
895
			Set<NomenclaturalStatus> states = nonViralName.getStatus();
896
			if (states.size() == 1) {
897
				NomenclaturalStatus state = states.iterator().next();
898
				NomenclaturalStatusType statusType = null;
899
				if (state != null) {
900
					statusType = state.getType();
901
				}
902
				if (statusType != null) {
903
					result = PesiTransformer.nomStatus2nomStatusFk(statusType);
904
				}
905
			} else if (states.size() > 1) {
906
				logger.error("This TaxonName has more than one Nomenclatural Status: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
907
			}
908
		}
909
		
910
		} catch (Exception e) {
911
			e.printStackTrace();
912
		}
913
		return result;
914
	}
915
	
916
	/**
917
	 * Returns the <code>NameStatusCache</code> attribute.
918
	 * @param taxon The {@link TaxonBase Taxon}.
919
	 * @return The <code>NameStatusCache</code> attribute.
920
	 * @see MethodMapper
921
	 */
922
	@SuppressWarnings("unused")
923
	private static String getNameStatusCache(TaxonNameBase taxonName) {
924
		String result = null;
925
		
926
		try {
927
		if (taxonName != null && (taxonName.isInstanceOf(NonViralName.class))) {
928
			NonViralName nonViralName = CdmBase.deproxy(taxonName, NonViralName.class);
929
			Set<NomenclaturalStatus> states = nonViralName.getStatus();
930
			if (states.size() == 1) {
931
				NomenclaturalStatus state = states.iterator().next();
932
				if (state != null) {
933
					result = PesiTransformer.nomStatus2NomStatusCache(state.getType());
934
				}
935
			} else if (states.size() > 1) {
936
				logger.error("This TaxonName has more than one Nomenclatural Status: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
937
			}
938
		}
939
		
940
		} catch (Exception e) {
941
			e.printStackTrace();
942
		}
943
		return result;
944
	}
945
	
946
	/**
947
	 * Returns the <code>TaxonStatusFk</code> attribute.
948
	 * @param taxon The {@link TaxonBase Taxon}.
949
	 * @return The <code>TaxonStatusFk</code> attribute.
950
	 * @see MethodMapper
951
	 */
952
	@SuppressWarnings("unused")
953
	private static Integer getTaxonStatusFk(TaxonNameBase taxonName) {
954
		Integer result = null;
955
		
956
		try {
957
		Set taxa = taxonName.getTaxa();
958
		if (taxa.size() == 1) {
959
			result = PesiTransformer.taxonBase2statusFk((TaxonBase<?>) taxa.iterator().next());
960
		} else if (taxa.size() > 1) {
961
			logger.warn("This TaxonName has " + taxa.size() + " Taxa: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
962
		}
963
		
964
		} catch (Exception e) {
965
			e.printStackTrace();
966
		}
967
		return result;
968
	}
969
	
970
	/**
971
	 * Returns the <code>TaxonStatusCache</code> attribute.
972
	 * @param taxon The {@link TaxonBase Taxon}.
973
	 * @return The <code>TaxonStatusCache</code> attribute.
974
	 * @see MethodMapper
975
	 */
976
	@SuppressWarnings("unused")
977
	private static String getTaxonStatusCache(TaxonNameBase taxonName) {
978
		String result = null;
979
		
980
		try {
981
		Set taxa = taxonName.getTaxa();
982
		if (taxa.size() == 1) {
983
			result = PesiTransformer.taxonBase2statusCache((TaxonBase<?>) taxa.iterator().next());
984
		} else if (taxa.size() > 1) {
985
			logger.warn("This TaxonName has " + taxa.size() + " Taxa: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
986
		}
987
		
988
		} catch (Exception e) {
989
			e.printStackTrace();
990
		}
991
		return result;
992
	}
993
	
994
	/**
995
	 * Returns the <code>TypeNameFk</code> attribute.
996
	 * @param taxon The {@link TaxonBase Taxon}.
997
	 * @return The <code>TypeNameFk</code> attribute.
998
	 * @see MethodMapper
999
	 */
1000
	@SuppressWarnings("unused")
1001
	private static Integer getTypeNameFk(TaxonNameBase taxonNameBase, PesiExportState state) {
1002
		Integer result = null;
1003
//		if (taxonNameBase != null) {
1004
//			Set<NameTypeDesignation> nameTypeDesignations = taxonNameBase.getNameTypeDesignations();
1005
//			if (nameTypeDesignations.size() == 1) {
1006
//				NameTypeDesignation nameTypeDesignation = nameTypeDesignations.iterator().next();
1007
//				if (nameTypeDesignation != null) {
1008
//					TaxonNameBase typeName = nameTypeDesignation.getTypeName();
1009
//					if (typeName != null) {
1010
//						Set<TaxonBase> taxa = typeName.getTaxa();
1011
//						if (taxa.size() == 1) {
1012
//							TaxonBase singleTaxon = taxa.iterator().next();
1013
//							result = state.getDbId(singleTaxon.getName());
1014
//						} else if (taxa.size() > 1) {
1015
//							logger.warn("This TaxonName has " + taxa.size() + " Taxa: " + taxonNameBase.getUuid() + " (" + taxonNameBase.getTitleCache() + ")");
1016
//						}
1017
//					}
1018
//				}
1019
//			} else if (nameTypeDesignations.size() > 1) {
1020
//				logger.warn("This TaxonName has " + nameTypeDesignations.size() + " NameTypeDesignations: " + taxonNameBase.getUuid() + " (" + taxonNameBase.getTitleCache() + ")");
1021
//			}
1022
//		}
1023
//		if (result != null) {
1024
//			logger.error("Taxon Id: " + result);
1025
//			logger.error("TaxonName: " + taxonNameBase.getUuid() + " (" + taxonNameBase.getTitleCache() +")");
1026
//		}
1027
		return result;
1028
	}
1029
	
1030
	/**
1031
	 * Returns the <code>TypeFullnameCache</code> attribute.
1032
	 * @param taxon The {@link TaxonBase Taxon}.
1033
	 * @return The <code>TypeFullnameCache</code> attribute.
1034
	 * @see MethodMapper
1035
	 */
1036
	@SuppressWarnings("unused")
1037
	private static String getTypeFullnameCache(TaxonNameBase taxonName) {
1038
		String result = null;
1039
		
1040
		try {
1041
		if (taxonName != null) {
1042
			Set<NameTypeDesignation> nameTypeDesignations = taxonName.getNameTypeDesignations();
1043
			if (nameTypeDesignations.size() == 1) {
1044
				NameTypeDesignation nameTypeDesignation = nameTypeDesignations.iterator().next();
1045
				if (nameTypeDesignation != null) {
1046
					TaxonNameBase typeName = nameTypeDesignation.getTypeName();
1047
					if (typeName != null) {
1048
						result = typeName.getTitleCache();
1049
					}
1050
				}
1051
			} else if (nameTypeDesignations.size() > 1) {
1052
				logger.warn("This TaxonName has " + nameTypeDesignations.size() + " NameTypeDesignations: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
1053
			}
1054
		}
1055
		
1056
		} catch (Exception e) {
1057
			e.printStackTrace();
1058
		}
1059
		return result;
1060
	}
1061
	
1062
	/**
1063
	 * Returns the <code>QualityStatusFk</code> attribute.
1064
	 * @param taxon The {@link TaxonBase Taxon}.
1065
	 * @return The <code>QualityStatusFk</code> attribute.
1066
	 * @see MethodMapper
1067
	 */
1068
	@SuppressWarnings("unused")
1069
	private static Integer getQualityStatusFk(TaxonNameBase taxonName) {
1070
		// TODO: Not represented in CDM right now. Depends on import.
1071
		Integer result = null;
1072
		return result;
1073
	}
1074
	
1075
	/**
1076
	 * Returns the <code>QualityStatusCache</code> attribute.
1077
	 * @param taxon The {@link TaxonBase Taxon}.
1078
	 * @return The <code>QualityStatusCache</code> attribute.
1079
	 * @see MethodMapper
1080
	 */
1081
	@SuppressWarnings("unused")
1082
	private static String getQualityStatusCache(TaxonNameBase taxonName) {
1083
		// TODO: Not represented in CDM right now. Depends on import.
1084
		String result = null;
1085
		return result;
1086
	}
1087
	
1088
	/**
1089
	 * Returns the <code>TypeDesignationStatusFk</code> attribute.
1090
	 * @param taxon The {@link TaxonBase Taxon}.
1091
	 * @return The <code>TypeDesignationStatusFk</code> attribute.
1092
	 * @see MethodMapper
1093
	 */
1094
	@SuppressWarnings("unused")
1095
	private static Integer getTypeDesignationStatusFk(TaxonNameBase taxonName) {
1096
		Integer result = null;
1097
		
1098
		try {
1099
		if (taxonName != null) {
1100
			Set<NameTypeDesignation> typeDesignations = taxonName.getNameTypeDesignations();
1101
			if (typeDesignations.size() == 1) {
1102
				Object obj = typeDesignations.iterator().next().getTypeStatus();
1103
				NameTypeDesignationStatus designationStatus = CdmBase.deproxy(obj, NameTypeDesignationStatus.class);
1104
				result = PesiTransformer.nameTypeDesignationStatus2TypeDesignationStatusId(designationStatus);
1105
			} else if (typeDesignations.size() > 1) {
1106
				logger.error("Found a TaxonName with more than one NameTypeDesignation: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
1107
			}
1108
		}
1109
		
1110
		} catch (Exception e) {
1111
			e.printStackTrace();
1112
		}
1113
		return result;
1114
	}
1115

    
1116
	/**
1117
	 * Returns the <code>TypeDesignationStatusCache</code> attribute.
1118
	 * @param taxon The {@link TaxonBase Taxon}.
1119
	 * @return The <code>TypeDesignationStatusCache</code> attribute.
1120
	 * @see MethodMapper
1121
	 */
1122
	@SuppressWarnings("unused")
1123
	private static String getTypeDesignationStatusCache(TaxonNameBase taxonName) {
1124
		String result = null;
1125
		
1126
		try {
1127
		if (taxonName != null) {
1128
			Set<NameTypeDesignation> typeDesignations = taxonName.getNameTypeDesignations();
1129
			if (typeDesignations.size() == 1) {
1130
				Object obj = typeDesignations.iterator().next().getTypeStatus();
1131
				NameTypeDesignationStatus designationStatus = CdmBase.deproxy(obj, NameTypeDesignationStatus.class);
1132
				result = PesiTransformer.nameTypeDesignationStatus2TypeDesignationStatusCache(designationStatus);
1133
			} else if (typeDesignations.size() > 1) {
1134
				logger.error("Found a TaxonName with more than one NameTypeDesignation: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
1135
			}
1136
		}
1137
		
1138
		} catch (Exception e) {
1139
			e.printStackTrace();
1140
		}
1141
		return result;
1142
	}
1143
	
1144
	/**
1145
	 * Returns the <code>FossilStatusFk</code> attribute.
1146
	 * @param taxon The {@link TaxonBase Taxon}.
1147
	 * @return The <code>FossilStatusFk</code> attribute.
1148
	 * @see MethodMapper
1149
	 */
1150
	@SuppressWarnings("unused")
1151
	private static Integer getFossilStatusFk(TaxonNameBase taxonNameBase) {
1152
		Integer result = null;
1153
//		Taxon taxon;
1154
//		if (taxonBase.isInstanceOf(Taxon.class)) {
1155
//			taxon = CdmBase.deproxy(taxonBase, Taxon.class);
1156
//			Set<TaxonDescription> specimenDescription = taxon.;
1157
//			result = PesiTransformer.fossil2FossilStatusId(fossil);
1158
//		}
1159
		return result;
1160
	}
1161
	
1162
	/**
1163
	 * Returns the <code>FossilStatusCache</code> attribute.
1164
	 * @param taxon The {@link TaxonBase Taxon}.
1165
	 * @return The <code>FossilStatusCache</code> attribute.
1166
	 * @see MethodMapper
1167
	 */
1168
	@SuppressWarnings("unused")
1169
	private static String getFossilStatusCache(TaxonNameBase taxonName) {
1170
		// TODO
1171
		String result = null;
1172
		return result;
1173
	}
1174
	
1175
	/**
1176
	 * Returns the <code>IdInSource</code> attribute.
1177
	 * @param taxon The {@link TaxonBase Taxon}.
1178
	 * @return The <code>IdInSource</code> attribute.
1179
	 * @see MethodMapper
1180
	 */
1181
	@SuppressWarnings("unused")
1182
	private static String getIdInSource(TaxonNameBase taxonName) {
1183
		return null;
1184
//		String result = "Nominal Taxon from TAX_ID: ";
1185
//		boolean set = false;
1186
//		
1187
//		try {
1188
//			if (taxon != null) {
1189
//				TaxonNameBase taxonName = taxon.getName();
1190
//				Set taxa = taxonName.getTaxa();
1191
//				if (taxa.size() == 1) {
1192
//					IdentifiableEntity singleTaxon = (IdentifiableEntity) taxa.iterator().next();
1193
//					if (singleTaxon != null) {
1194
//						Set<IdentifiableSource> sources = singleTaxon.getSources();
1195
//						if (sources.size() == 1) {
1196
//							IdentifiableSource source = sources.iterator().next();
1197
//							if (source != null) {
1198
//								result += source.getIdInSource();
1199
//								set = true;
1200
//							}
1201
//						} else if (sources.size() > 1) {
1202
//							logger.warn("Taxon has multiple IdentifiableSources: " + singleTaxon.getUuid() + " (" + singleTaxon.getTitleCache() + ")");
1203
//							int count = 1;
1204
//							for (IdentifiableSource source : sources) {
1205
//								result += source.getIdInSource();
1206
//								if (count < sources.size()) {
1207
//									result += "; ";
1208
//								}
1209
//								count++;
1210
//								set = true;
1211
//							}
1212
//						} else {
1213
//							result = null;
1214
//						}
1215
//					}
1216
//				} else if (taxa.size() > 1) {
1217
//					logger.warn("This TaxonName has " + taxa.size() + " Taxa: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() +")");
1218
//				}
1219
//			}
1220
//		
1221
//		} catch (Exception e) {
1222
//			e.printStackTrace();
1223
//		}
1224
//		
1225
//		if (set) {
1226
//			return result;
1227
//		} else {
1228
//			return null;
1229
//		}
1230
	}
1231
	
1232
	/**
1233
	 * Returns the <code>GUID</code> attribute.
1234
	 * @param taxon The {@link TaxonBase Taxon}.
1235
	 * @return The <code>GUID</code> attribute.
1236
	 * @see MethodMapper
1237
	 */
1238
	@SuppressWarnings("unused")
1239
	private static String getGUID(TaxonNameBase taxonName) {
1240
		// TODO
1241
		String result = null;
1242
		return result;
1243
	}
1244
	
1245
	/**
1246
	 * Returns the <code>DerivedFromGuid</code> attribute.
1247
	 * @param taxon The {@link TaxonBase Taxon}.
1248
	 * @return The <code>DerivedFromGuid</code> attribute.
1249
	 * @see MethodMapper
1250
	 */
1251
	@SuppressWarnings("unused")
1252
	private static String getDerivedFromGuid(TaxonNameBase taxonName) {
1253
		// TODO
1254
		String result = null;
1255
		return result;
1256
	}
1257
	
1258
	/**
1259
	 * Returns the <code>OriginalDB</code> attribute.
1260
	 * @param taxon The {@link TaxonBase Taxon}.
1261
	 * @return The <code>OriginalDB</code> attribute.
1262
	 * @see MethodMapper
1263
	 */
1264
	@SuppressWarnings("unused")
1265
	private static String getOriginalDB(TaxonNameBase taxonName) {
1266
		String result = "";
1267
		try {
1268
		Set taxa = taxonName.getTaxa();
1269
		if (taxa.size() == 1) {
1270
			IdentifiableEntity singleTaxon = (IdentifiableEntity) taxa.iterator().next();
1271
			if (singleTaxon != null) {
1272
				Set<IdentifiableSource> sources = singleTaxon.getSources();
1273
				if (sources.size() == 1) {
1274
					IdentifiableSource source = sources.iterator().next();
1275
					if (source != null) {
1276
						ReferenceBase citation = source.getCitation();
1277
						if (citation != null) {
1278
							result = PesiTransformer.databaseString2Abbreviation(citation.getTitleCache());
1279
						}
1280
					}
1281
				} else if (sources.size() > 1) {
1282
					logger.warn("Taxon has multiple IdentifiableSources: " + singleTaxon.getUuid() + " (" + singleTaxon.getTitleCache() + ")");
1283
					int count = 1;
1284
					for (IdentifiableSource source : sources) {
1285
						result += PesiTransformer.databaseString2Abbreviation(source.getCitation().getTitleCache());
1286
						if (count < sources.size()) {
1287
							result += "; ";
1288
						}
1289
						count++;
1290
					}
1291
				} else {
1292
					result = null;
1293
				}
1294
			}
1295
		} else if (taxa.size() > 1) {
1296
			logger.warn("This TaxonName has " + taxa.size() + " Taxa: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() +")");
1297
		}
1298

    
1299
		} catch (Exception e) {
1300
			e.printStackTrace();
1301
		}
1302
		if ("".equals(result)) {
1303
			return null;
1304
		} else {
1305
			return result;
1306
		}
1307
	}
1308
	
1309
	/**
1310
	 * Returns the <code>LastAction</code> attribute.
1311
	 * @param taxon The {@link TaxonBase Taxon}.
1312
	 * @return The <code>LastAction</code> attribute.
1313
	 * @see MethodMapper
1314
	 */
1315
	@SuppressWarnings("unused")
1316
	private static String getLastAction(TaxonNameBase taxonName) {
1317
		// TODO
1318
		return null;
1319
	}
1320
	
1321
	/**
1322
	 * Returns the <code>LastActionDate</code> attribute.
1323
	 * @param taxon The {@link TaxonBase Taxon}.
1324
	 * @return The <code>LastActionDate</code> attribute.
1325
	 * @see MethodMapper
1326
	 */
1327
	@SuppressWarnings("unused")
1328
	private static DateTime getLastActionDate(TaxonNameBase taxonNameBase) {
1329
		DateTime result = null;
1330
		
1331
		try {
1332
		if (taxonNameBase != null) {
1333
			Set taxa = taxonNameBase.getTaxa();
1334
			if (taxa.size() == 1) {
1335
				VersionableEntity singleTaxon = (VersionableEntity) taxa.iterator().next();
1336
				if (singleTaxon != null) {
1337
					DateTime updated = singleTaxon.getUpdated();
1338
					if (updated != null) {
1339
		//				logger.error("Taxon Updated: " + updated);
1340
						result = new DateTime(updated.toDate()); // Unfortunately the time information gets lost here.
1341
					}
1342
				}
1343
			} else if (taxa.size() > 1) {
1344
				logger.warn("This TaxonName has " + taxa.size() + " Taxa: " + taxonNameBase.getUuid() + " (" + taxonNameBase.getTitleCache() + ")");
1345
			}
1346
		}
1347
		
1348
		} catch (Exception e) {
1349
			e.printStackTrace();
1350
		}
1351
		return result;
1352
	}
1353
	
1354
	/**
1355
	 * Returns the <code>ExpertName</code> attribute.
1356
	 * @param taxon The {@link TaxonBase Taxon}.
1357
	 * @return The <code>ExpertName</code> attribute.
1358
	 * @see MethodMapper
1359
	 */
1360
	@SuppressWarnings("unused")
1361
	private static String getExpertName(TaxonNameBase taxonName) {
1362
		// TODO
1363
		return null;
1364
	}
1365
	
1366
	/**
1367
	 * Returns the <code>ExpertFk</code> attribute.
1368
	 * @param taxon The {@link TaxonBase Taxon}.
1369
	 * @return The <code>ExpertFk</code> attribute.
1370
	 * @see MethodMapper
1371
	 */
1372
	@SuppressWarnings("unused")
1373
	private static String getExpertFk(TaxonNameBase taxonName) {
1374
		// TODO
1375
		return null;
1376
	}
1377
	
1378
	@SuppressWarnings("unused")
1379
	private static Integer getSourceFk(TaxonNameBase taxonName, PesiExportState state) {
1380
		Integer result = null;
1381
		
1382
		try {
1383
		Set taxa = taxonName.getTaxa();
1384
		if (taxa.size() == 1) {
1385
			TaxonBase singleTaxon = CdmBase.deproxy(taxa.iterator().next(), TaxonBase.class);
1386
			result = state.getDbId(singleTaxon.getSec());
1387
		} else if (taxa.size() > 1) {
1388
			logger.warn("This TaxonName has " + taxa.size() + " Taxa: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
1389
		}
1390
		
1391
		} catch (Exception e) {
1392
			e.printStackTrace();
1393
		}
1394
		return result;
1395
	}
1396
	
1397
	/**
1398
	 * Returns the CDM to PESI specific export mappings.
1399
	 * @return The {@link PesiExportMapping PesiExportMapping}.
1400
	 */
1401
	private PesiExportMapping getMapping() {
1402
		PesiExportMapping mapping = new PesiExportMapping(dbTableName);
1403
		
1404
		mapping.addMapper(IdMapper.NewInstance("TaxonId"));
1405
		mapping.addMapper(MethodMapper.NewInstance("SourceFK", this.getClass(), "getSourceFk", standardMethodParameter, PesiExportState.class));
1406
//		mapping.addMapper(MethodMapper.NewInstance("KingdomFk", this.getClass(), "getKingdomFk", standardMethodParameter, PesiExportState.class));
1407
//		mapping.addMapper(MethodMapper.NewInstance("RankFk", this));
1408
//		mapping.addMapper(MethodMapper.NewInstance("RankCache", this));
1409
		mapping.addMapper(MethodMapper.NewInstance("GenusOrUninomial", this));
1410
		mapping.addMapper(MethodMapper.NewInstance("InfraGenericEpithet", this));
1411
		mapping.addMapper(MethodMapper.NewInstance("SpecificEpithet", this));
1412
		mapping.addMapper(MethodMapper.NewInstance("InfraSpecificEpithet", this));
1413
		mapping.addMapper(MethodMapper.NewInstance("WebSearchName", this));
1414
		mapping.addMapper(MethodMapper.NewInstance("WebShowName", this));
1415
		mapping.addMapper(MethodMapper.NewInstance("AuthorString", this));
1416
		mapping.addMapper(MethodMapper.NewInstance("FullName", this));
1417
		mapping.addMapper(MethodMapper.NewInstance("NomRefString", this));
1418
		mapping.addMapper(MethodMapper.NewInstance("DisplayName", this));
1419
		mapping.addMapper(MethodMapper.NewInstance("FuzzyName", this));
1420
		mapping.addMapper(MethodMapper.NewInstance("NameStatusFk", this));
1421
		mapping.addMapper(MethodMapper.NewInstance("NameStatusCache", this));
1422
		mapping.addMapper(MethodMapper.NewInstance("TaxonStatusFk", this));
1423
		mapping.addMapper(MethodMapper.NewInstance("TaxonStatusCache", this));
1424
		mapping.addMapper(MethodMapper.NewInstance("TypeNameFk", this.getClass(), "getTypeNameFk", standardMethodParameter, PesiExportState.class));
1425
		mapping.addMapper(MethodMapper.NewInstance("TypeFullnameCache", this));
1426
		mapping.addMapper(MethodMapper.NewInstance("QualityStatusFk", this));
1427
		mapping.addMapper(MethodMapper.NewInstance("QualityStatusCache", this));
1428
		mapping.addMapper(MethodMapper.NewInstance("TypeDesignationStatusFk", this));
1429
		mapping.addMapper(MethodMapper.NewInstance("TypeDesignationStatusCache", this));
1430
//		mapping.addMapper(MethodMapper.NewInstance("TreeIndex", this.getClass(), "getTreeIndex", standardMethodParameter, PesiExportState.class));
1431
		mapping.addMapper(MethodMapper.NewInstance("FossilStatusFk", this));
1432
		mapping.addMapper(MethodMapper.NewInstance("FossilStatusCache", this));
1433
		mapping.addMapper(MethodMapper.NewInstance("IdInSource", this));
1434
		mapping.addMapper(MethodMapper.NewInstance("GUID", this)); // TODO
1435
		mapping.addMapper(MethodMapper.NewInstance("DerivedFromGuid", this)); // TODO
1436
		mapping.addMapper(MethodMapper.NewInstance("OriginalDB", this));
1437
		mapping.addMapper(MethodMapper.NewInstance("LastAction", this));
1438
//		mapping.addMapper(DbTimePeriodMapper.NewInstance("updated", "LastActionDate"));
1439
		mapping.addMapper(MethodMapper.NewInstance("LastActionDate", this));
1440
		mapping.addMapper(MethodMapper.NewInstance("ExpertName", this)); // TODO
1441
		mapping.addMapper(MethodMapper.NewInstance("ExpertFk", this)); // TODO
1442

    
1443
		return mapping;
1444
	}
1445
}
(13-13/14)