Project

General

Profile

Download (31.6 KB) Statistics
| Branch: | Tag: | 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.faunaEuropaea;
11

    
12
import static eu.etaxonomy.cdm.io.faunaEuropaea.FaunaEuropaeaTransformer.A_AUCT;
13
import static eu.etaxonomy.cdm.io.faunaEuropaea.FaunaEuropaeaTransformer.P_PARENTHESIS;
14
import static eu.etaxonomy.cdm.io.faunaEuropaea.FaunaEuropaeaTransformer.R_GENUS;
15
import static eu.etaxonomy.cdm.io.faunaEuropaea.FaunaEuropaeaTransformer.R_SPECIES;
16
import static eu.etaxonomy.cdm.io.faunaEuropaea.FaunaEuropaeaTransformer.R_SUBGENUS;
17
import static eu.etaxonomy.cdm.io.faunaEuropaea.FaunaEuropaeaTransformer.R_SUBSPECIES;
18
import static eu.etaxonomy.cdm.io.faunaEuropaea.FaunaEuropaeaTransformer.T_STATUS_ACCEPTED;
19
import static eu.etaxonomy.cdm.io.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

    
30
import org.apache.log4j.Logger;
31
import org.apache.poi.hssf.record.formula.functions.Isblank;
32
import org.springframework.stereotype.Component;
33
import org.springframework.transaction.TransactionStatus;
34

    
35
import eu.etaxonomy.cdm.common.CdmUtils;
36
import eu.etaxonomy.cdm.io.common.ICdmIO;
37
import eu.etaxonomy.cdm.io.common.ImportHelper;
38
import eu.etaxonomy.cdm.io.common.MapWrapper;
39
import eu.etaxonomy.cdm.io.common.Source;
40
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
41
import eu.etaxonomy.cdm.model.common.CdmBase;
42
import eu.etaxonomy.cdm.model.common.IdentifiableSource;
43
import eu.etaxonomy.cdm.model.name.Rank;
44
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
45
import eu.etaxonomy.cdm.model.name.ZoologicalName;
46
import eu.etaxonomy.cdm.model.reference.ReferenceBase;
47
import eu.etaxonomy.cdm.model.taxon.Synonym;
48
import eu.etaxonomy.cdm.model.taxon.Taxon;
49
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
50
import eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException;
51

    
52

    
53
/**
54
 * @author a.babadshanjan
55
 * @created 12.05.2009
56
 * @version 1.0
57
 */
