Project

General

Profile

Download (40.1 KB) Statistics
| Branch: | Revision:
1
/**
2
* Copyright (C) 2007 EDIT
3
* European Distributed Institute of Taxonomy 
4
* http://www.e-taxonomy.eu
5
* 
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9

    
10
package eu.etaxonomy.cdm.io.pesi.faunaEuropaea;
11

    
12
import static eu.etaxonomy.cdm.io.pesi.faunaEuropaea.FaunaEuropaeaTransformer.A_AUCT;
13
import static eu.etaxonomy.cdm.io.pesi.faunaEuropaea.FaunaEuropaeaTransformer.P_PARENTHESIS;
14
import static eu.etaxonomy.cdm.io.pesi.faunaEuropaea.FaunaEuropaeaTransformer.R_GENUS;
15
import static eu.etaxonomy.cdm.io.pesi.faunaEuropaea.FaunaEuropaeaTransformer.R_SPECIES;
16
import static eu.etaxonomy.cdm.io.pesi.faunaEuropaea.FaunaEuropaeaTransformer.R_SUBGENUS;
17
import static eu.etaxonomy.cdm.io.pesi.faunaEuropaea.FaunaEuropaeaTransformer.R_SUBSPECIES;
18
import static eu.etaxonomy.cdm.io.pesi.faunaEuropaea.FaunaEuropaeaTransformer.T_STATUS_ACCEPTED;
19
import static eu.etaxonomy.cdm.io.pesi.faunaEuropaea.FaunaEuropaeaTransformer.T_STATUS_NOT_ACCEPTED;
20

    
21
import java.sql.ResultSet;
22
import java.sql.SQLException;
23
import java.util.Collection;
24
import java.util.HashMap;
25
import java.util.HashSet;
26
import java.util.Map;
27
import java.util.Set;
28
import java.util.UUID;
29
import java.util.regex.Matcher;
30
import java.util.regex.Pattern;
31

    
32
import org.apache.log4j.Logger;
33
import org.springframework.stereotype.Component;
34
import org.springframework.transaction.TransactionStatus;
35

    
36
import eu.etaxonomy.cdm.app.common.ImportUtils;
37
import eu.etaxonomy.cdm.common.CdmUtils;
38
import eu.etaxonomy.cdm.io.common.ICdmIO;
39
import eu.etaxonomy.cdm.io.common.ImportHelper;
40
import eu.etaxonomy.cdm.io.common.MapWrapper;
41
import eu.etaxonomy.cdm.io.common.Source;
42
import eu.etaxonomy.cdm.io.pesi.out.PesiTransformer;
43
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
44
import eu.etaxonomy.cdm.model.common.CdmBase;
45
import eu.etaxonomy.cdm.model.common.Extension;
46
import eu.etaxonomy.cdm.model.common.ExtensionType;
47
import eu.etaxonomy.cdm.model.common.IdentifiableSource;
48
import eu.etaxonomy.cdm.model.common.LSID;
49
import eu.etaxonomy.cdm.model.name.Rank;
50
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
51
import eu.etaxonomy.cdm.model.name.ZoologicalName;
52
import eu.etaxonomy.cdm.model.reference.Reference;
53
import eu.etaxonomy.cdm.model.taxon.Synonym;
54
import eu.etaxonomy.cdm.model.taxon.Taxon;
55
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
56
import eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException;
57

    
58

    
59
/**
60
 * @author a.babadshanjan
61
 * @created 12.05.2009
62
 * @version 1.0
63
 */
