Project

General

Profile

Download (26.3 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

    
14
import java.sql.ResultSet;
15
import java.sql.SQLException;
16
import java.util.HashMap;
17
import java.util.HashSet;
18
import java.util.List;
19
import java.util.Map;
20
import java.util.Set;
21
import java.util.UUID;
22

    
23
import org.apache.log4j.Logger;
24
import org.springframework.stereotype.Component;
25
import org.springframework.transaction.TransactionStatus;
26

    
27
import eu.etaxonomy.cdm.io.common.ICdmIO;
28
import eu.etaxonomy.cdm.io.common.MapWrapper;
29
import eu.etaxonomy.cdm.io.common.Source;
30
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
31
import eu.etaxonomy.cdm.model.common.CdmBase;
32
import eu.etaxonomy.cdm.model.reference.Reference;
33
import eu.etaxonomy.cdm.model.taxon.Classification;
34
import eu.etaxonomy.cdm.model.taxon.Synonym;
35
import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;
36
import eu.etaxonomy.cdm.model.taxon.Taxon;
37
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
38
import eu.etaxonomy.cdm.profiler.ProfilerController;
39

    
40

    
41

    
42
/**
43
 * @author a.babadshanjan
44
 * @created 12.05.2009
45
 * @version 1.0
46
 */
47
@Component
48
public class FaunaEuropaeaRelTaxonIncludeImport extends FaunaEuropaeaImportBase  {
49
	
50
	public static final String OS_NAMESPACE_TAXON = "Taxon";
51
	private static final Logger logger = Logger.getLogger(FaunaEuropaeaRelTaxonIncludeImport.class);
52
	//private static final String acceptedTaxonUUID = "A9C24E42-69F5-4681-9399-041E652CF338"; // any accepted taxon uuid, taken from original fauna europaea database
53
	//private static final String acceptedTaxonUUID = "E23E6295-836A-4332-BF72-7D29949C7C60"; //faunaEu_1_3
54
	private static final String acceptedTaxonUUID = "BB9CDF6C-BBA3-4AC7-A3FD-648A14F518A0"; //for faunEu (2.4)
55
	
56
	private Reference<?> sourceRef;
57
	private static String ALL_SYNONYM_FROM_CLAUSE = " FROM Taxon INNER JOIN Taxon AS Parent " +
58
	" ON Taxon.TAX_TAX_IDPARENT = Parent.TAX_ID " +
59
	" WHERE (Taxon.TAX_VALID = 0) " +
60
	" AND (Taxon.TAX_AUT_ID <> " + A_AUCT + " OR Taxon.TAX_AUT_ID IS NULL)";
61

    
62
	/* (non-Javadoc)
63
	 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doCheck(eu.etaxonomy.cdm.io.common.IImportConfigurator)
64
	 */
65
	@Override
66
	protected boolean doCheck(FaunaEuropaeaImportState state) {
67
		boolean result = true;
68
		FaunaEuropaeaImportConfigurator fauEuConfig = state.getConfig();
69
		logger.warn("Checking for Taxa not yet fully implemented");
70
		result &= checkTaxonStatus(fauEuConfig);
71
		
72
		return result;
73
	}
74
	
75
	/* (non-Javadoc)
76
	 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IImportConfigurator)
77
	 */
78
	protected boolean isIgnore(FaunaEuropaeaImportState state) {
79
		return ! (state.getConfig().isDoTaxonomicallyIncluded() || 
80
		state.getConfig().isDoMisappliedNames() || state.getConfig().isDoHeterotypicSynonyms());
81
	}
82

    
83
	private boolean checkTaxonStatus(FaunaEuropaeaImportConfigurator fauEuConfig) {
84
		boolean result = true;
85
//		try {
86
			Source source = fauEuConfig.getSource();
87
			String sqlStr = "";
88
			ResultSet rs = source.getResultSet(sqlStr);
89
			return result;
90
//		} catch (SQLException e) {
91
//			e.printStackTrace();
92
//			return false;
93
//		}
94
	}
95
	
96
	protected void doInvoke(FaunaEuropaeaImportState state) {				
97
		
98
		/*logger.warn("Start RelTaxon doInvoke");
99
		ProfilerController.memorySnapshot();
100
		*/
101
		Map<String, MapWrapper<? extends CdmBase>> stores = state.getStores();
102

    
103
		MapWrapper<TeamOrPersonBase> authorStore = (MapWrapper<TeamOrPersonBase>)stores.get(ICdmIO.TEAM_STORE);
104
		authorStore.makeEmpty();
105

    
106
		if(logger.isInfoEnabled()) { logger.info("Start making relationships..."); }
107

    
108
		TransactionStatus txStatus = startTransaction();
109
		
110
		// the uuid of an accepted taxon is needed here. any accepted taxon will do.
111
		TaxonBase taxon = getTaxonService().find(UUID.fromString(acceptedTaxonUUID));
112
		sourceRef = taxon.getSec();
113

    
114
		Classification tree = getClassificationFor(state, sourceRef);
115
		commitTransaction(txStatus);
116
		/*
117
		logger.warn("Before processParentsChildren");
118
		
119
		ProfilerController.memorySnapshot();
120
		*/
121
		if (state.getConfig().isDoTaxonomicallyIncluded()) {
122
			processParentsChildren(state);
123
		}
124
		/*
125
		logger.warn("Before processMissappliedNames");
126
		
127
		ProfilerController.memorySnapshot();
128
		*/
129
		if (state.getConfig().isDoMisappliedNames()) {
130
			processMisappliedNames(state);
131
		}
132
		/*
133
		logger.warn("Before heterotypic synonyms");
134
		ProfilerController.memorySnapshot();
135
		*/
136
		if (state.getConfig().isDoHeterotypicSynonyms()) {
137
			if(logger.isInfoEnabled()) { 
138
				logger.info("Start making heterotypic synonym relationships..."); 
139
			}
140
			processHeterotypicSynonyms(state, ALL_SYNONYM_FROM_CLAUSE);
141
		}
142
		/*
143
		logger.warn("End RelTaxon doInvoke");
144
		ProfilerController.memorySnapshot();
145
		*/
146
		logger.info("End making taxa...");
147

    
148
		return;
149
	}
150

    
151
	/** Retrieve child-parent uuid map from CDM DB */
152
	private void processParentsChildren(FaunaEuropaeaImportState state) {
153

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

    
156
		TransactionStatus txStatus = null;
157

    
158
		Map<UUID, UUID> childParentMap = null;
159
		FaunaEuropaeaImportConfigurator fauEuConfig = state.getConfig();
160
		Source source = fauEuConfig.getSource();
161
		int i = 0;
162
		
163
		String selectCount = 
164
			" SELECT count(*) ";
165

    
166
		String selectColumns = " SELECT Taxon.UUID AS ChildUuid, Parent.UUID AS ParentUuid ";
167
		
168
		String fromClause = " FROM Taxon INNER JOIN Taxon AS Parent " +
169
		" ON Taxon.TAX_TAX_IDPARENT = Parent.TAX_ID " +
170
		" WHERE (Taxon.TAX_VALID <> 0) AND (Taxon.TAX_AUT_ID <> " + A_AUCT + " OR Taxon.TAX_AUT_ID IS NULL )";
171
		
172
		String orderClause = " ORDER BY Taxon.TAX_RNK_ID ASC";
173

    
174
		String countQuery = 
175
			selectCount + fromClause;
176

    
177
		String selectQuery = 
178
			selectColumns + fromClause + orderClause;
179
			
180
		if(logger.isInfoEnabled()) { logger.info("Start making taxonomically included relationships..."); }
181
		
182
		try {
183

    
184
			ResultSet rs = source.getResultSet(countQuery);
185
			rs.next();
186
			int count = rs.getInt(1);
187
			
188
			rs = source.getResultSet(selectQuery);
189

    
190
	        if (logger.isInfoEnabled()) {
191
				logger.info("Number of rows: " + count);
192
				logger.info("Count Query: " + countQuery);
193
				logger.info("Select Query: " + selectQuery);
194
			}
195

    
196
	        while (rs.next()) {
197
				
198
				if ((i++ % limit) == 0) {
199
					
200
					txStatus = startTransaction();
201
					childParentMap = new HashMap<UUID, UUID>(limit);
202
					
203
					if(logger.isInfoEnabled()) {
204
						logger.info("Taxonomically included retrieved: " + (i-1)); 
205
					}
206
				}
207

    
208
				String childUuidStr = rs.getString("ChildUuid");
209
				String parentUuidStr = rs.getString("ParentUuid");
210
				UUID childUuid = UUID.fromString(childUuidStr);
211
				UUID parentUuid = UUID.fromString(parentUuidStr);
212
				
213
				if (!childParentMap.containsKey(childUuid)) {
214

    
215
						childParentMap.put(childUuid, parentUuid);
216

    
217
				} else {
218
					if(logger.isDebugEnabled()) {
219
						logger.debug("Duplicated child UUID (" + childUuid + ")");
220
					}
221
				}
222
				if (((i % limit) == 0 && i != 1 ) || i == count ) { 
223

    
224
					createAndCommitParentChildRelationships(
225
							state, txStatus, childParentMap);
226
					childParentMap = null;
227

    
228
					if(logger.isInfoEnabled()) {
229
						logger.info("i = " + i + " - Transaction committed"); 
230
					}
231
				}
232
			}
233
	        
234
	        if (childParentMap != null){
235
	        	logger.info("processParentsChildren... last commit");
236
	        	createAndCommitParentChildRelationships(
237
						state, txStatus, childParentMap);
238
	        	childParentMap = null;
239
	        }
240

    
241
		} catch (SQLException e) {
242
			logger.error("SQLException:" +  e);
243
			state.setUnsuccessfull();
244
		}
245
		return;		
246
	}
247

    
248
	private Map<UUID, UUID> createAndCommitParentChildRelationships(
249
			FaunaEuropaeaImportState state, TransactionStatus txStatus,
250
			Map<UUID, UUID> childParentMap) {
251
		createParentChildRelationships(state, childParentMap);
252

    
253
		
254
		commitTransaction(txStatus);
255
		return childParentMap;
256
	}
257
	
258

    
259
	/** Retrieve misapplied name / accepted taxon uuid map from CDM DB */
260
	private void processMisappliedNames(FaunaEuropaeaImportState state) {
261

    
262
		int limit = state.getConfig().getLimitSave();
263

    
264
		TransactionStatus txStatus = null;
265

    
266
		Map<UUID, UUID> childParentMap = null;
267
		FaunaEuropaeaImportConfigurator fauEuConfig = state.getConfig();
268
		Source source = fauEuConfig.getSource();
269
		int i = 0;
270
		
271
		String selectCount = 
272
			" SELECT count(*) ";
273

    
274
		String selectColumns = " SELECT Taxon.UUID AS MisappliedUuid, Parent.UUID AS AcceptedUuid ";
275
		
276
		String fromClause = " FROM Taxon INNER JOIN Taxon AS Parent " +
277
		" ON Taxon.TAX_TAX_IDPARENT = Parent.TAX_ID " +
278
		" WHERE (Taxon.TAX_VALID = 0) AND (Taxon.TAX_AUT_ID = " + A_AUCT + ")";		
279
		String orderClause = " ORDER BY dbo.Taxon.TAX_RNK_ID ASC ";
280

    
281
		
282
		
283
		
284
		String countQuery = 
285
			selectCount + fromClause;
286

    
287
		String selectQuery = 
288
			selectColumns + fromClause + orderClause;
289
			
290
		if(logger.isInfoEnabled()) { logger.info("Start making misapplied name relationships..."); }
291

    
292
		try {
293

    
294
			ResultSet rs = source.getResultSet(countQuery);
295
			rs.next();
296
			int count = rs.getInt(1);
297
			
298
			rs = source.getResultSet(selectQuery);
299

    
300
	        if (logger.isInfoEnabled()) {
301
				logger.info("Number of rows: " + count);
302
				logger.info("Count Query: " + countQuery);
303
				logger.info("Select Query: " + selectQuery);
304
			}
305

    
306
			while (rs.next()) {
307
				
308
				if ((i++ % limit) == 0) {
309
					
310
					txStatus = startTransaction();
311
					childParentMap = new HashMap<UUID, UUID>(limit);
312
					
313
					if(logger.isInfoEnabled()) {
314
						logger.info("Misapplied names retrieved: " + (i-1) ); 
315
					}
316
				}
317

    
318
				String childUuidStr = rs.getString("MisappliedUuid");
319
				String parentUuidStr = rs.getString("AcceptedUuid");
320
				UUID childUuid = UUID.fromString(childUuidStr);
321
				UUID parentUuid = UUID.fromString(parentUuidStr);
322
				
323
				if (!childParentMap.containsKey(childUuid)) {
324

    
325
						childParentMap.put(childUuid, parentUuid);
326

    
327
				} else {
328
					if(logger.isDebugEnabled()) {
329
						logger.debug("Duplicated child UUID (" + childUuid + ")");
330
					}
331
				}
332

    
333
				if (((i % limit) == 0 && i != 1 ) || i == count) { 
334

    
335
					createAndCommitMisappliedNameRelationships(state, txStatus,
336
							childParentMap);
337
					childParentMap = null;
338
					
339

    
340
					if(logger.isInfoEnabled()) {
341
						logger.info("i = " + i + " - Transaction committed"); 
342
					}
343
				}
344
			}
345
			if (childParentMap != null){
346
				logger.info("processMisappliedNames... last commit");
347
				createAndCommitMisappliedNameRelationships(state, txStatus,
348
						childParentMap);
349
				childParentMap = null;
350
			}
351

    
352
		} catch (SQLException e) {
353
			logger.error("SQLException:" +  e);
354
			state.setUnsuccessfull();
355
		}
356
		return;		
357
	}
358

    
359
	private void createAndCommitMisappliedNameRelationships(
360
			FaunaEuropaeaImportState state, TransactionStatus txStatus,
361
			Map<UUID, UUID> childParentMap) {
362
		createMisappliedNameRelationships(state, childParentMap);
363
		commitTransaction(txStatus);
364
	}
365

    
366

    
367

    
368
	/** Retrieve synonyms from FauEuDB DB */
369
	private void processHeterotypicSynonyms(FaunaEuropaeaImportState state, String fromClause) {
370

    
371
		FaunaEuropaeaImportConfigurator fauEuConfig = state.getConfig();
372
		Source source = fauEuConfig.getSource();
373
		
374
		String selectCount = 
375
			" SELECT count(*) ";
376

    
377
		String selectColumns = " SELECT Taxon.UUID AS SynonymUuid, Parent.UUID AS AcceptedUuid ";
378
		
379
		String orderClause = " ORDER BY dbo.Taxon.TAX_RNK_ID ASC ";
380

    
381
		String countQuery = 
382
			selectCount + fromClause;
383

    
384
		String selectQuery = 
385
			selectColumns + fromClause + orderClause;
386
		logger.debug(selectQuery);
387
			
388
		try {
389

    
390
			ResultSet rs = source.getResultSet(countQuery);
391
			rs.next();
392
			int count = rs.getInt(1);
393
			
394
			rs = source.getResultSet(selectQuery);
395

    
396
	        if (logger.isInfoEnabled()) {
397
				logger.info("Number of rows: " + count);
398
				logger.info("Count Query: " + countQuery);
399
				logger.info("Select Query: " + selectQuery);
400
			}
401
	        
402
	        storeSynonymRelationships(rs, count, state);
403

    
404
		} catch (SQLException e) {
405
			logger.error("SQLException:" +  e);
406
			state.setUnsuccessfull();
407
		}
408
		return;		
409
	}
410
	
411
	
412

    
413
	
414
	private void storeSynonymRelationships(ResultSet rs, int count, FaunaEuropaeaImportState state) 
415
	throws SQLException {
416

    
417
		TransactionStatus txStatus = null;
418
		Map<UUID, UUID> synonymAcceptedMap = null;
419
		int i = 0;
420
		int limit = state.getConfig().getLimitSave();
421

    
422
		while (rs.next()) {
423

    
424
			if ((i++ % limit) == 0) {
425

    
426
				txStatus = startTransaction();
427
				synonymAcceptedMap = new HashMap<UUID, UUID>(limit);
428

    
429
				if(logger.isInfoEnabled()) {
430
					logger.info("Synonyms retrieved: " + (i-1)); 
431
				}
432
			}
433

    
434
			String synonymUuidStr = rs.getString("SynonymUuid");
435
			String acceptedUuidStr = rs.getString("AcceptedUuid");
436
			UUID synonymUuid = UUID.fromString(synonymUuidStr);
437
			UUID acceptedUuid = UUID.fromString(acceptedUuidStr);
438

    
439
			if (!synonymAcceptedMap.containsKey(synonymUuid)) {
440

    
441
				synonymAcceptedMap.put(synonymUuid, acceptedUuid);
442

    
443
			} else {
444
				if(logger.isDebugEnabled()) {
445
					logger.debug("Duplicated synonym UUID (" + synonymUuid + ")");
446
				}
447
			}
448

    
449
			if (((i % limit) == 0 && i != 1 ) || i == count ) { 
450

    
451
				synonymAcceptedMap = createAndCommitHeterotypicSynonyms(state,
452
						txStatus, synonymAcceptedMap);
453

    
454
				if(logger.isInfoEnabled()) {
455
					logger.info("i = " + i + " - Transaction committed"); 
456
				}
457
			}
458
		}
459
		if (synonymAcceptedMap != null){
460
			logger.info("processHeterotypicSynonyms... last commit");
461
			synonymAcceptedMap = createAndCommitHeterotypicSynonyms(state,
462
					txStatus, synonymAcceptedMap);
463
		}
464
		return;
465
	}
466

    
467
	private Map<UUID, UUID> createAndCommitHeterotypicSynonyms(
468
			FaunaEuropaeaImportState state, TransactionStatus txStatus,
469
			Map<UUID, UUID> synonymAcceptedMap) {
470
		createHeterotypicSynonyms(state, synonymAcceptedMap);
471

    
472
		synonymAcceptedMap = null;
473
		commitTransaction(txStatus);
474
		return synonymAcceptedMap;
475
	}
476
	
477
	
478
	
479
	
480

    
481
	/* Creates parent-child relationships.
482
	 * Parent-child pairs are retrieved in blocks via findByUUID(Set<UUID>) from CDM DB. 
483
	 */
484
	private void createParentChildRelationships(FaunaEuropaeaImportState state, Map<UUID, UUID> childParentMap) {
485
		//gets the taxon "Hydroscaphidae"(family)
486
		TaxonBase taxon = getTaxonService().find(UUID.fromString(acceptedTaxonUUID));
487
		sourceRef = taxon.getSec();
488
		int limit = state.getConfig().getLimitSave();
489
		
490
		Classification tree = getClassificationFor(state, sourceRef);
491
		
492
		Set<TaxonBase> childSet = new HashSet<TaxonBase>(limit);
493
		
494
		Set<UUID> childKeysSet = childParentMap.keySet();
495
		Set<UUID> parentValuesSet = new HashSet<UUID>(childParentMap.values());
496
		
497
		if (logger.isTraceEnabled()) {
498
			logger.trace("Start reading children and parents");
499
		}
500
		List<TaxonBase> children = getTaxonService().find(childKeysSet);
501
		List<TaxonBase> parents = getTaxonService().find(parentValuesSet);
502
		Map<UUID, TaxonBase> parentsMap = new HashMap<UUID, TaxonBase>(parents.size());
503
		
504
		for (TaxonBase taxonBase : parents){
505
			parentsMap.put(taxonBase.getUuid(), taxonBase);
506
		}
507
		
508
		if (logger.isTraceEnabled()) {
509
			logger.debug("End reading children and parents");
510
			for (UUID uuid : childKeysSet) {
511
				logger.trace("child uuid query: " + uuid);
512
			}
513
			for (UUID uuid : parentValuesSet) {
514
				logger.trace("parent uuid query: " + uuid);
515
			}
516
			for (TaxonBase tb : children) {
517
				logger.trace("child uuid result: " + tb.getUuid());
518
			}
519
			for (TaxonBase tb : parents) {
520
				logger.trace("parent uuid result: " + tb.getUuid());
521
			}
522
		}
523

    
524
		UUID mappedParentUuid = null;
525
		UUID childUuid = null;
526

    
527
		for (TaxonBase child : children) {
528

    
529
			try {
530
				Taxon childTaxon = child.deproxy(child, Taxon.class);
531
				childUuid = childTaxon.getUuid();
532
				mappedParentUuid = childParentMap.get(childUuid);
533
				TaxonBase parent = null;
534
				
535
				TaxonBase potentialParent = parentsMap.get(mappedParentUuid);
536
//					for (TaxonBase potentialParent : parents ) {
537
//						parentUuid = potentialParent.getUuid();
538
//						if(parentUuid.equals(mappedParentUuid)) {
539
						parent = potentialParent;
540
						if (logger.isDebugEnabled()) {
541
							logger.debug("Parent (" + mappedParentUuid + ") found for child (" + childUuid + ")");
542
						}
543
//							break;
544
//						}
545
//					}
546
				
547
				Taxon parentTaxon = parent.deproxy(parent, Taxon.class);
548
				
549
				if (childTaxon != null && parentTaxon != null) {
550
					
551
					tree.addParentChild(parentTaxon, childTaxon, sourceRef, null);
552
					
553
					if (logger.isDebugEnabled()) {
554
						logger.debug("Parent-child (" + mappedParentUuid + "-" + childUuid + 
555
						") relationship created");
556
					}
557
					if (childTaxon != null && !childSet.contains(childTaxon)) {
558
						
559
						childSet.add(childTaxon);
560
						
561
						if (logger.isTraceEnabled()) {
562
							logger.trace("Child taxon (" + childUuid + ") added to Set");
563
						}
564
						
565
					} else {
566
						if (logger.isDebugEnabled()) {
567
							logger.debug("Duplicated child taxon (" + childUuid + ")");
568
						}
569
					}
570
				} else {
571
					if (logger.isDebugEnabled()) {
572
						logger.debug("Parent(" + mappedParentUuid + ") or child (" + childUuid + " is null");
573
					}
574
				}
575
				
576
			} catch (Exception e) {
577
				logger.error("Error creating taxonomically included relationship parent-child (" + 
578
					mappedParentUuid + " <----> " + childUuid + ")", e);
579
			}
580

    
581
		}
582
		if (logger.isTraceEnabled()) {
583
			logger.trace("Start saving childSet");
584
		}
585
		getTaxonService().save(childSet);
586
		if (logger.isTraceEnabled()) {
587
			logger.trace("End saving childSet");
588
		}
589

    
590
		parentValuesSet = null;
591
		childSet = null;
592
		children = null;
593
		parents = null;
594
		tree = null;
595
		
596
		return;
597
	}
598

    
599
	/* Creates misapplied name relationships.
600
	 * Misapplied name-accepted taxon pairs are retrieved in blocks via findByUUID(Set<UUID>) from CDM DB. 
601
	 */
602
	private void createMisappliedNameRelationships(FaunaEuropaeaImportState state, Map<UUID, UUID> fromToMap) {
603

    
604
		//gets the taxon "Hydroscaphidae" (family)
605
		
606
		TaxonBase taxon = getTaxonService().find(UUID.fromString(acceptedTaxonUUID));
607
		sourceRef = taxon.getSec();
608
		int limit = state.getConfig().getLimitSave();
609
		
610
			Set<TaxonBase> misappliedNameSet = new HashSet<TaxonBase>(limit);
611
			
612
			Set<UUID> misappliedNamesSet = fromToMap.keySet();
613
			Set<UUID> acceptedTaxaSet = new HashSet<UUID>(fromToMap.values());
614
			
615
			if (logger.isTraceEnabled()) {
616
				logger.trace("Start reading misapplied names and accepted taxa");
617
			}
618
			List<TaxonBase> misappliedNames = getTaxonService().find(misappliedNamesSet);
619
			List<TaxonBase> acceptedTaxa = getTaxonService().find(acceptedTaxaSet);
620
			Map<UUID, TaxonBase> acceptedTaxaMap = new HashMap<UUID, TaxonBase>(acceptedTaxa.size());
621
			for (TaxonBase taxonBase : acceptedTaxa){
622
				acceptedTaxaMap.put(taxonBase.getUuid(), taxonBase);
623
			}
624
			
625
			if (logger.isTraceEnabled()) {
626
				logger.info("End reading misapplied names and accepted taxa");
627
				for (UUID uuid : misappliedNamesSet) {
628
					logger.trace("misapplied name uuid query: " + uuid);
629
				}
630
				for (UUID uuid : acceptedTaxaSet) {
631
					logger.trace("accepted taxon uuid query: " + uuid);
632
				}
633
				for (TaxonBase tb : misappliedNames) {
634
					logger.trace("misapplied name uuid result: " + tb.getUuid());
635
				}
636
				for (TaxonBase tb : acceptedTaxa) {
637
					logger.trace("accepted taxon uuid result: " + tb.getUuid());
638
				}
639
			}
640

    
641
			UUID mappedAcceptedTaxonUuid = null;
642
			UUID misappliedNameUuid = null;
643
			Taxon misappliedNameTaxon = null;
644
			TaxonBase acceptedTaxonBase = null;
645
			Taxon acceptedTaxon = null;
646

    
647
			for (TaxonBase misappliedName : misappliedNames) {
648

    
649
				try {
650
					misappliedNameTaxon = misappliedName.deproxy(misappliedName, Taxon.class);
651
					misappliedNameUuid = misappliedNameTaxon.getUuid();
652
					mappedAcceptedTaxonUuid = fromToMap.get(misappliedNameUuid);
653
					acceptedTaxonBase = null;
654
					
655
					acceptedTaxonBase = acceptedTaxaMap.get(mappedAcceptedTaxonUuid);
656
							if (logger.isDebugEnabled()) {
657
								logger.debug("Parent (" + mappedAcceptedTaxonUuid + ") found for child (" + misappliedNameUuid + ")");
658
							}
659
					
660
							acceptedTaxon = acceptedTaxonBase.deproxy(acceptedTaxonBase, Taxon.class);
661
					
662
					if (misappliedNameTaxon != null && acceptedTaxon != null) {
663
						
664
						acceptedTaxon.addMisappliedName(misappliedNameTaxon, sourceRef, null);
665
					
666
						if (logger.isDebugEnabled()) {
667
							logger.debug("Accepted taxon / misapplied name (" + mappedAcceptedTaxonUuid + "-" + misappliedNameUuid + 
668
							") relationship created");
669
						}
670
						if (!misappliedNameSet.contains(misappliedNameTaxon)) {
671
							
672
							misappliedNameSet.add(misappliedNameTaxon);
673
							
674
							if (logger.isTraceEnabled()) {
675
								logger.trace("Misapplied name taxon (" + misappliedNameUuid + ") added to Set");
676
							}
677
							
678
						} else {
679
							if (logger.isDebugEnabled()) {
680
								logger.debug("Duplicated misapplied name taxon (" + misappliedNameUuid + ")");
681
							}
682
						}
683
					} else {
684
						if (logger.isDebugEnabled()) {
685
							logger.debug("Accepted taxon (" + mappedAcceptedTaxonUuid + ") or misapplied name (" + misappliedNameUuid + " is null");
686
						}
687
					}
688
					
689
					if (misappliedNameTaxon != null && !misappliedNameSet.contains(misappliedNameTaxon)) {
690
						misappliedNameSet.add(misappliedNameTaxon);
691
						if (logger.isTraceEnabled()) {
692
							logger.trace("Misapplied name taxon (" + misappliedNameUuid + ") added to Set");
693
						}
694
					} else {
695
						if (logger.isDebugEnabled()) {
696
							logger.debug("Duplicated misapplied name taxon (" + misappliedNameUuid + ")");
697
						}
698
					}
699
					
700
				} catch (Exception e) {
701
					logger.error("Error creating misapplied name relationship accepted taxon-misapplied name (" + 
702
						mappedAcceptedTaxonUuid + "-" + misappliedNameUuid + ")", e);
703
				}
704

    
705
			}
706
			if (logger.isTraceEnabled()) {
707
				logger.trace("Start saving misappliedNameSet");
708
			}
709
			getTaxonService().save(misappliedNameSet);
710
			if (logger.isTraceEnabled()) {
711
				logger.trace("End saving misappliedNameSet");
712
			}
713

    
714
			acceptedTaxaSet = null;
715
			misappliedNameSet = null;
716
			misappliedNames = null;
717
			acceptedTaxa = null;
718
		
719
		return;
720
	}
721

    
722
	
723
	/* Creates heterotypic synonym relationships.
724
	 * Synonym-accepted taxon pairs are retrieved in blocks via findByUUID(Set<UUID>) from CDM DB. 
725
	 */
726
	private void createHeterotypicSynonyms(FaunaEuropaeaImportState state, Map<UUID, UUID> fromToMap) {
727

    
728
		int limit = state.getConfig().getLimitSave();
729
		
730
		Set<TaxonBase> synonymSet = new HashSet<TaxonBase>(limit);
731

    
732
		Set<UUID> synonymUuidSet = fromToMap.keySet();
733
		Set<UUID> acceptedTaxaUuidSet = new HashSet<UUID>(fromToMap.values());
734

    
735
		if (logger.isTraceEnabled()) {
736
			logger.trace("Reading synonym names and accepted taxa...");
737
		}
738
		List<TaxonBase> synonyms = getTaxonService().find(synonymUuidSet);
739
		List<TaxonBase> acceptedTaxa = getTaxonService().find(acceptedTaxaUuidSet);
740
		Map<UUID, TaxonBase> acceptedTaxaMap = new HashMap<UUID, TaxonBase>(acceptedTaxa.size());
741
		for (TaxonBase taxonBase : acceptedTaxa){
742
			acceptedTaxaMap.put(taxonBase.getUuid(), taxonBase);
743
		}
744

    
745
		if (logger.isTraceEnabled()) {
746
			logger.trace("End reading synonyms names and accepted taxa");
747
			for (UUID uuid : synonymUuidSet) {
748
				logger.trace("synonym uuid query: " + uuid);
749
			}
750
			for (UUID uuid : acceptedTaxaUuidSet) {
751
				logger.trace("accepted taxon uuid query: " + uuid);
752
			}
753
			for (TaxonBase tb : synonyms) {
754
				logger.trace("synonym uuid result: " + tb.getUuid());
755
			}
756
			for (TaxonBase tb : acceptedTaxa) {
757
				logger.trace("accepted taxon uuid result: " + tb.getUuid());
758
			}
759
		}
760

    
761
		UUID mappedAcceptedTaxonUuid = null;
762
		UUID synonymUuid = null;
763
		Synonym synonym = null;
764
		TaxonBase acceptedTaxonBase = null;
765
		Taxon acceptedTaxon = null;
766

    
767
		for (TaxonBase synonymTaxonBase : synonyms) {
768

    
769
			try {
770
				//check for misapplied names with nec (in Fauna Europaea they have a synonym relationship to the accepted taxon)
771
				if (synonymTaxonBase instanceof Taxon ){
772
					if (((Taxon)synonymTaxonBase).isMisapplication()){
773
						if (logger.isDebugEnabled()) {
774
							logger.debug("misapplied name with exclusion" +  synonymTaxonBase.getTitleCache());
775
						}
776
					}
777
					continue;
778
				}
779
				synonym = CdmBase.deproxy(synonymTaxonBase, Synonym.class);
780
				synonymUuid = synonym.getUuid();
781
				mappedAcceptedTaxonUuid = fromToMap.get(synonymUuid);
782
				acceptedTaxonBase = null;
783

    
784
				acceptedTaxonBase = acceptedTaxaMap.get(mappedAcceptedTaxonUuid);
785
				if (logger.isDebugEnabled()) {
786
					logger.debug("Parent (" + mappedAcceptedTaxonUuid + ") found for child (" + synonymUuid + ")");
787
				}
788
				acceptedTaxon = CdmBase.deproxy(acceptedTaxonBase, Taxon.class);
789

    
790
				if (synonym != null && acceptedTaxon != null) {
791

    
792
					//TODO: in case original genus exists must add synonym to original genus instead of to accepted taxon
793
					acceptedTaxon.addSynonym(synonym, SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF());
794

    
795
					if (logger.isDebugEnabled()) {
796
						logger.debug("Accepted taxon - synonym (" + mappedAcceptedTaxonUuid + " - " + synonymUuid + 
797
						") relationship created");
798
					}
799
					if (synonym != null && !synonymSet.contains(synonym)) {
800

    
801
						synonymSet.add(synonym);
802

    
803
						if (logger.isTraceEnabled()) {
804
							logger.trace("Synonym (" + synonymUuid + ") added to Set");
805
						}
806

    
807
					} else {
808
						if (logger.isDebugEnabled()) {
809
							logger.debug("Duplicated synonym (" + synonymUuid + ")");
810
						}
811
					}
812
				} else {
813
					if (logger.isDebugEnabled()) {
814
						logger.debug("Accepted taxon (" + mappedAcceptedTaxonUuid + ") or misapplied name (" + synonymUuid + " is null");
815
					}
816
				}
817
			} catch (Exception e) {
818
				logger.error("Error creating synonym relationship: accepted taxon-synonym (" + 
819
						mappedAcceptedTaxonUuid + "-" + synonymUuid + ": "+ synonymTaxonBase.getTitleCache() +")", e);
820
			}
821
		}
822
		if (logger.isTraceEnabled()) {
823
			logger.trace("Start saving synonymSet");
824
		}
825
		getTaxonService().save(synonymSet);
826
		if (logger.isTraceEnabled()) {
827
			logger.trace("End saving synonymSet");
828
		}
829

    
830
		acceptedTaxaUuidSet = null;
831
		synonymSet = null;
832
		synonyms = null;
833
		acceptedTaxa = null;
834

    
835
		return;
836
	}
837

    
838
}
(13-13/17)