58
@Component
59
public class FaunaEuropaeaTaxonNameImport extends FaunaEuropaeaImportBase  {
60
	
61
	public static final String OS_NAMESPACE_TAXON = "Taxon";
62
	private static final Logger logger = Logger.getLogger(FaunaEuropaeaTaxonNameImport.class);
63

    
64
	/* Max number of taxa to retrieve (for test purposes) */
65
	private int maxTaxa = 0;
66
	
67

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

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

    
117
	
118
	/** Retrieve taxa from FauEu DB, process in blocks */
119
	private boolean processTaxa(FaunaEuropaeaImportState state) {
120

    
121
		int limit = state.getConfig().getLimitSave();
122

    
123
		TransactionStatus txStatus = null;
124

    
125
		Map<String, MapWrapper<? extends CdmBase>> stores = state.getStores();
126
		MapWrapper<TeamOrPersonBase> authorStore = (MapWrapper<TeamOrPersonBase>)stores.get(ICdmIO.TEAM_STORE);
127
		
128
		Map<Integer, TaxonBase<?>> taxonMap = null;
129
		Map<Integer, FaunaEuropaeaTaxon> fauEuTaxonMap = null;
130
		/* Store for heterotypic synonyms to be save separately */
131
		Set<Synonym> synonymSet = null;
132

    
133
		FaunaEuropaeaImportConfigurator fauEuConfig = state.getConfig();
134
		ReferenceBase<?> sourceRef = fauEuConfig.getSourceReference();
135

    
136
		Source source = fauEuConfig.getSource();
137
		int i = 0;
138
		boolean success = true;
139

    
140
		String selectCount = 
141
			" SELECT count(*) ";
142

    
143
		String selectColumns = 
144
			" SELECT Parent.TAX_NAME AS P2Name, Parent.TAX_RNK_ID AS P2RankId, " +
145
			" GrandParent.TAX_ID AS GP3Id, GrandParent.TAX_NAME AS GP3Name, GrandParent.TAX_RNK_ID AS GP3RankId, " +
146
			" GreatGrandParent.TAX_ID AS GGP4Id, GreatGrandParent.TAX_NAME AS GGP4Name, GreatGrandParent.TAX_RNK_ID AS GGP4RankId, " +
147
			" GreatGreatGrandParent.TAX_ID AS GGGP5Id, GreatGreatGrandParent.TAX_NAME AS GGGP5Name, OriginalGenusTaxon.TAX_NAME AS OGenusName, " +
148
			" Taxon.*, rank.*, author.* ";
149
		
150
		String fromClause = 
151
			" FROM Taxon LEFT OUTER JOIN " +
152
			" Taxon AS Parent ON Taxon.TAX_TAX_IDPARENT = Parent.TAX_ID LEFT OUTER JOIN " +
153
			" Taxon AS GrandParent ON Parent.TAX_TAX_IDPARENT = GrandParent.TAX_ID LEFT OUTER JOIN " +
154
			" Taxon AS GreatGrandParent ON GrandParent.TAX_TAX_IDPARENT = GreatGrandParent.TAX_ID LEFT OUTER JOIN " +
155
			" Taxon AS GreatGreatGrandParent ON GreatGrandParent.TAX_TAX_IDPARENT = GreatGreatGrandParent.TAX_ID LEFT OUTER JOIN " +
156
			" Taxon AS OriginalGenusTaxon ON Taxon.TAX_TAX_IDGENUS = OriginalGenusTaxon.TAX_ID LEFT OUTER JOIN " +
157
			" author ON Taxon.TAX_AUT_ID = author.aut_id LEFT OUTER JOIN " +
158
			" rank ON Taxon.TAX_RNK_ID = rank.rnk_id ";
159

    
160
		String countQuery = 
161
			selectCount + fromClause;
162

    
163
		String selectQuery = 
164
			selectColumns + fromClause;
165
		
166

    
167
        try {
168

    
169
			ResultSet rs = source.getResultSet(countQuery);
170
			rs.next();
171
			int count = rs.getInt(1);
172
			
173
			rs = source.getResultSet(selectQuery);
174

    
175
	        if (logger.isInfoEnabled()) {
176
				logger.info("Number of rows: " + count);
177
				logger.info("Count Query: " + countQuery);
178
				logger.info("Select Query: " + selectQuery);
179
			}
180
	        
181
			while (rs.next()) {
182

    
183
				if ((i++ % limit) == 0) {
184
					
185
					txStatus = startTransaction();
186
					taxonMap = new HashMap<Integer, TaxonBase<?>>(limit);
187
					fauEuTaxonMap = new HashMap<Integer, FaunaEuropaeaTaxon>(limit);
188
					synonymSet = new HashSet<Synonym>();
189
					
190
					if(logger.isInfoEnabled()) {
191
						logger.info("i = " + i + " - Transaction started"); 
192
					}
193
				}
194

    
195
				String localName = rs.getString("TAX_NAME");
196
				String parentName = rs.getString("P2Name");
197
				int grandParentId = rs.getInt("GP3Id");
198
				String grandParentName = rs.getString("GP3Name");
199
				int greatGrandParentId = rs.getInt("GGP4Id");
200
				String greatGrandParentName = rs.getString("GGP4Name");
201
				int greatGreatGrandParentId = rs.getInt("GGGP5Id");
202
				String greatGreatGrandParentName = rs.getString("GGGP5Name");
203
				String originalGenusName = rs.getString("OGenusName");
204
				String autName = rs.getString("aut_name");
205
				int taxonId = rs.getInt("TAX_ID");
206
				int rankId = rs.getInt("TAX_RNK_ID");
207
				int parentId = rs.getInt("TAX_TAX_IDPARENT");
208
				int parentRankId = rs.getInt("P2RankId");
209
				int grandParentRankId = rs.getInt("GP3RankId");
210
				int greatGrandParentRankId = rs.getInt("GGP4RankId");
211
				int originalGenusId = rs.getInt("TAX_TAX_IDGENUS");
212
				int autId = rs.getInt("TAX_AUT_ID");
213
				int status = rs.getInt("TAX_VALID");
214
				
215
				// Avoid publication year 0 for NULL values in database.
216
				Integer year = rs.getInt("TAX_YEAR");
217
				if (year != null && year.intValue() == 0) {
218
					year = null;
219
				}
220
				
221
				//int familyId = rs.getInt("TAX_TAX_IDFAMILY");
222

    
223
				Rank rank = null;
224
				int parenthesis = rs.getInt("TAX_PARENTHESIS");
225
				UUID taxonBaseUuid = null;
226
				if (resultSetHasColumn(rs,"UUID")){
227
					taxonBaseUuid = UUID.fromString(rs.getString("UUID"));
228
				} else {
229
					taxonBaseUuid = UUID.randomUUID();
230
				}
231

    
232
				FaunaEuropaeaTaxon fauEuTaxon = new FaunaEuropaeaTaxon();
233
				fauEuTaxon.setUuid(taxonBaseUuid);
234
				fauEuTaxon.setId(taxonId);
235
				fauEuTaxon.setRankId(rankId);
236
				fauEuTaxon.setLocalName(localName);
237
				
238
				fauEuTaxon.setParentId(parentId);
239
				fauEuTaxon.setParentRankId(parentRankId);
240
				fauEuTaxon.setParentName(parentName);
241
				
242
				fauEuTaxon.setGrandParentId(grandParentId);
243
				fauEuTaxon.setGrandParentRankId(grandParentRankId);
244
				fauEuTaxon.setGrandParentName(grandParentName);
245
				
246
				fauEuTaxon.setGreatGrandParentId(greatGrandParentId);
247
				fauEuTaxon.setGreatGrandParentName(greatGrandParentName);
248
				
249
				fauEuTaxon.setGreatGreatGrandParentId(greatGreatGrandParentId);
250
				fauEuTaxon.setGreatGrandParentRankId(greatGrandParentRankId);
251
				fauEuTaxon.setGreatGreatGrandParentName(greatGreatGrandParentName);
252
				
253
				fauEuTaxon.setOriginalGenusId(originalGenusId);
254
				fauEuTaxon.setYear(year);
255
				fauEuTaxon.setOriginalGenusName(originalGenusName);
256
				fauEuTaxon.setAuthorName(autName);
257
				if (parenthesis == P_PARENTHESIS) {
258
					fauEuTaxon.setParenthesis(true);
259
				} else {
260
					fauEuTaxon.setParenthesis(false);
261
				}
262
				if (status == T_STATUS_ACCEPTED) {
263
					fauEuTaxon.setValid(true);
264
				} else {
265
					fauEuTaxon.setValid(false);
266
				}
267

    
268
//				fauEuTaxon.setAuthorId(autId);
269

    
270
				try {
271
					rank = FaunaEuropaeaTransformer.rankId2Rank(rs, false);
272
				} catch (UnknownCdmTypeException e) {
273
					logger.warn("Taxon (" + taxonId + ") has unknown rank (" + rankId + ") and could not be saved.");
274
					continue;
275
				} catch (NullPointerException e) {
276
					logger.warn("Taxon (" + taxonId + ") has rank null and can not be saved.");
277
					continue;
278
				}
279

    
280
				ReferenceBase<?> sourceReference = fauEuConfig.getSourceReference();
281
				ReferenceBase<?> auctReference = fauEuConfig.getAuctReference();
282

    
283
				ZoologicalName zooName = ZoologicalName.NewInstance(rank);
284
				TeamOrPersonBase<?> author = authorStore.get(autId);
285
				
286
				zooName.setCombinationAuthorTeam(author);
287
				zooName.setPublicationYear(year);
288
				
289
				TaxonBase<?> taxonBase;
290

    
291
				Synonym synonym;
292
				Taxon taxon;
293
				try {
294
					if ((status == T_STATUS_ACCEPTED) || (autId == A_AUCT)) { // taxon
295
						if (autId == A_AUCT) { // misapplied name
296
							zooName.setCombinationAuthorTeam(null);
297
							zooName.setPublicationYear(null);
298
							taxon = Taxon.NewInstance(zooName, auctReference);
299
							if (logger.isDebugEnabled()) {
300
								logger.debug("Misapplied name created (" + taxonId + ")");
301
							}
302
						} else { // accepted taxon
303
							taxon = Taxon.NewInstance(zooName, sourceReference);
304
							if (logger.isDebugEnabled()) {
305
								logger.debug("Taxon created (" + taxonId + ")");
306
							}
307
						}
308
						taxonBase = taxon;
309
					} else if ((status == T_STATUS_NOT_ACCEPTED) && (autId != A_AUCT)) { // synonym
310
						synonym = Synonym.NewInstance(zooName, sourceReference);
311
						//logger.info("Synonym created: " + synonym.getTitleCache() + " taxonName: " + zooName.getTitleCache());
312
						if (logger.isDebugEnabled()) {
313
							logger.debug("Synonym created (" + taxonId + ")");
314
						}
315
						taxonBase = synonym;
316
					} else {
317
						logger.warn("Unknown taxon status " + status + ". Taxon (" + taxonId + ") ignored.");
318
						continue;
319
					}
320

    
321
					taxonBase.setUuid(taxonBaseUuid);
322

    
323
					ImportHelper.setOriginalSource(taxonBase, fauEuConfig.getSourceReference(), taxonId, OS_NAMESPACE_TAXON);
324
					ImportHelper.setOriginalSource(zooName, fauEuConfig.getSourceReference(), taxonId, "TaxonName");
325

    
326

    
327
					if (!taxonMap.containsKey(taxonId)) {
328
						if (taxonBase == null) {
329
							if (logger.isDebugEnabled()) { 
330
								logger.debug("Taxon base is null. Taxon (" + taxonId + ") ignored.");
331
							}
332
							continue;
333
						}
334
						taxonMap.put(taxonId, taxonBase);
335
						fauEuTaxonMap.put(taxonId, fauEuTaxon);
336
						
337
//						if (logger.isDebugEnabled()) { 
338
//						logger.debug("Stored taxon base (" + taxonId + ") " + localName); 
339
//						}
340
					} else {
341
						logger.warn("Not imported taxon base with duplicated TAX_ID (" + taxonId + 
342
								") " + localName);
343
					}
344
				} catch (Exception e) {
345
					logger.warn("An exception occurred when creating taxon base with id " + taxonId + 
346
					". Taxon base could not be saved.");
347
					e.printStackTrace();
348
				}
349

    
350
				if (((i % limit) == 0 && i != 1 ) || i == count) { 
351

    
352
					success = processTaxaSecondPass(state, taxonMap, fauEuTaxonMap, synonymSet);
353
					if(logger.isDebugEnabled()) { logger.debug("Saving taxa ..."); }
354
					getTaxonService().save((Collection)taxonMap.values());
355
					getTaxonService().save((Collection)synonymSet);
356
					
357
					taxonMap = null;
358
					synonymSet = null;
359
					fauEuTaxonMap = null;
360
					commitTransaction(txStatus);
361
					
362
					if(logger.isInfoEnabled()) {
363
						logger.info("i = " + i + " - Transaction committed"); 
364
					}
365
				}
366

    
367
			}
368
		} catch (SQLException e) {
369
			logger.error("SQLException:" +  e);
370
			success = false;
371
		}
372

    
373
		return success;
374
	}
375
	
376
	
377
	/**
378
	 * Processes taxa from complete taxon store
379
	 */
380
	private boolean processTaxaSecondPass(FaunaEuropaeaImportState state, Map<Integer, TaxonBase<?>> taxonMap,
381
			Map<Integer, FaunaEuropaeaTaxon> fauEuTaxonMap, Set<Synonym> synonymSet) {
382

    
383
		if(logger.isDebugEnabled()) { logger.debug("Processing taxa second pass..."); }
384

    
385
		FaunaEuropaeaImportConfigurator fauEuConfig = state.getConfig();
386
		
387
		boolean success = true;
388

    
389
		for (int id : taxonMap.keySet())
390
		{
391
			if (logger.isDebugEnabled()) { logger.debug("Taxon # " + id); }
392
			
393
			TaxonBase<?> taxonBase = taxonMap.get(id);
394
			TaxonNameBase<?,?> taxonName = taxonBase.getName();
395
			FaunaEuropaeaTaxon fauEuTaxon = fauEuTaxonMap.get(id);
396
			boolean useOriginalGenus = false;
397
			if (taxonBase instanceof Synonym){
398
				useOriginalGenus = true;
399
			}
400
			String nameString = 
401
				buildTaxonName(fauEuTaxon, taxonBase, taxonName, useOriginalGenus, fauEuConfig);
402
			
403
			if (taxonBase instanceof Synonym){
404
				logger.info("Name of Synonym: " + nameString);
405
			}
406
			
407
			
408
			if (fauEuConfig.isDoBasionyms() 
409
					&& fauEuTaxon.getRankId() > R_SUBGENUS
410
					&& (fauEuTaxon.getOriginalGenusId() != 0)) {
411
				
412
				int originalGenusId = fauEuTaxon.getOriginalGenusId();
413
				int actualGenusId = getActualGenusId(fauEuTaxon);
414
				
415
				if (logger.isDebugEnabled()) {
416
					logger.debug("actual genus id = " + actualGenusId + ", original genus id = " + originalGenusId);
417
				}
418
				
419
				if (actualGenusId != originalGenusId && taxonBase.isInstanceOf(Taxon.class)) { 
420
					success = createBasionym(fauEuTaxon, taxonBase, taxonName, fauEuConfig, synonymSet);
421
				} else if (fauEuTaxon.isParenthesis()){
422
					//the authorteam should be set in parenthesis because there should be a basionym, but we do not know it?
423
					ZoologicalName zooName = taxonName.deproxy(taxonName, ZoologicalName.class);
424
					zooName.setBasionymAuthorTeam(zooName.getCombinationAuthorTeam());
425
					zooName.setCombinationAuthorTeam(null);
426
					zooName.setOriginalPublicationYear(zooName.getPublicationYear());
427
					zooName.setPublicationYear(null);
428
				}
429
				
430
			}
431
		}
432
		return success;	
433
	}
434

    
435
	
436
	private boolean createBasionym(FaunaEuropaeaTaxon fauEuTaxon, TaxonBase<?> taxonBase, 
437
			TaxonNameBase<?,?>taxonName, FaunaEuropaeaImportConfigurator fauEuConfig, Set<Synonym> synonymSet) {
438

    
439
		boolean success = true;
440

    
441
		try {
442
			ZoologicalName zooName = taxonName.deproxy(taxonName, ZoologicalName.class);
443
			
444
			// create basionym
445
			ZoologicalName basionym = ZoologicalName.NewInstance(taxonName.getRank());
446
			basionym.setCombinationAuthorTeam(zooName.getCombinationAuthorTeam());
447
			
448
			zooName.setOriginalPublicationYear(zooName.getPublicationYear());
449
			basionym.setPublicationYear(zooName.getPublicationYear());
450

    
451
			// add originalGenusId as source
452
			String originalGenusIdString = "" + fauEuTaxon.getOriginalGenusId();
453
			IdentifiableSource basionymSource = IdentifiableSource.NewInstance(originalGenusIdString, "originalGenusId");
454
			basionym.addSource(basionymSource);
455
			
456
			zooName.addBasionym(basionym, fauEuConfig.getSourceReference(), null, null);
457
			zooName.setBasionymAuthorTeam(zooName.getCombinationAuthorTeam());
458
			zooName.setCombinationAuthorTeam(null);
459
			zooName.setPublicationYear(null);
460
			zooName.setTitleCache(null); // This should (re)generate the titleCache automagically
461
			if (logger.isDebugEnabled()) {
462
				logger.debug("Basionym created (" + fauEuTaxon.getId() + ")");
463
			}
464

    
465
			// create synonym
466
			Synonym synonym = Synonym.NewInstance(basionym, fauEuConfig.getSourceReference());
467
			
468
			if (fauEuTaxon.isValid()) { // Taxon
469

    
470
				// homotypic synonym
471
				Taxon taxon = taxonBase.deproxy(taxonBase, Taxon.class);
472
				taxon.addHomotypicSynonym(synonym, fauEuConfig.getSourceReference(), null);
473
				if (logger.isDebugEnabled()) {
474
					logger.debug("Homotypic synonym created (" + fauEuTaxon.getId() + ")");
475
				}
476

    
477
			} else { // Synonym
478
				
479
				// heterotypic synonym
480
				// synonym relationship to the accepted taxon is created later
481
				synonymSet.add(synonym);
482
				
483
				if (logger.isDebugEnabled()) {
484
					logger.debug("Heterotypic synonym stored (" + fauEuTaxon.getId() + ")");
485
				}
486
			}
487
			
488
			buildTaxonName(fauEuTaxon, synonym, basionym, true, fauEuConfig);
489
			
490
		} catch (Exception e) {
491
			logger.warn("Exception occurred when creating basionym for " + fauEuTaxon.getId());
492
			e.printStackTrace();
493
		}
494
		
495
		
496
		return success;
497
	}
498
	
499
	
500
	/* Build name title cache */
501
	private String buildNameTitleCache(String nameString, boolean useOriginalGenus, FaunaEuropaeaTaxon fauEuTaxon) {
502
		
503
		StringBuilder titleCacheStringBuilder = new StringBuilder(nameString);
504
		Integer year = fauEuTaxon.getYear();
505
		if (year != null) { // TODO: Ignore authors like xp, xf, etc?
506
			titleCacheStringBuilder.append(" ");
507
			if ((fauEuTaxon.isParenthesis() == true) && !useOriginalGenus) {
508
				titleCacheStringBuilder.append("(");
509
			}
510
			titleCacheStringBuilder.append(fauEuTaxon.getAuthor());
511
			titleCacheStringBuilder.append(" ");
512
			titleCacheStringBuilder.append(year);
513
			if ((fauEuTaxon.isParenthesis() == true) && !useOriginalGenus) {
514
				titleCacheStringBuilder.append(")");
515
			}
516
		}
517
		return titleCacheStringBuilder.toString();
518
	}
519

    
520

    
521
	/* Build taxon title cache */
522
	private String buildTaxonTitleCache(String nameCache, ReferenceBase<?> reference) {
523
		
524
		StringBuilder titleCacheStringBuilder = new StringBuilder(nameCache);
525
		titleCacheStringBuilder.append(" sec. ");
526
		titleCacheStringBuilder.append(reference.getTitleCache());
527
		return titleCacheStringBuilder.toString();
528
	}
529

    
530
	
531
	/* Build name full title cache */
532
	private String buildNameFullTitleCache(String titleCache, FaunaEuropaeaImportConfigurator fauEuConfig) {
533
		
534
		StringBuilder fullTitleCacheStringBuilder = new StringBuilder(titleCache);
535
		fullTitleCacheStringBuilder.append(" ");
536
		fullTitleCacheStringBuilder.append(fauEuConfig.getSourceReferenceTitle());
537
		return fullTitleCacheStringBuilder.toString();
538
	}
539
	
540
	
541
	private String genusPart(StringBuilder originalGenusName, boolean useOriginalGenus, 
542
			StringBuilder genusOrUninomial) {
543

    
544
		StringBuilder stringBuilder = new StringBuilder();
545
		
546
		if(useOriginalGenus == true) {
547
			stringBuilder.append(originalGenusName);
548
			genusOrUninomial.delete(0, genusOrUninomial.length());
549
			genusOrUninomial.append(originalGenusName);
550
		} else {
551
			stringBuilder.append(genusOrUninomial);
552
		}
553
		stringBuilder.append(" ");
554

    
555
		return stringBuilder.toString();
556
	}
557

    
558
	
559
	private String genusSubGenusPart(StringBuilder originalGenusName, boolean useOriginalGenus,
560
			StringBuilder genusOrUninomial,
561
			StringBuilder infraGenericEpithet) {
562

    
563
		StringBuilder stringBuilder = new StringBuilder();
564
		
565
		stringBuilder.append(genusPart(originalGenusName, useOriginalGenus, genusOrUninomial));
566

    
567
		if (useOriginalGenus == true) {
568
			infraGenericEpithet.delete(0, infraGenericEpithet.length());
569
			stringBuilder.append(" ");
570
			return stringBuilder.toString();
571
		}
572

    
573
		stringBuilder.append("(");
574
		stringBuilder.append(infraGenericEpithet);
575
		stringBuilder.append(")");
576
		stringBuilder.append(" ");
577
		
578
		return stringBuilder.toString();
579
	}
580

    
581
	/** Get actual genus id **/
582
	private int getActualGenusId(FaunaEuropaeaTaxon fauEuTaxon) {
583
		
584
		int actualGenusId = -1;
585
		int rank = fauEuTaxon.getRankId();
586
		int parentRankId = fauEuTaxon.getParentRankId();
587
		int grandParentRankId = fauEuTaxon.getGrandParentRankId();
588
		int greatGrandParentRankId = fauEuTaxon.getGreatGrandParentRankId();
589
		
590
		if (fauEuTaxon.isValid()) { // Taxon
591
			
592
			if (rank == R_SPECIES) {
593

    
594
				if(parentRankId == R_SUBGENUS) {
595

    
596
					actualGenusId = fauEuTaxon.getGrandParentId();
597
	
598
				} else if(parentRankId == R_GENUS) {
599

    
600
					actualGenusId = fauEuTaxon.getParentId();
601
				}
602

    
603
			} else if (rank == R_SUBSPECIES) {
604

    
605
				if(grandParentRankId == R_SUBGENUS) {
606

    
607
					actualGenusId = fauEuTaxon.getGreatGrandParentId();
608
					
609
				} else if (grandParentRankId == R_GENUS) {
610

    
611
					actualGenusId = fauEuTaxon.getGrandParentId();
612

    
613
				}
614
			}
615
		} else { // Synonym
616
			
617
			if (rank == R_SPECIES) {
618

    
619
				if(grandParentRankId == R_SUBGENUS) {
620
					
621
					actualGenusId = fauEuTaxon.getGreatGrandParentId();
622
					
623
				} else if (grandParentRankId == R_GENUS) {
624
					
625
					actualGenusId = fauEuTaxon.getGrandParentId();
626

    
627
				}
628

    
629
			} else if (rank == R_SUBSPECIES) {
630
				
631
				if(greatGrandParentRankId == R_SUBGENUS) {
632
					
633
					actualGenusId = fauEuTaxon.getGreatGreatGrandParentId();
634
					
635
				} else if (greatGrandParentRankId == R_GENUS) {
636
					
637
					actualGenusId = fauEuTaxon.getGreatGrandParentId();
638
				}
639
			}
640
		}
641
		return actualGenusId;
642
	}
643
	
644
	
645
	/** Build species and subspecies names */
646
	private String buildLowerTaxonName(StringBuilder originalGenus, boolean useOriginalGenus,
647
			StringBuilder genusOrUninomial, StringBuilder infraGenericEpithet, 
648
			StringBuilder specificEpithet, StringBuilder infraSpecificEpithet,
649
			FaunaEuropaeaTaxon fauEuTaxon) {
650
		
651
		String localName = fauEuTaxon.getLocalName();
652
		int taxonId = fauEuTaxon.getId();
653
		int parentId = fauEuTaxon.getParentId();
654
		StringBuilder nameCacheStringBuilder = new StringBuilder();
655

    
656
//		FaunaEuropaeaTaxon parent = fauEuTaxonMap.get(parentId);
657
		if (parentId == 0) {
658
			nameCacheStringBuilder.append(localName);
659
			if (logger.isInfoEnabled()) {
660
				logger.info("Parent of (" + taxonId + ") is null");
661
			}
662
			return nameCacheStringBuilder.toString();
663
		}
664
		
665
		String parentName = fauEuTaxon.getParentName();
666
		String grandParentName = fauEuTaxon.getGrandParentName();
667
		String greatGrandParentName = fauEuTaxon.getGreatGrandParentName();
668
		int rank = fauEuTaxon.getRankId();
669
		int parentRankId = fauEuTaxon.getParentRankId();
670
		int grandParentRankId = fauEuTaxon.getGrandParentRankId();
671
		int greatGrandParentRankId = fauEuTaxon.getGreatGrandParentRankId();
672
//		int grandParentId = fauEuTaxon.getGrandParentId();
673
//		int greatGrandParentId = grandParent.getParentId();
674

    
675
		
676
		if (fauEuTaxon.isValid()) { // Taxon
677
			
678
			if (rank == R_SPECIES) {
679

    
680
				if(parentRankId == R_SUBGENUS) {
681
					//differ between isParanthesis= true and false
682
					String genusSubGenusPart = genusSubGenusPart(originalGenus, useOriginalGenus, 
683
							genusOrUninomial.append(grandParentName), 
684
							infraGenericEpithet.append(parentName));
685
						nameCacheStringBuilder.append(genusSubGenusPart);
686
					
687

    
688
				} else if(parentRankId == R_GENUS) {
689

    
690
					String genusPart = genusPart(originalGenus, useOriginalGenus, 
691
							genusOrUninomial.append(parentName));
692
					nameCacheStringBuilder.append(genusPart);
693
				}
694
				nameCacheStringBuilder.append(localName);
695
				specificEpithet.append(localName);
696

    
697
			} else if (rank == R_SUBSPECIES) {
698

    
699
				if(grandParentRankId == R_SUBGENUS) {
700

    
701
					String genusSubGenusPart = genusSubGenusPart(originalGenus, useOriginalGenus, 
702
							genusOrUninomial.append(greatGrandParentName), 
703
							infraGenericEpithet.append(grandParentName));
704
					nameCacheStringBuilder.append(genusSubGenusPart);
705

    
706
				} else if (grandParentRankId == R_GENUS) {
707

    
708
					String genusPart = genusPart(originalGenus, useOriginalGenus, 
709
							genusOrUninomial.append(grandParentName));
710
					nameCacheStringBuilder.append(genusPart);
711

    
712
				}
713
				nameCacheStringBuilder.append(parentName);
714
				nameCacheStringBuilder.append(" ");
715
				nameCacheStringBuilder.append(localName);
716
				specificEpithet.append(parentName);
717
				infraSpecificEpithet.append(localName);
718
			}
719
		} else { // Synonym
720
			
721
			if (rank == R_SPECIES) {
722

    
723
				if(grandParentRankId == R_SUBGENUS) {
724
					
725
					String genusSubGenusPart = genusSubGenusPart(originalGenus, useOriginalGenus, 
726
							genusOrUninomial.append(greatGrandParentName), 
727
							infraGenericEpithet.append(grandParentName));
728
					nameCacheStringBuilder.append(genusSubGenusPart);
729

    
730
				} else if (grandParentRankId == R_GENUS) {
731
					
732
					String genusPart = genusPart(originalGenus, useOriginalGenus, 
733
							genusOrUninomial.append(grandParentName));
734
					nameCacheStringBuilder.append(genusPart);
735

    
736
				}
737
				nameCacheStringBuilder.append(localName);
738
				specificEpithet.append(localName);
739

    
740
			} else if (rank == R_SUBSPECIES) {
741
				
742
				String greatGreatGrandParentName = fauEuTaxon.getGreatGreatGrandParentName();
743
				
744
				if(greatGrandParentRankId == R_SUBGENUS) {
745
					
746
					String genusSubGenusPart = genusSubGenusPart(originalGenus, useOriginalGenus, 
747
							genusOrUninomial.append(greatGreatGrandParentName), 
748
							infraGenericEpithet.append(greatGrandParentName));
749
					nameCacheStringBuilder.append(genusSubGenusPart);
750
					
751
				} else if (greatGrandParentRankId == R_GENUS) {
752
					
753
					String genusPart = genusPart(originalGenus, useOriginalGenus, 
754
							genusOrUninomial.append(greatGreatGrandParentName));
755
					nameCacheStringBuilder.append(genusPart);
756
				}
757
				
758
				nameCacheStringBuilder.append(grandParentName);
759
				nameCacheStringBuilder.append(" ");
760
				specificEpithet.append(grandParentName);
761
				nameCacheStringBuilder.append(localName);
762
				infraSpecificEpithet.append(localName);
763
			}
764
			
765
			
766
			
767
		}
768
		
769
		return nameCacheStringBuilder.toString();
770
	}
771
	
772
	
773
	/** Build taxon's name parts and caches */
774
	private String buildTaxonName(FaunaEuropaeaTaxon fauEuTaxon, TaxonBase<?> taxonBase, TaxonNameBase<?,?>taxonName,
775
			boolean useOriginalGenus, FaunaEuropaeaImportConfigurator fauEuConfig) {
776

    
777
		/* Local taxon name string */
778
		String localString = "";
779
		/* Concatenated taxon name string */
780
		String completeString = "";
781

    
782
		StringBuilder originalGenus = null;
783
		
784
		
785
		StringBuilder genusOrUninomial = new StringBuilder();
786
		StringBuilder infraGenericEpithet = new StringBuilder(); 
787
		StringBuilder specificEpithet = new StringBuilder();
788
		StringBuilder infraSpecificEpithet = new StringBuilder();
789

    
790
		localString = fauEuTaxon.getLocalName();
791

    
792
		int rank = fauEuTaxon.getRankId();
793
		
794
		String originalGenusString = null;
795
		//rank is subgenus and the taxon is accepted -> the genusepithet is the parentName
796
		if (rank == R_SUBGENUS && fauEuTaxon.isValid()){
797
			originalGenusString = fauEuTaxon.getParentName();
798
			
799
		} else if (rank == R_SUBGENUS && !fauEuTaxon.isValid()){
800
		//the rank is subgenus and not accepted -> the parent is the accepted taxon and the grandparent name is the genusepithet
801
			originalGenusString = fauEuTaxon.getGrandParentName();
802
		}else{
803
			// parent of species can be subgenus, so the grandparent is genus
804
			int parentRankId = fauEuTaxon.getParentRankId();
805
			if (parentRankId == R_SUBGENUS) {
806
				originalGenusString = fauEuTaxon.getGrandParentName();
807
			} else {
808
				originalGenusString = fauEuTaxon.getParentName();
809
			}
810
		}
811
		if (originalGenusString != null) {
812
			originalGenus = new StringBuilder(originalGenusString);
813
		}
814
		
815
		if(logger.isDebugEnabled()) { 
816
			logger.debug("Local taxon name (rank = " + rank + "): " + localString); 
817
		}
818

    
819
		if (rank < R_SPECIES) {
820

    
821
			completeString = localString;
822
			if (rank == R_SUBGENUS) {
823
				infraGenericEpithet.append(localString);
824
				genusOrUninomial.append(originalGenus);
825
				completeString = originalGenus + " ("+ localString + ")";
826
			} else {
827
				genusOrUninomial.append(localString);
828
			}
829
			
830
		} else {
831

    
832
			taxonBase = taxonBase.deproxy(taxonBase, TaxonBase.class);
833

    
834
			completeString = 
835
				buildLowerTaxonName(originalGenus, useOriginalGenus,
836
						genusOrUninomial, infraGenericEpithet, specificEpithet, infraSpecificEpithet,
837
						fauEuTaxon);
838
			
839
			completeString = (String) CdmUtils.removeDuplicateWhitespace(completeString.trim());
840

    
841
		}
842
		return setCompleteTaxonName(completeString, useOriginalGenus,
843
				genusOrUninomial.toString(), infraGenericEpithet.toString(), 
844
				specificEpithet.toString(), infraSpecificEpithet.toString(),
845
				fauEuTaxon, taxonBase, fauEuConfig);
846
		 
847
	}
848
	
849
	
850
	/** Sets name parts and caches */
851
	private String setCompleteTaxonName(String concatString, boolean useOriginalGenus,
852
			String genusOrUninomial, String infraGenericEpithet, String specificEpithet, String infraSpecificEpithet, 
853
			FaunaEuropaeaTaxon fauEuTaxon, TaxonBase<?> taxonBase, FaunaEuropaeaImportConfigurator fauEuConfig) {
854

    
855
		boolean success = true;
856
		
857
		TaxonNameBase<?,?> taxonName = taxonBase.getName();
858
		ZoologicalName zooName = (ZoologicalName)taxonName;
859
		
860
		if (!genusOrUninomial.equals("")) {
861
			zooName.setGenusOrUninomial(emptyToNull(genusOrUninomial));
862
			if (logger.isDebugEnabled()) { 
863
				logger.debug("genusOrUninomial: " + genusOrUninomial); 
864
			}
865
		}
866
		
867
		//if ((!infraGenericEpithet.equals("") && fauEuTaxon.isParenthesis()) || (!infraGenericEpithet.equals("") && fauEuTaxon.)) {
868
		if (fauEuTaxon.getParentRankId() == R_SUBGENUS || (fauEuTaxon.getRankId() == R_SUBGENUS)){
869
			zooName.setInfraGenericEpithet(emptyToNull(infraGenericEpithet));
870
			if (logger.isDebugEnabled()) { 
871
				logger.debug("infraGenericEpithet: " + infraGenericEpithet); 
872
			}
873
		}
874
		if ((fauEuTaxon.getRankId() == R_SPECIES || fauEuTaxon.getRankId() == R_SUBSPECIES)) {
875
			zooName.setSpecificEpithet(emptyToNull(specificEpithet));
876
			if (logger.isDebugEnabled()) { 
877
				logger.debug("specificEpithet: " + specificEpithet); 
878
			}
879
		}
880
		if (fauEuTaxon.getRankId() == R_SUBSPECIES) {
881
			zooName.setInfraSpecificEpithet(emptyToNull(infraSpecificEpithet));
882
			if (logger.isDebugEnabled()) { 
883
				logger.debug("infraSpecificEpithet: " + infraSpecificEpithet); 
884
			}
885
		}
886
		//TODO: use generate NameCache
887
		//zooName.setNameCache(concatString);
888
		String result = zooName.getNameCache();
889
//		zooName.generateTitle();
890
		//String titleCache = buildNameTitleCache(concatString, useOriginalGenus, fauEuTaxon);
891
		//zooName.setTitleCache(titleCache);
892
		//titleCache = buildNameFullTitleCache(concatString, fauEuConfig);
893
//		zooName.generateFullTitle();
894
		//zooName.setFullTitleCache(titleCache); // TODO: Add reference, NC status
895
		
896
//		ImportHelper.setOriginalSource(taxonName, fauEuConfig.getSourceReference(), 
897
//				fauEuTaxon.getId(), "TaxonName");
898
//		taxonBase.setSec(fauEuConfig.getSourceReference());
899
//		taxonBase.generateTitle();
900
		//titleCache = buildTaxonTitleCache(concatString, fauEuConfig.getSourceReference());
901
		//taxonBase.setTitleCache(titleCache);
902
		
903
		if (logger.isDebugEnabled()) { 
904
			logger.debug("Name stored: " + result); 
905
		}
906
		return result;
907
	}
908

    
909
	/**
910
	 * Ensures that empty strings are translated to null.
911
	 * @param genusOrUninomial
912
	 * @return
913
	 */
914
	private String emptyToNull(String text) {
915
		if (CdmUtils.isEmpty(text)) {
916
			return null;
917
		} else {
918
			return text;
919
		}
920
	}
921

    
922
}
(14-14/15)