64
@Component
65
public class FaunaEuropaeaTaxonNameImport extends FaunaEuropaeaImportBase  {
66
	
67
	public static final String OS_NAMESPACE_TAXON = "Taxon";
68
	private static final Logger logger = Logger.getLogger(FaunaEuropaeaTaxonNameImport.class);
69

    
70
	/* Max number of taxa to retrieve (for test purposes) */
71
	private int maxTaxa = 0;
72

    
73
	/* (non-Javadoc)
74
	 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doCheck(eu.etaxonomy.cdm.io.common.IImportConfigurator)
75
	 */
76
	@Override
77
	protected boolean doCheck(FaunaEuropaeaImportState state) {
78
		boolean result = true;
79
		FaunaEuropaeaImportConfigurator fauEuConfig = state.getConfig();
80
		logger.warn("Checking for Taxa not yet fully implemented");
81
		result &= checkTaxonStatus(fauEuConfig);
82
		
83
		return result;
84
	}
85
	
86
	/* (non-Javadoc)
87
	 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IImportConfigurator)
88
	 */
89
	protected boolean isIgnore(FaunaEuropaeaImportState state) {
90
		return ! state.getConfig().isDoTaxa();
91
	}
92

    
93
	private boolean checkTaxonStatus(FaunaEuropaeaImportConfigurator fauEuConfig) {
94
		boolean result = true;
95
//		try {
96
			Source source = fauEuConfig.getSource();
97
			String sqlStr = "";
98
			ResultSet rs = source.getResultSet(sqlStr);
99
			return result;
100
//		} catch (SQLException e) {
101
//			e.printStackTrace();
102
//			return false;
103
//		}
104
	}
105
	
106
	/** 
107
	 * Import taxa from FauEU DB
108
	 */
109
	protected void doInvoke(FaunaEuropaeaImportState state) {				
110
		if(logger.isInfoEnabled()) { logger.info("Start making taxa..."); }
111
		
112
		processTaxa(state);
113
		logger.info("End making taxa...");
114
		return;
115
	}
116

    
117
	/**
118
	 * Returns the ExtensionType for a given UUID.
119
	 * @param uuid
120
	 * @param label
121
	 * @param text
122
	 * @param labelAbbrev
123
	 * @return
124
	 */
125
	protected ExtensionType getExtensionType(UUID uuid, String label, String text, String labelAbbrev){
126
		ExtensionType extensionType = (ExtensionType)getTermService().find(uuid);
127
		if (extensionType == null) {
128
			extensionType = ExtensionType.NewInstance(label, text, labelAbbrev);
129
			extensionType.setUuid(uuid);
130
//			annotationType.setVocabulary(AnnotationType.EDITORIAL().getVocabulary());
131
			getTermService().save(extensionType);
132
		}
133
		return extensionType;
134
	}
135

    
136
	/**
137
	 * Returns an empty string in case of a null string.
138
	 * This avoids having the string "null" when using StringBuilder.append(null);
139
	 * @param string
140
	 * @return
141
	 */
142
	private String NullToEmpty(String string) {
143
		if (string == null) {
144
			return "";
145
		} else {
146
			return string;
147
		}
148
	}
149

    
150
	/** Retrieve taxa from FauEu DB, process in blocks */
151
	private void processTaxa(FaunaEuropaeaImportState state) {
152

    
153
		int limit = state.getConfig().getLimitSave();
154

    
155
		TransactionStatus txStatus = null;
156

    
157
		Map<String, MapWrapper<? extends CdmBase>> stores = state.getStores();
158
		MapWrapper<TeamOrPersonBase> authorStore = (MapWrapper<TeamOrPersonBase>)stores.get(ICdmIO.TEAM_STORE);
159
		
160
		Map<Integer, TaxonBase<?>> taxonMap = null;
161
		Map<Integer, FaunaEuropaeaTaxon> fauEuTaxonMap = null;
162
		/* Store for heterotypic synonyms to be save separately */
163
		Set<Synonym> synonymSet = null;
164

    
165
		FaunaEuropaeaImportConfigurator fauEuConfig = state.getConfig();
166
		Reference<?> sourceRef = fauEuConfig.getSourceReference();
167

    
168
		Source source = fauEuConfig.getSource();
169
		int i = 0;
170
		
171
		String selectCount = 
172
			" SELECT count(*) ";
173

    
174
		String selectColumns = 
175
			" SELECT Parent.TAX_NAME AS P2Name, Parent.TAX_RNK_ID AS P2RankId, " +
176
			" GrandParent.TAX_ID AS GP3Id, GrandParent.TAX_NAME AS GP3Name, GrandParent.TAX_RNK_ID AS GP3RankId, " +
177
			" GreatGrandParent.TAX_ID AS GGP4Id, GreatGrandParent.TAX_NAME AS GGP4Name, GreatGrandParent.TAX_RNK_ID AS GGP4RankId, " +
178
			" GreatGreatGrandParent.TAX_ID AS GGGP5Id, GreatGreatGrandParent.TAX_NAME AS GGGP5Name, GreatGreatGrandParent.TAX_RNK_ID AS GGGP5RankId, " +
179
			" OriginalGenusTaxon.TAX_NAME AS OGenusName, " +
180
			" GreatGreatGreatGrandParent.TAX_ID AS GGGGP6Id, GreatGreatGreatGrandParent.TAX_NAME AS GGGGP6Name, GreatGreatGreatGrandParent.TAX_RNK_ID AS GGGGP6RankId," +
181
			" expertUsers.usr_id AS expertUserId, expertUsers.usr_title AS ExpertUsrTitle, expertUsers.usr_firstname AS ExpertUsrFirstname, expertUsers.usr_lastname AS ExpertUsrLastname," +
182
			" speciesExpertUsers.usr_id AS speciesExpertUserId, speciesExpertUsers.usr_title AS SpeciesUsrTitle, speciesExpertUsers.usr_firstname AS SpeciesUsrFirstname, speciesExpertUsers.usr_lastname AS SpeciesUsrLastname," +
183
			" Taxon.*, rank.*, author.* ";
184
		
185
		String fromClause = 
186
			" FROM Taxon LEFT OUTER JOIN " +
187
			" Taxon AS Parent ON Taxon.TAX_TAX_IDPARENT = Parent.TAX_ID LEFT OUTER JOIN " +
188
			" Taxon AS GrandParent ON Parent.TAX_TAX_IDPARENT = GrandParent.TAX_ID LEFT OUTER JOIN " +
189
			" Taxon AS GreatGrandParent ON GrandParent.TAX_TAX_IDPARENT = GreatGrandParent.TAX_ID LEFT OUTER JOIN " +
190
			" Taxon AS GreatGreatGrandParent ON GreatGrandParent.TAX_TAX_IDPARENT = GreatGreatGrandParent.TAX_ID LEFT OUTER JOIN " +
191
			" Taxon AS GreatGreatGreatGrandParent ON GreatGreatGrandParent.TAX_TAX_IDPARENT = GreatGreatGreatGrandParent.TAX_ID LEFT OUTER JOIN " +
192
			" Taxon AS OriginalGenusTaxon ON Taxon.TAX_TAX_IDGENUS = OriginalGenusTaxon.TAX_ID LEFT OUTER JOIN " +
193
			" author ON Taxon.TAX_AUT_ID = author.aut_id LEFT OUTER JOIN " +
194
			" users AS expertUsers ON Taxon.TAX_USR_IDGC = expertUsers.usr_id LEFT OUTER JOIN " +
195
			" users AS speciesExpertUsers ON Taxon.TAX_USR_IDSP = speciesExpertUsers.usr_id LEFT OUTER JOIN " +
196
			" rank ON Taxon.TAX_RNK_ID = rank.rnk_id ";
197

    
198
		String countQuery = 
199
			selectCount + fromClause;
200

    
201
		String selectQuery = 
202
			selectColumns + fromClause;
203
		
204

    
205
        try {
206

    
207
			ResultSet rs = source.getResultSet(countQuery);
208
			rs.next();
209
			int count = rs.getInt(1);
210
			
211
			rs = source.getResultSet(selectQuery);
212

    
213
	        if (logger.isInfoEnabled()) {
214
				logger.info("Number of rows: " + count);
215
				logger.info("Count Query: " + countQuery);
216
				logger.info("Select Query: " + selectQuery);
217
			}
218
	        
219
			while (rs.next()) {
220

    
221
				if ((i++ % limit) == 0) {
222
					
223
					txStatus = startTransaction();
224
					taxonMap = new HashMap<Integer, TaxonBase<?>>(limit);
225
					fauEuTaxonMap = new HashMap<Integer, FaunaEuropaeaTaxon>(limit);
226
					synonymSet = new HashSet<Synonym>();
227
					
228
					if(logger.isInfoEnabled()) {
229
						logger.info("i = " + i + " - Transaction started"); 
230
					}
231
				}
232

    
233
				String localName = rs.getString("TAX_NAME");
234
				String parentName = rs.getString("P2Name");
235
				int grandParentId = rs.getInt("GP3Id");
236
				String grandParentName = rs.getString("GP3Name");
237
				int greatGrandParentId = rs.getInt("GGP4Id");
238
				String greatGrandParentName = rs.getString("GGP4Name");
239
				int greatGreatGrandParentId = rs.getInt("GGGP5Id");
240
				String greatGreatGrandParentName = rs.getString("GGGP5Name");
241
				String greatGreatGreatGrandParentName = rs.getString("GGGGP6Name");
242
				String originalGenusName = rs.getString("OGenusName");
243
				String autName = rs.getString("aut_name");
244
				int taxonId = rs.getInt("TAX_ID");
245
				int rankId = rs.getInt("TAX_RNK_ID");
246
				int parentId = rs.getInt("TAX_TAX_IDPARENT");
247
				int parentRankId = rs.getInt("P2RankId");
248
				int grandParentRankId = rs.getInt("GP3RankId");
249
				int greatGrandParentRankId = rs.getInt("GGP4RankId");
250
				int greatGreatGrandParentRankId = rs.getInt("GGGP5RankId");
251
				int greatGreatGreatGrandParentRankId = rs.getInt("GGGGP6RankId");
252
				int originalGenusId = rs.getInt("TAX_TAX_IDGENUS");
253
				int autId = rs.getInt("TAX_AUT_ID");
254
				int status = rs.getInt("TAX_VALID");
255

    
256
				// user related
257
				String expertUsrTitle = rs.getString("ExpertUsrTitle");
258
				String expertUsrFirstname = rs.getString("ExpertUsrFirstname");
259
				String expertUsrLastname = rs.getString("ExpertUsrLastname");
260
				String speciesUsrTitle = rs.getString("SpeciesUsrTitle");
261
				String speciesUsrFirstname = rs.getString("SpeciesUsrFirstname");
262
				String speciesUsrLastname = rs.getString("SpeciesUsrLastname");
263
				String expertUserId = "" + rs.getInt("expertUserId");
264
				String speciesExpertUserId = "" + rs.getInt("speciesExpertUserId");
265

    
266
				String expertName = "";
267
				if (expertUsrTitle != null) {
268
					expertName = expertUsrTitle;
269
					if (! expertUsrTitle.endsWith(".")) {
270
						expertName += ".";
271
					}
272
				}
273
				expertName += expertUsrTitle == null ? NullToEmpty(expertUsrFirstname) : " " + NullToEmpty(expertUsrFirstname);
274
				if ((expertUsrTitle != null || expertUsrFirstname != null) && expertUsrLastname != null) {
275
					expertName += " " + expertUsrLastname;
276
				}
277
				
278
				String speciesExpertName = speciesUsrTitle == null ? "" : speciesUsrTitle + ".";
279
				if (speciesUsrTitle != null) {
280
					speciesExpertName = speciesUsrTitle;
281
					if (! speciesUsrTitle.endsWith(".")) {
282
						speciesExpertName += ".";
283
					}
284
				}
285
				speciesExpertName += speciesUsrTitle == null ? NullToEmpty(speciesUsrFirstname) : " " + NullToEmpty(speciesUsrFirstname);
286
				if ((speciesUsrTitle != null || speciesUsrFirstname != null) && speciesUsrLastname != null) {
287
					speciesExpertName += " " + speciesUsrLastname;
288
				}
289
				
290
				// date related
291
				String createdDate = rs.getString("TAX_CREATEDAT");
292
				String modifiedDate = rs.getString("TAX_MODIFIEDAT");
293
				String lastAction = createdDate.equals(modifiedDate) ? "created" : "modified";
294
				String lastActionDate = createdDate.equals(modifiedDate) ? createdDate : modifiedDate;
295
				
296
				// note related
297
				String taxComment = rs.getString("TAX_TAXCOMMENT");
298
				String fauComment = rs.getString("TAX_FAUCOMMENT");
299
				String fauExtraCodes = rs.getString("TAX_FAUEXTRACODES");
300

    
301
				// Avoid publication year 0 for NULL values in database.
302
				Integer year = rs.getInt("TAX_YEAR");
303
				if (year != null && year.intValue() == 0) {
304
					year = null;
305
				}
306
				
307
				//int familyId = rs.getInt("TAX_TAX_IDFAMILY");
308

    
309
				Rank rank = null;
310
				int parenthesis = rs.getInt("TAX_PARENTHESIS");
311
				UUID taxonBaseUuid = null;
312
				if (resultSetHasColumn(rs,"UUID")){
313
					String uuid = rs.getString("UUID");
314
					taxonBaseUuid = UUID.fromString(uuid);
315
				} else {
316
					taxonBaseUuid = UUID.randomUUID();
317
				}
318

    
319
				FaunaEuropaeaTaxon fauEuTaxon = new FaunaEuropaeaTaxon();
320
				fauEuTaxon.setUuid(taxonBaseUuid);
321
				fauEuTaxon.setId(taxonId);
322
				fauEuTaxon.setRankId(rankId);
323
				fauEuTaxon.setLocalName(localName);
324
				
325
				fauEuTaxon.setParentId(parentId);
326
				fauEuTaxon.setParentRankId(parentRankId);
327
				fauEuTaxon.setParentName(parentName);
328
				
329
				fauEuTaxon.setGrandParentId(grandParentId);
330
				fauEuTaxon.setGrandParentRankId(grandParentRankId);
331
				fauEuTaxon.setGrandParentName(grandParentName);
332
				
333
				fauEuTaxon.setGreatGrandParentId(greatGrandParentId);
334
				fauEuTaxon.setGreatGrandParentRankId(greatGrandParentRankId);
335
				fauEuTaxon.setGreatGrandParentName(greatGrandParentName);
336
				
337
				fauEuTaxon.setGreatGreatGrandParentId(greatGreatGrandParentId);
338
				fauEuTaxon.setGreatGreatGrandParentRankId(greatGreatGrandParentRankId);
339
				fauEuTaxon.setGreatGreatGrandParentName(greatGreatGrandParentName);
340
				
341
				fauEuTaxon.setGreatGreatGreatGrandParentRankId(greatGreatGreatGrandParentRankId);
342
				fauEuTaxon.setGreatGreatGreatGrandParentName(greatGreatGreatGrandParentName);
343
				
344
				fauEuTaxon.setOriginalGenusId(originalGenusId);
345
				fauEuTaxon.setYear(year);
346
				fauEuTaxon.setOriginalGenusName(originalGenusName);
347
				fauEuTaxon.setAuthorName(autName);
348
				if (parenthesis == P_PARENTHESIS) {
349
					fauEuTaxon.setParenthesis(true);
350
				} else {
351
					fauEuTaxon.setParenthesis(false);
352
				}
353
				if (status == T_STATUS_ACCEPTED) {
354
					fauEuTaxon.setValid(true);
355
				} else {
356
					fauEuTaxon.setValid(false);
357
				}
358

    
359
//				fauEuTaxon.setAuthorId(autId);
360

    
361
				try {
362
					rank = FaunaEuropaeaTransformer.rankId2Rank(rs, false);
363
				} catch (UnknownCdmTypeException e) {
364
					logger.warn("Taxon (" + taxonId + ") has unknown rank (" + rankId + ") and could not be saved.");
365
					continue;
366
				} catch (NullPointerException e) {
367
					logger.warn("Taxon (" + taxonId + ") has rank null and can not be saved.");
368
					continue;
369
				}
370

    
371
				Reference<?> sourceReference = fauEuConfig.getSourceReference();
372
				Reference<?> auctReference = fauEuConfig.getAuctReference();
373

    
374
				ZoologicalName zooName = ZoologicalName.NewInstance(rank);
375
				TeamOrPersonBase<?> author = authorStore.get(autId);
376
				
377
				zooName.setCombinationAuthorTeam(author);
378
				zooName.setPublicationYear(year);
379
				
380
				// Add UserId extensions to this zooName
381
				Extension.NewInstance(zooName, expertUserId, getExtensionType(PesiTransformer.expertUserIdUuid, "expertUserId", "expertUserId", "EUID"));
382
				Extension.NewInstance(zooName, speciesExpertUserId, getExtensionType(PesiTransformer.speciesExpertUserIdUuid, "speciesExpertUserId", "speciesExpertUserId", "SEUID"));
383
				
384
				// Add Expert extensions to this zooName
385
				Extension.NewInstance(zooName, expertName, getExtensionType(PesiTransformer.expertNameUuid, "ExpertName", "ExpertName", "EN"));
386
				Extension.NewInstance(zooName, speciesExpertName, getExtensionType(PesiTransformer.speciesExpertNameUuid, "SpeciesExpertName", "SpeciesExpertName", "SEN"));
387

    
388
				// Add Date extensions to this zooName
389
				Extension.NewInstance(zooName, lastAction, getExtensionType(PesiTransformer.lastActionUuid, "LastAction", "LastAction", "LA"));
390
				Extension.NewInstance(zooName, lastActionDate, getExtensionType(PesiTransformer.lastActionDateUuid, "LastActionDate", "LastActionDate", "LAD"));
391

    
392
				/* Add Note extensions to this zooName
393
				Extension.NewInstance(zooName, taxComment, getExtensionType(PesiTransformer.taxCommentUuid, "TaxComment", "TaxComment", "TC"));
394
				Extension.NewInstance(zooName, fauComment, getExtensionType(PesiTransformer.fauCommentUuid, "FauComment", "FauComment", "FC"));
395
				Extension.NewInstance(zooName, fauExtraCodes, getExtensionType(PesiTransformer.fauExtraCodesUuid, "FauExtraCodes", "FauExtraCodes", "FEC"));
396
				*/
397
				TaxonBase<?> taxonBase;
398

    
399
				Synonym synonym = null;
400
				Taxon taxon;
401
				try {
402
					// check for occurrence of the auct string in auctName
403
					String auctRegEx = "\\bauct\\b\\.?"; // The word "auct" with or without "."
404
					
405
					String auctWithNecRegEx = "\\bauct\\b\\.?.*\\bnec\\b\\.?.*";
406
					String necAuctRegEx = ".*\\bnec\\b\\.?.*\\bauct\\b\\.?";
407
					
408
					boolean auctNecFound = expressionMatches(auctWithNecRegEx, autName);
409
					boolean necAuctFound = expressionMatches(necAuctRegEx, autName);
410
					boolean auctWordFound = expressionMatches(auctRegEx, autName);
411
					
412
						
413
					
414
					if (status == T_STATUS_ACCEPTED ) {
415
						
416
							taxon = Taxon.NewInstance(zooName, sourceReference);
417
							if (logger.isDebugEnabled()) {
418
								logger.debug("Taxon created (" + taxonId + ")");
419
							}
420
							
421
						
422
						taxonBase = taxon;
423
					} else if ((status == T_STATUS_NOT_ACCEPTED) && ! auctWordFound) { // synonym
424
						synonym = Synonym.NewInstance(zooName, sourceReference);
425
						//logger.info("Synonym created: " + synonym.getTitleCache() + " taxonName: " + zooName.getTitleCache());
426
						if (logger.isDebugEnabled()) {
427
							logger.debug("Synonym created (" + taxonId + ")");
428
						}
429
						taxonBase = synonym;
430
					} else if (status == T_STATUS_NOT_ACCEPTED && (necAuctFound || auctNecFound)){
431
						synonym = Synonym.NewInstance(zooName, sourceReference);
432
						synonym.setDoubtful(true);
433
						taxonBase = synonym;
434
						logger.info("Misapplied name created ("+ taxonId + ") " + autName);
435
					}else if (status == T_STATUS_NOT_ACCEPTED && auctWordFound){
436
							// misapplied name
437
								zooName.setCombinationAuthorTeam(null);
438
								zooName.setPublicationYear(null);
439
								taxon = Taxon.NewInstance(zooName, auctReference);
440
								taxonBase = taxon;
441
								logger.info("Misapplied name created ("+ taxonId + ") " + autName);
442
								if (logger.isDebugEnabled()) {
443
									logger.debug("Misapplied name created (" + taxonId + ")");
444
									}
445
					}else{
446
						
447
						logger.warn("Unknown taxon status " + status + ". Taxon (" + taxonId + ") ignored.");
448
						continue;
449
					}
450

    
451
					taxonBase.setUuid(taxonBaseUuid);
452
					taxonBase.setLsid(new LSID( "urn:lsid:faunaeur.org:taxname:"+taxonId));
453
					
454
					// Add Note extensions to this taxon
455
					Extension.NewInstance(taxonBase, taxComment, getExtensionType(PesiTransformer.taxCommentUuid, "TaxComment", "TaxComment", "TC"));
456
					Extension.NewInstance(taxonBase, fauComment, getExtensionType(PesiTransformer.fauCommentUuid, "FauComment", "FauComment", "FC"));
457
					Extension.NewInstance(taxonBase, fauExtraCodes, getExtensionType(PesiTransformer.fauExtraCodesUuid, "FauExtraCodes", "FauExtraCodes", "FEC"));
458
					
459

    
460
					ImportHelper.setOriginalSource(taxonBase, fauEuConfig.getSourceReference(), taxonId, OS_NAMESPACE_TAXON);
461
					ImportHelper.setOriginalSource(zooName, fauEuConfig.getSourceReference(), taxonId, "TaxonName");
462

    
463
					if (!taxonMap.containsKey(taxonId)) {
464
						if (taxonBase == null) {
465
							if (logger.isDebugEnabled()) { 
466
								logger.debug("Taxon base is null. Taxon (" + taxonId + ") ignored.");
467
							}
468
							continue;
469
						}
470
						taxonMap.put(taxonId, taxonBase);
471
						fauEuTaxonMap.put(taxonId, fauEuTaxon);
472
						
473
//						if (logger.isDebugEnabled()) { 
474
//						logger.debug("Stored taxon base (" + taxonId + ") " + localName); 
475
//						}
476
					} else {
477
						logger.warn("Not imported taxon base with duplicated TAX_ID (" + taxonId + 
478
								") " + localName);
479
					}
480
				} catch (Exception e) {
481
					logger.warn("An exception occurred when creating taxon base with id " + taxonId + 
482
					". Taxon base could not be saved.");
483
					e.printStackTrace();
484
				}
485

    
486
				if (((i % limit) == 0 && i != 1 )) { 
487

    
488
					commitTaxa(state, txStatus, taxonMap, fauEuTaxonMap,
489
							synonymSet);
490
					
491
					taxonMap = null;
492
					synonymSet = null;
493
					fauEuTaxonMap = null;
494
					
495
					
496
					if(logger.isInfoEnabled()) {
497
						logger.info("i = " + i + " - Transaction committed"); 
498
					}
499
				}
500

    
501
			}
502
			if (taxonMap != null){
503
				commitTaxa(state, txStatus, taxonMap, fauEuTaxonMap,
504
						synonymSet);
505
				taxonMap = null;
506
				synonymSet = null;
507
				fauEuTaxonMap = null;
508
			}
509
		} catch (SQLException e) {
510
			logger.error("SQLException:" +  e);
511
			state.setUnsuccessfull();
512
		}
513

    
514
		return;
515
	}
516

    
517
	private void commitTaxa(FaunaEuropaeaImportState state,
518
			TransactionStatus txStatus, Map<Integer, TaxonBase<?>> taxonMap,
519
			Map<Integer, FaunaEuropaeaTaxon> fauEuTaxonMap,
520
			Set<Synonym> synonymSet) {
521
		processTaxaSecondPass(state, taxonMap, fauEuTaxonMap, synonymSet);
522
		if(logger.isDebugEnabled()) { logger.debug("Saving taxa ... " + taxonMap.size()); }
523
		getTaxonService().save((Collection)taxonMap.values());
524
		
525
		commitTransaction(txStatus);
526
	}
527

    
528
	
529
	
530
	/**
531
	 * Processes taxa from complete taxon store
532
	 */
533
	private void processTaxaSecondPass(FaunaEuropaeaImportState state, Map<Integer, TaxonBase<?>> taxonMap,
534
			Map<Integer, FaunaEuropaeaTaxon> fauEuTaxonMap, Set<Synonym> synonymSet) {
535
		if(logger.isDebugEnabled()) { logger.debug("Processing taxa second pass..."); }
536

    
537
		FaunaEuropaeaImportConfigurator fauEuConfig = state.getConfig();
538
		
539
		for (int id : taxonMap.keySet())
540
		{
541
			if (logger.isDebugEnabled()) { logger.debug("Taxon # " + id); }
542
			
543
			TaxonBase<?> taxonBase = taxonMap.get(id);
544
			TaxonNameBase<?,?> taxonName = taxonBase.getName();
545
			FaunaEuropaeaTaxon fauEuTaxon = fauEuTaxonMap.get(id);
546
			boolean useOriginalGenus = false;
547
			if (taxonBase instanceof Synonym){
548
				useOriginalGenus = true;
549
			}
550
			
551
			String nameString = 
552
				buildTaxonName(fauEuTaxon, taxonBase, taxonName, useOriginalGenus, fauEuConfig);
553
			
554
			if (taxonBase instanceof Synonym){
555
				logger.debug("Name of Synonym: " + nameString);
556
			}
557
			
558
			if (fauEuConfig.isDoBasionyms() 
559
					&& fauEuTaxon.getRankId() > R_SUBGENUS
560
					&& (fauEuTaxon.getOriginalGenusId() != 0)) {
561
				
562
				Integer originalGenusId = fauEuTaxon.getOriginalGenusId();
563
				Integer actualGenusId = getActualGenusId(fauEuTaxon);
564
				
565
				if (logger.isDebugEnabled()) {
566
					logger.debug("actual genus id = " + actualGenusId + ", original genus id = " + originalGenusId);
567
				}
568
				
569
				if (actualGenusId.intValue() != originalGenusId.intValue() && taxonBase.isInstanceOf(Taxon.class)) {
570
					createBasionym(fauEuTaxon, taxonBase, taxonName, fauEuConfig, synonymSet);
571
				} else if (fauEuTaxon.isParenthesis()) {
572
					//the authorteam should be set in parenthesis because there should be a basionym, but we do not know it?
573
					ZoologicalName zooName = taxonName.deproxy(taxonName, ZoologicalName.class);
574
					zooName.setBasionymAuthorTeam(zooName.getCombinationAuthorTeam());
575
					zooName.setCombinationAuthorTeam(null);
576
					zooName.setOriginalPublicationYear(zooName.getPublicationYear());
577
					zooName.setPublicationYear(null);
578
				}
579
				
580
			}
581
		}
582
		return;	
583
	}
584

    
585
	
586
	private void createBasionym(FaunaEuropaeaTaxon fauEuTaxon, TaxonBase<?> taxonBase, 
587
			TaxonNameBase<?,?>taxonName, FaunaEuropaeaImportConfigurator fauEuConfig,
588
			Set<Synonym> synonymSet) {
589

    
590
		try {
591
			ZoologicalName zooName = taxonName.deproxy(taxonName, ZoologicalName.class);
592
			
593
			// create basionym
594
			ZoologicalName basionym = ZoologicalName.NewInstance(taxonName.getRank());
595
			basionym.setCombinationAuthorTeam(zooName.getCombinationAuthorTeam());
596
			
597
			zooName.setOriginalPublicationYear(zooName.getPublicationYear());
598
			basionym.setPublicationYear(zooName.getPublicationYear());
599

    
600
			// add originalGenusId as source
601
			String originalGenusIdString = "" + fauEuTaxon.getId();
602
			IdentifiableSource basionymSource = IdentifiableSource.NewInstance(originalGenusIdString, "originalGenusId");
603
			basionym.addSource(basionymSource);
604
			
605
			// add original database reference
606
			ImportHelper.setOriginalSource(basionym, fauEuConfig.getSourceReference(), fauEuTaxon.getId(), "TaxonName");
607
			
608
			zooName.addBasionym(basionym, fauEuConfig.getSourceReference(), null, null);
609
			zooName.setBasionymAuthorTeam(zooName.getCombinationAuthorTeam());
610
			zooName.setCombinationAuthorTeam(null);
611
			zooName.setPublicationYear(null);
612
			zooName.setTitleCache(null); // This should (re)generate the titleCache automagically
613
			if (logger.isDebugEnabled()) {
614
				logger.debug("Basionym created (" + fauEuTaxon.getId() + ")");
615
			}
616

    
617
			// create synonym
618
			Synonym synonym = Synonym.NewInstance(basionym, fauEuConfig.getSourceReference());
619
			
620
			if (fauEuTaxon.isValid()) { // Taxon
621

    
622
				// homotypic synonym
623
				Taxon taxon = taxonBase.deproxy(taxonBase, Taxon.class);
624
				taxon.addHomotypicSynonym(synonym, fauEuConfig.getSourceReference(), null);
625
				if (logger.isDebugEnabled()) {
626
					logger.debug("Homotypic synonym created (" + fauEuTaxon.getId() + ")");
627
				}
628

    
629
			} else { // Synonym
630
				
631
				// heterotypic synonym
632
				// synonym relationship to the accepted taxon is created later
633
				synonymSet.add(synonym);
634
				
635
				if (logger.isDebugEnabled()) {
636
					logger.debug("Heterotypic synonym stored (" + fauEuTaxon.getId() + ")");
637
				}
638
			}
639
			
640
			
641
			buildTaxonName(fauEuTaxon, synonym, basionym, true, fauEuConfig);
642
		} catch (Exception e) {
643
			logger.warn("Exception occurred when creating basionym for " + fauEuTaxon.getId());
644
			e.printStackTrace();
645
		}
646
		
647
		
648
		return;
649
	}
650
	
651
	
652
	/* Build name title cache */
653
	private String buildNameTitleCache(String nameString, boolean useOriginalGenus, FaunaEuropaeaTaxon fauEuTaxon) {
654
		
655
		StringBuilder titleCacheStringBuilder = new StringBuilder(nameString);
656
		Integer year = fauEuTaxon.getYear();
657
		if (year != null) { // TODO: Ignore authors like xp, xf, etc?
658
			titleCacheStringBuilder.append(" ");
659
			if ((fauEuTaxon.isParenthesis() == true) && !useOriginalGenus) {
660
				titleCacheStringBuilder.append("(");
661
			}
662
			titleCacheStringBuilder.append(fauEuTaxon.getAuthor());
663
			titleCacheStringBuilder.append(" ");
664
			titleCacheStringBuilder.append(year);
665
			if ((fauEuTaxon.isParenthesis() == true) && !useOriginalGenus) {
666
				titleCacheStringBuilder.append(")");
667
			}
668
		}
669
		return titleCacheStringBuilder.toString();
670
	}
671

    
672

    
673
	/* Build taxon title cache */
674
	private String buildTaxonTitleCache(String nameCache, Reference<?> reference) {
675
		
676
		StringBuilder titleCacheStringBuilder = new StringBuilder(nameCache);
677
		titleCacheStringBuilder.append(" sec. ");
678
		titleCacheStringBuilder.append(reference.getTitleCache());
679
		return titleCacheStringBuilder.toString();
680
	}
681

    
682
	
683
	/* Build name full title cache */
684
	private String buildNameFullTitleCache(String titleCache, FaunaEuropaeaImportConfigurator fauEuConfig) {
685
		
686
		StringBuilder fullTitleCacheStringBuilder = new StringBuilder(titleCache);
687
		fullTitleCacheStringBuilder.append(" ");
688
		fullTitleCacheStringBuilder.append(fauEuConfig.getSourceReferenceTitle());
689
		return fullTitleCacheStringBuilder.toString();
690
	}
691
	
692
	
693
	private String genusPart(StringBuilder originalGenusName, boolean useOriginalGenus, 
694
			StringBuilder genusOrUninomial) {
695

    
696
		StringBuilder stringBuilder = new StringBuilder();
697
		
698
		if(useOriginalGenus) {
699
			stringBuilder.append(originalGenusName);
700
			genusOrUninomial.delete(0, genusOrUninomial.length());
701
			genusOrUninomial.append(originalGenusName);
702
		} else {
703
			stringBuilder.append(genusOrUninomial);
704
		}
705
		stringBuilder.append(" ");
706

    
707
		return stringBuilder.toString();
708
	}
709

    
710
	
711
	private String genusSubGenusPart(StringBuilder originalGenusName, boolean useOriginalGenus, 
712
			StringBuilder genusOrUninomial,
713
			StringBuilder infraGenericEpithet,
714
			FaunaEuropaeaTaxon fauEuTaxon) {
715

    
716
		StringBuilder stringBuilder = new StringBuilder();
717
		
718
		stringBuilder.append(genusPart(originalGenusName, useOriginalGenus, genusOrUninomial));
719

    
720
		// The infraGenericEpithet is set to empty only if the original genus should be used and
721
		// the actualGenusId is not the originalGenusId.
722
		// This differentiation is relevant for synonyms and for basionyms.
723
		// InfraGenericEpithets of accepted taxa are not touched at all.
724
		Integer originalGenusId = fauEuTaxon.getOriginalGenusId();
725
		Integer actualGenusId = getActualGenusId(fauEuTaxon);
726
		if (useOriginalGenus && 
727
				originalGenusId.intValue() != actualGenusId.intValue() && 
728
				originalGenusId.intValue() > 0 &&
729
				actualGenusId.intValue() > 0) {
730
			infraGenericEpithet.delete(0, infraGenericEpithet.length());
731
			stringBuilder.append(" ");
732
			return stringBuilder.toString();
733
		}
734

    
735
		stringBuilder.append("(");
736
		stringBuilder.append(infraGenericEpithet);
737
		stringBuilder.append(")");
738
		stringBuilder.append(" ");
739
		
740
		return stringBuilder.toString();
741
	}
742

    
743
	/** Get actual genus id **/
744
	private Integer getActualGenusId(FaunaEuropaeaTaxon fauEuTaxon) {
745
		Integer actualGenusId = null;
746
		HashMap<Integer, Integer> ranks = new HashMap<Integer, Integer>();
747
		ranks.put(fauEuTaxon.getParentRankId(), fauEuTaxon.getParentId());
748
		ranks.put(fauEuTaxon.getGrandParentRankId(), fauEuTaxon.getGrandParentId());
749
		ranks.put(fauEuTaxon.getGreatGrandParentRankId(), fauEuTaxon.getGreatGrandParentId());
750
		ranks.put(fauEuTaxon.getGreatGreatGrandParentRankId(), fauEuTaxon.getGreatGreatGrandParentId());
751
		ranks.put(fauEuTaxon.getGreatGreatGreatGrandParentRankId(), fauEuTaxon.getGreatGreatGreatGrandParentId());
752
		
753
		actualGenusId = ranks.get(R_GENUS);
754

    
755
		return actualGenusId;
756
	}
757
	
758
	
759
	/** Build species and subspecies names */
760
	private String buildLowerTaxonName(StringBuilder originalGenus, boolean useOriginalGenus, 
761
			StringBuilder genusOrUninomial, StringBuilder infraGenericEpithet, 
762
			StringBuilder specificEpithet, StringBuilder infraSpecificEpithet,
763
			FaunaEuropaeaTaxon fauEuTaxon) {
764
		
765
		// species or subspecies name
766
		String localName = fauEuTaxon.getLocalName();
767
		int taxonId = fauEuTaxon.getId();
768
		int parentId = fauEuTaxon.getParentId();
769
		StringBuilder nameCacheStringBuilder = new StringBuilder();
770

    
771
//		FaunaEuropaeaTaxon parent = fauEuTaxonMap.get(parentId);
772
		if (parentId == 0) {
773
			nameCacheStringBuilder.append(localName);
774
			if (logger.isInfoEnabled()) {
775
				logger.info("Parent of (" + taxonId + ") is null");
776
			}
777
			return nameCacheStringBuilder.toString();
778
		}
779
		
780
		String parentName = fauEuTaxon.getParentName();
781
		String grandParentName = fauEuTaxon.getGrandParentName();
782
		String greatGrandParentName = fauEuTaxon.getGreatGrandParentName();
783
		int rank = fauEuTaxon.getRankId();
784
		int parentRankId = fauEuTaxon.getParentRankId();
785
		int grandParentRankId = fauEuTaxon.getGrandParentRankId();
786
		int greatGrandParentRankId = fauEuTaxon.getGreatGrandParentRankId();
787
//		int grandParentId = fauEuTaxon.getGrandParentId();
788
//		int greatGrandParentId = grandParent.getParentId();
789

    
790
		
791
		if (fauEuTaxon.isValid()) { // Taxon
792
			
793
			if (rank == R_SPECIES) {
794

    
795
				if(parentRankId == R_SUBGENUS) {
796
					//differ between isParanthesis= true and false
797
					String genusSubGenusPart = genusSubGenusPart(originalGenus, useOriginalGenus, 
798
							genusOrUninomial.append(grandParentName), 
799
							infraGenericEpithet.append(parentName),
800
							fauEuTaxon);
801
						nameCacheStringBuilder.append(genusSubGenusPart);
802
					
803

    
804
				} else if(parentRankId == R_GENUS) {
805

    
806
					String genusPart = genusPart(originalGenus, useOriginalGenus, 
807
							genusOrUninomial.append(parentName));
808
					nameCacheStringBuilder.append(genusPart);
809
				}
810
				nameCacheStringBuilder.append(localName);
811
				specificEpithet.append(localName);
812

    
813
			} else if (rank == R_SUBSPECIES) {
814

    
815
				if(grandParentRankId == R_SUBGENUS) {
816

    
817
					String genusSubGenusPart = genusSubGenusPart(originalGenus, useOriginalGenus, 
818
							genusOrUninomial.append(greatGrandParentName), 
819
							infraGenericEpithet.append(grandParentName),
820
							fauEuTaxon);
821
					nameCacheStringBuilder.append(genusSubGenusPart);
822

    
823
				} else if (grandParentRankId == R_GENUS) {
824

    
825
					String genusPart = genusPart(originalGenus, useOriginalGenus, 
826
							genusOrUninomial.append(grandParentName));
827
					nameCacheStringBuilder.append(genusPart);
828

    
829
				}
830
				nameCacheStringBuilder.append(parentName);
831
				nameCacheStringBuilder.append(" ");
832
				nameCacheStringBuilder.append(localName);
833
				specificEpithet.append(parentName);
834
				infraSpecificEpithet.append(localName);
835
			}
836
		} else { // Synonym
837
			
838
			if (rank == R_SPECIES) {
839

    
840
				if(grandParentRankId == R_SUBGENUS) {
841
					
842
					String genusSubGenusPart = genusSubGenusPart(originalGenus, useOriginalGenus, 
843
							genusOrUninomial.append(greatGrandParentName), 
844
							infraGenericEpithet.append(grandParentName),
845
							fauEuTaxon);
846
					nameCacheStringBuilder.append(genusSubGenusPart);
847

    
848
				} else if (grandParentRankId == R_GENUS) {
849
					
850
					String genusPart = genusPart(originalGenus, useOriginalGenus, 
851
							genusOrUninomial.append(grandParentName));
852
					nameCacheStringBuilder.append(genusPart);
853

    
854
				}
855
				nameCacheStringBuilder.append(localName);
856
				specificEpithet.append(localName);
857

    
858
			} else if (rank == R_SUBSPECIES) {
859
				
860
				String greatGreatGrandParentName = fauEuTaxon.getGreatGreatGrandParentName();
861
				
862
				if(greatGrandParentRankId == R_SUBGENUS) {
863
					
864
					String genusSubGenusPart = genusSubGenusPart(originalGenus, useOriginalGenus, 
865
							genusOrUninomial.append(greatGreatGrandParentName), 
866
							infraGenericEpithet.append(greatGrandParentName),
867
							fauEuTaxon);
868
					nameCacheStringBuilder.append(genusSubGenusPart);
869
					
870
				} else if (greatGrandParentRankId == R_GENUS) {
871
					
872
					String genusPart = genusPart(originalGenus, useOriginalGenus, 
873
							genusOrUninomial.append(greatGreatGrandParentName));
874
					nameCacheStringBuilder.append(genusPart);
875
				}
876
				
877
				nameCacheStringBuilder.append(grandParentName);
878
				nameCacheStringBuilder.append(" ");
879
				specificEpithet.append(grandParentName);
880
				nameCacheStringBuilder.append(localName);
881
				infraSpecificEpithet.append(localName);
882
			}
883
			
884
			
885
			
886
		}
887
		
888
		return nameCacheStringBuilder.toString();
889
	}
890
	
891
	
892
	/** Build taxon's name parts and caches */
893
	private String buildTaxonName(FaunaEuropaeaTaxon fauEuTaxon, TaxonBase<?> taxonBase, TaxonNameBase<?,?>taxonName,
894
			boolean useOriginalGenus, FaunaEuropaeaImportConfigurator fauEuConfig) {
895

    
896
		/* Local taxon name string */
897
		String localString = "";
898
		/* Concatenated taxon name string */
899
		String completeString = "";
900

    
901
		StringBuilder originalGenus = new StringBuilder("");
902
		
903
		StringBuilder genusOrUninomial = new StringBuilder();
904
		StringBuilder infraGenericEpithet = new StringBuilder(); 
905
		StringBuilder specificEpithet = new StringBuilder();
906
		StringBuilder infraSpecificEpithet = new StringBuilder();
907

    
908
		localString = fauEuTaxon.getLocalName();
909
		int rank = fauEuTaxon.getRankId();
910
		
911
		// determine genus: this also works for cases of synonyms since the accepted taxon is its parent
912
		String originalGenusString = null;
913
		if (useOriginalGenus && ! "".equals(fauEuTaxon.getOriginalGenusName())) {
914
			originalGenusString  = fauEuTaxon.getOriginalGenusName();
915
		} else {
916
			originalGenusString = determineOriginalGenus(fauEuTaxon);
917
		}
918

    
919
		if (originalGenusString != null) {
920
			originalGenus = new StringBuilder(originalGenusString);
921
		}
922

    
923
		if(logger.isDebugEnabled()) { 
924
			logger.debug("Local taxon name (rank = " + rank + "): " + localString); 
925
		}
926

    
927
		if (rank < R_SPECIES) {
928
			// subgenus or above
929

    
930
			completeString = localString;
931
			if (rank == R_SUBGENUS) {
932
				// subgenus part
933
				infraGenericEpithet.append(localString);
934
				
935
				// genus part
936
				genusOrUninomial.append(originalGenus);
937
				
938
				completeString = originalGenus + " ("+ localString + ")";
939
			} else {
940
				// genus or above
941
				genusOrUninomial.append(localString);
942
			}
943
			
944
		} else {
945
			// species or below
946

    
947
			taxonBase = taxonBase.deproxy(taxonBase, TaxonBase.class);
948

    
949
			completeString = 
950
				buildLowerTaxonName(originalGenus, useOriginalGenus, 
951
						genusOrUninomial, infraGenericEpithet, specificEpithet, infraSpecificEpithet,
952
						fauEuTaxon);
953
			
954
			completeString = (String) CdmUtils.removeDuplicateWhitespace(completeString.trim());
955

    
956
		}
957
		return setCompleteTaxonName(completeString, useOriginalGenus,
958
				genusOrUninomial.toString(), infraGenericEpithet.toString(), 
959
				specificEpithet.toString(), infraSpecificEpithet.toString(),
960
				fauEuTaxon, taxonBase, fauEuConfig);
961
		 
962
	}
963
	
964
	
965
	/**
966
	 * Determines the original genus name by searching the taxon with rank Genus.
967
	 * @param fauEuTaxon
968
	 * @return
969
	 */
970
	private String determineOriginalGenus(FaunaEuropaeaTaxon fauEuTaxon) {
971
		String originalGenus = null;
972

    
973
		HashMap<Integer, String> ranks = new HashMap<Integer, String>();
974
		ranks.put(fauEuTaxon.getParentRankId(), fauEuTaxon.getParentName());
975
		ranks.put(fauEuTaxon.getGrandParentRankId(), fauEuTaxon.getGrandParentName());
976
		ranks.put(fauEuTaxon.getGreatGrandParentRankId(), fauEuTaxon.getGreatGrandParentName());
977
		ranks.put(fauEuTaxon.getGreatGreatGrandParentRankId(), fauEuTaxon.getGreatGreatGrandParentName());
978
		ranks.put(fauEuTaxon.getGreatGreatGreatGrandParentRankId(), fauEuTaxon.getGreatGreatGreatGrandParentName());
979
		
980
		originalGenus = ranks.get(R_GENUS);
981

    
982
		return originalGenus;
983
	}
984

    
985
	/** Sets name parts and caches */
986
	private String setCompleteTaxonName(String concatString, boolean useOriginalGenus,
987
			String genusOrUninomial, String infraGenericEpithet, String specificEpithet, String infraSpecificEpithet, 
988
			FaunaEuropaeaTaxon fauEuTaxon, TaxonBase<?> taxonBase, FaunaEuropaeaImportConfigurator fauEuConfig) {
989

    
990
		boolean success = true;
991
		
992
		TaxonNameBase<?,?> taxonName = taxonBase.getName();
993
		ZoologicalName zooName = (ZoologicalName)taxonName;
994
		
995
		if (!genusOrUninomial.equals("")) {
996
			zooName.setGenusOrUninomial(emptyToNull(genusOrUninomial));
997
			if (logger.isDebugEnabled()) { 
998
				logger.debug("genusOrUninomial: " + genusOrUninomial); 
999
			}
1000
		}
1001
		
1002
		//if ((!infraGenericEpithet.equals("") && fauEuTaxon.isParenthesis()) || (!infraGenericEpithet.equals("") && fauEuTaxon.)) {
1003
		if (fauEuTaxon.getParentRankId() == R_SUBGENUS || fauEuTaxon.getRankId() == R_SUBGENUS ||
1004
				fauEuTaxon.getGrandParentRankId() == R_SUBGENUS || fauEuTaxon.getGreatGrandParentRankId() == R_SUBGENUS) {
1005
			zooName.setInfraGenericEpithet(emptyToNull(infraGenericEpithet));
1006
			if (logger.isDebugEnabled()) { 
1007
				logger.debug("infraGenericEpithet: " + infraGenericEpithet); 
1008
			}
1009
		}
1010
		if ((fauEuTaxon.getRankId() == R_SPECIES || fauEuTaxon.getRankId() == R_SUBSPECIES)) {
1011
			zooName.setSpecificEpithet(emptyToNull(specificEpithet));
1012
			if (logger.isDebugEnabled()) { 
1013
				logger.debug("specificEpithet: " + specificEpithet); 
1014
			}
1015
		}
1016
		if (fauEuTaxon.getRankId() == R_SUBSPECIES) {
1017
			zooName.setInfraSpecificEpithet(emptyToNull(infraSpecificEpithet));
1018
			if (logger.isDebugEnabled()) { 
1019
				logger.debug("infraSpecificEpithet: " + infraSpecificEpithet); 
1020
			}
1021
		}
1022
		//TODO: use generate NameCache
1023
		//zooName.setNameCache(concatString);
1024
		String result = zooName.getNameCache();
1025
//		zooName.generateTitle();
1026
		//String titleCache = buildNameTitleCache(concatString, useOriginalGenus, fauEuTaxon);
1027
		//zooName.setTitleCache(titleCache);
1028
		//titleCache = buildNameFullTitleCache(concatString, fauEuConfig);
1029
//		zooName.generateFullTitle();
1030
		//zooName.setFullTitleCache(titleCache); // TODO: Add reference, NC status
1031
		
1032
//		ImportHelper.setOriginalSource(taxonName, fauEuConfig.getSourceReference(), 
1033
//				fauEuTaxon.getId(), "TaxonName");
1034
//		taxonBase.setSec(fauEuConfig.getSourceReference());
1035
//		taxonBase.generateTitle();
1036
		//titleCache = buildTaxonTitleCache(concatString, fauEuConfig.getSourceReference());
1037
		//taxonBase.setTitleCache(titleCache);
1038
		
1039
		if (logger.isDebugEnabled()) { 
1040
			logger.debug("Name stored: " + result); 
1041
		}
1042
		return result;
1043
	}
1044

    
1045
	/**
1046
	 * Ensures that empty strings are translated to null.
1047
	 * @param genusOrUninomial
1048
	 * @return
1049
	 */
1050
	private String emptyToNull(String text) {
1051
		if (CdmUtils.isEmpty(text)) {
1052
			return null;
1053
		} else {
1054
			return text;
1055
		}
1056
	}
1057

    
1058
}
(15-15/17)