Project

General

Profile

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

    
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.io.profiler.ProfilerController;
31
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
32
import eu.etaxonomy.cdm.model.common.CdmBase;
33
import eu.etaxonomy.cdm.model.reference.ReferenceBase;
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.model.taxon.TaxonomicTree;
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 = "EC765B43-E909-4D32-8822-34DA186424E8"; // any accepted taxon uuid, taken from original fauna europaea database
53
	
54
	private ReferenceBase<?> sourceRef;
55
	private static String ALL_SYNONYM_FROM_CLAUSE = " FROM Taxon INNER JOIN Taxon AS Parent " +
56
	" ON Taxon.TAX_TAX_IDPARENT = Parent.TAX_ID " +
57
	" WHERE (Taxon.TAX_VALID = 0) " +
58
	" AND (Taxon.TAX_AUT_ID <> " + A_AUCT + " OR Taxon.TAX_AUT_ID IS NULL)";
59

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

    
81
	private boolean checkTaxonStatus(FaunaEuropaeaImportConfigurator fauEuConfig) {
82
		boolean result = true;
83
//		try {
84
			Source source = fauEuConfig.getSource();
85
			String sqlStr = "";
86
			ResultSet rs = source.getResultSet(sqlStr);
87
			return result;
88
//		} catch (SQLException e) {
89
//			e.printStackTrace();
90
//			return false;
91
//		}
92
	}
93
	
94
	protected boolean doInvoke(FaunaEuropaeaImportState state) {				
95
		
96
		boolean success = true;
97

    
98
		Map<String, MapWrapper<? extends CdmBase>> stores = state.getStores();
99

    
100
		MapWrapper<TeamOrPersonBase> authorStore = (MapWrapper<TeamOrPersonBase>)stores.get(ICdmIO.TEAM_STORE);
101
		authorStore.makeEmpty();
102

    
103
		if(logger.isInfoEnabled()) { logger.info("Start making relationships..."); }
104

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

    
111
		TaxonomicTree tree = getTaxonomicTreeFor(state, sourceRef);
112
		commitTransaction(txStatus);
113
		
114
		//ProfilerController.memorySnapshot();
115
		if (state.getConfig().isDoTaxonomicallyIncluded()) {
116
			success = processParentsChildren(state);
117
		}
118
		//ProfilerController.memorySnapshot();
119
		if (state.getConfig().isDoMisappliedNames()) {
120
			success = processMisappliedNames(state);
121
		}
122
		//ProfilerController.memorySnapshot();
123
		if (state.getConfig().isDoHeterotypicSynonyms()) {
124
			if(logger.isInfoEnabled()) { 
125
				logger.info("Start making heterotypic synonym relationships..."); 
126
			}
127
			success = processHeterotypicSynonyms(state, ALL_SYNONYM_FROM_CLAUSE);
128
		}
129
		//ProfilerController.memorySnapshot();
130

    
131
		logger.info("End making taxa...");
132

    
133
		return success;
134
	}
135

    
136
	/** Retrieve child-parent uuid map from CDM DB */
137
	private boolean processParentsChildren(FaunaEuropaeaImportState state) {
138

    
139
		int limit = state.getConfig().getLimitSave();
140

    
141
		TransactionStatus txStatus = null;
142

    
143
		Map<UUID, UUID> childParentMap = null;
144
		FaunaEuropaeaImportConfigurator fauEuConfig = state.getConfig();
145
		Source source = fauEuConfig.getSource();
146
		int i = 0;
147
		boolean success = true;
148

    
149
		String selectCount = 
150
			" SELECT count(*) ";
151

    
152
		String selectColumns = " SELECT Taxon.UUID AS ChildUuid, Parent.UUID AS ParentUuid ";
153
		
154
		String fromClause = " FROM Taxon INNER JOIN Taxon AS Parent " +
155
		" ON Taxon.TAX_TAX_IDPARENT = Parent.TAX_ID " +
156
		" WHERE (Taxon.TAX_VALID <> 0) AND (Taxon.TAX_AUT_ID <> " + A_AUCT + " OR Taxon.TAX_AUT_ID IS NULL )";
157
		
158
		String orderClause = " ORDER BY Taxon.TAX_RNK_ID ASC";
159

    
160
		String countQuery = 
161
			selectCount + fromClause;
162

    
163
		String selectQuery = 
164
			selectColumns + fromClause + orderClause;
165
			
166
		if(logger.isInfoEnabled()) { logger.info("Start making taxonomically included relationships..."); }
167
		
168
		try {
169

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

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

    
182
	        while (rs.next()) {
183
				
184
				if ((i++ % limit) == 0) {
185
					
186
					txStatus = startTransaction();
187
					childParentMap = new HashMap<UUID, UUID>(limit);
188
					
189
					if(logger.isInfoEnabled()) {
190
						logger.info("Taxonomically included retrieved: " + (i-1)); 
191
					}
192
				}
193

    
194
				String childUuidStr = rs.getString("ChildUuid");
195
				String parentUuidStr = rs.getString("ParentUuid");
196
				UUID childUuid = UUID.fromString(childUuidStr);
197
				UUID parentUuid = UUID.fromString(parentUuidStr);
198
				
199
				if (!childParentMap.containsKey(childUuid)) {
200

    
201
						childParentMap.put(childUuid, parentUuid);
202

    
203
				} else {
204
					if(logger.isDebugEnabled()) {
205
						logger.debug("Duplicated child UUID (" + childUuid + ")");
206
					}
207
				}
208
				if (((i % limit) == 0 && i != 1 ) || i == count) { 
209

    
210
					success = createParentChildRelationships(state, childParentMap);
211

    
212
					childParentMap = null;
213
					commitTransaction(txStatus);
214

    
215
					if(logger.isInfoEnabled()) {
216
						logger.info("i = " + i + " - Transaction committed"); 
217
					}
218
				}
219
			}
220

    
221
		} catch (SQLException e) {
222
			logger.error("SQLException:" +  e);
223
			success = false;
224
		}
225
		return success;		
226
	}
227
	
228

    
229
	/** Retrieve misapplied name / accepted taxon uuid map from CDM DB */
230
	private boolean processMisappliedNames(FaunaEuropaeaImportState state) {
231

    
232
		int limit = state.getConfig().getLimitSave();
233

    
234
		TransactionStatus txStatus = null;
235

    
236
		Map<UUID, UUID> childParentMap = null;
237
		FaunaEuropaeaImportConfigurator fauEuConfig = state.getConfig();
238
		Source source = fauEuConfig.getSource();
239
		int i = 0;
240
		boolean success = true;
241

    
242
		String selectCount = 
243
			" SELECT count(*) ";
244

    
245
		String selectColumns = " SELECT Taxon.UUID AS MisappliedUuid, Parent.UUID AS AcceptedUuid ";
246
		
247
		String fromClause = " FROM Taxon INNER JOIN Taxon AS Parent " +
248
		" ON Taxon.TAX_TAX_IDPARENT = Parent.TAX_ID " +
249
		" WHERE (Taxon.TAX_VALID = 0) AND (Taxon.TAX_AUT_ID = " + A_AUCT + ")";
250
		
251
		String orderClause = " ORDER BY dbo.Taxon.TAX_RNK_ID ASC ";
252

    
253
		String countQuery = 
254
			selectCount + fromClause;
255

    
256
		String selectQuery = 
257
			selectColumns + fromClause + orderClause;
258
			
259
		if(logger.isInfoEnabled()) { logger.info("Start making misapplied name relationships..."); }
260

    
261
		try {
262

    
263
			ResultSet rs = source.getResultSet(countQuery);
264
			rs.next();
265
			int count = rs.getInt(1);
266
			
267
			rs = source.getResultSet(selectQuery);
268

    
269
	        if (logger.isInfoEnabled()) {
270
				logger.info("Number of rows: " + count);
271
				logger.info("Count Query: " + countQuery);
272
				logger.info("Select Query: " + selectQuery);
273
			}
274

    
275
			while (rs.next()) {
276
				
277
				if ((i++ % limit) == 0) {
278
					
279
					txStatus = startTransaction();
280
					childParentMap = new HashMap<UUID, UUID>(limit);
281
					
282
					if(logger.isInfoEnabled()) {
283
						logger.info("Misapplied names retrieved: " + (i-1) ); 
284
					}
285
				}
286

    
287
				String childUuidStr = rs.getString("MisappliedUuid");
288
				String parentUuidStr = rs.getString("AcceptedUuid");
289
				UUID childUuid = UUID.fromString(childUuidStr);
290
				UUID parentUuid = UUID.fromString(parentUuidStr);
291
				
292
				if (!childParentMap.containsKey(childUuid)) {
293

    
294
						childParentMap.put(childUuid, parentUuid);
295

    
296
				} else {
297
					if(logger.isDebugEnabled()) {
298
						logger.debug("Duplicated child UUID (" + childUuid + ")");
299
					}
300
				}
301

    
302
				if (((i % limit) == 0 && i != 1 ) || i == count) { 
303

    
304
					success = createMisappliedNameRelationships(state, childParentMap);
305

    
306
					childParentMap = null;
307
					commitTransaction(txStatus);
308

    
309
					if(logger.isInfoEnabled()) {
310
						logger.info("i = " + i + " - Transaction committed"); 
311
					}
312
				}
313
			}
314

    
315
		} catch (SQLException e) {
316
			logger.error("SQLException:" +  e);
317
			success = false;
318
		}
319
		return success;		
320
	}
321

    
322

    
323

    
324
	/** Retrieve synonyms from FauEuDB DB */
325
	private boolean processHeterotypicSynonyms(FaunaEuropaeaImportState state, String fromClause) {
326

    
327
		FaunaEuropaeaImportConfigurator fauEuConfig = state.getConfig();
328
		Source source = fauEuConfig.getSource();
329
		boolean success = true;
330

    
331
		String selectCount = 
332
			" SELECT count(*) ";
333

    
334
		String selectColumns = " SELECT Taxon.UUID AS SynonymUuid, Parent.UUID AS AcceptedUuid ";
335
		
336
		String orderClause = " ORDER BY dbo.Taxon.TAX_RNK_ID ASC ";
337

    
338
		String countQuery = 
339
			selectCount + fromClause;
340

    
341
		String selectQuery = 
342
			selectColumns + fromClause + orderClause;
343
		logger.debug(selectQuery);
344
			
345
		try {
346

    
347
			ResultSet rs = source.getResultSet(countQuery);
348
			rs.next();
349
			int count = rs.getInt(1);
350
			
351
			rs = source.getResultSet(selectQuery);
352

    
353
	        if (logger.isInfoEnabled()) {
354
				logger.info("Number of rows: " + count);
355
				logger.info("Count Query: " + countQuery);
356
				logger.info("Select Query: " + selectQuery);
357
			}
358
	        
359
	        success = storeSynonymRelationships(rs, count, state);
360

    
361
		} catch (SQLException e) {
362
			logger.error("SQLException:" +  e);
363
			success = false;
364
		}
365
		return success;		
366
	}
367
	
368
	
369

    
370
	
371
	private boolean storeSynonymRelationships(ResultSet rs, int count, FaunaEuropaeaImportState state) 
372
	throws SQLException {
373

    
374
		TransactionStatus txStatus = null;
375
		Map<UUID, UUID> synonymAcceptedMap = null;
376
		int i = 0;
377
		boolean success = true;
378
		int limit = state.getConfig().getLimitSave();
379

    
380
		while (rs.next()) {
381

    
382
			if ((i++ % limit) == 0) {
383

    
384
				txStatus = startTransaction();
385
				synonymAcceptedMap = new HashMap<UUID, UUID>(limit);
386

    
387
				if(logger.isInfoEnabled()) {
388
					logger.info("Synonyms retrieved: " + (i-1)); 
389
				}
390
			}
391

    
392
			String synonymUuidStr = rs.getString("SynonymUuid");
393
			String acceptedUuidStr = rs.getString("AcceptedUuid");
394
			UUID synonymUuid = UUID.fromString(synonymUuidStr);
395
			UUID acceptedUuid = UUID.fromString(acceptedUuidStr);
396

    
397
			if (!synonymAcceptedMap.containsKey(synonymUuid)) {
398

    
399
				synonymAcceptedMap.put(synonymUuid, acceptedUuid);
400

    
401
			} else {
402
				if(logger.isDebugEnabled()) {
403
					logger.debug("Duplicated synonym UUID (" + synonymUuid + ")");
404
				}
405
			}
406

    
407
			if (((i % limit) == 0 && i != 1 ) || i == count) { 
408

    
409
				success = createHeterotypicSynonyms(state, synonymAcceptedMap);
410

    
411
				synonymAcceptedMap = null;
412
				commitTransaction(txStatus);
413

    
414
				if(logger.isInfoEnabled()) {
415
					logger.info("i = " + i + " - Transaction committed"); 
416
				}
417
			}
418
		}
419
		return success;
420
	}
421
	
422
	
423
	
424
	
425

    
426
	/* Creates parent-child relationships.
427
	 * Parent-child pairs are retrieved in blocks via findByUUID(Set<UUID>) from CDM DB. 
428
	 */
429
	private boolean createParentChildRelationships(FaunaEuropaeaImportState state, Map<UUID, UUID> childParentMap) {
430
		//gets the taxon "Hydroscaphidae"(family)
431
		TaxonBase taxon = getTaxonService().find(UUID.fromString(acceptedTaxonUUID));
432
		sourceRef = taxon.getSec();
433
		boolean success = true;
434
		int limit = state.getConfig().getLimitSave();
435
		
436
			TaxonomicTree tree = getTaxonomicTreeFor(state, sourceRef);
437
			
438
			Set<TaxonBase> childSet = new HashSet<TaxonBase>(limit);
439
			
440
			Set<UUID> childKeysSet = childParentMap.keySet();
441
			Set<UUID> parentValuesSet = new HashSet<UUID>(childParentMap.values());
442
			
443
			if (logger.isTraceEnabled()) {
444
				logger.trace("Start reading children and parents");
445
			}
446
			List<TaxonBase> children = getTaxonService().find(childKeysSet);
447
			List<TaxonBase> parents = getTaxonService().find(parentValuesSet);
448
			Map<UUID, TaxonBase> parentsMap = new HashMap<UUID, TaxonBase>(parents.size());
449
			for (TaxonBase taxonBase : parents){
450
				parentsMap.put(taxonBase.getUuid(), taxonBase);
451
			}
452
			
453
			if (logger.isTraceEnabled()) {
454
				logger.debug("End reading children and parents");
455
				for (UUID uuid : childKeysSet) {
456
					logger.trace("child uuid query: " + uuid);
457
				}
458
				for (UUID uuid : parentValuesSet) {
459
					logger.trace("parent uuid query: " + uuid);
460
				}
461
				for (TaxonBase tb : children) {
462
					logger.trace("child uuid result: " + tb.getUuid());
463
				}
464
				for (TaxonBase tb : parents) {
465
					logger.trace("parent uuid result: " + tb.getUuid());
466
				}
467
			}
468

    
469
			UUID mappedParentUuid = null;
470
			UUID childUuid = null;
471

    
472
			for (TaxonBase child : children) {
473

    
474
				try {
475
					Taxon childTaxon = child.deproxy(child, Taxon.class);
476
					childUuid = childTaxon.getUuid();
477
					mappedParentUuid = childParentMap.get(childUuid);
478
					TaxonBase parent = null;
479
					
480
					TaxonBase potentialParent = parentsMap.get(mappedParentUuid);
481
//					for (TaxonBase potentialParent : parents ) {
482
//						parentUuid = potentialParent.getUuid();
483
//						if(parentUuid.equals(mappedParentUuid)) {
484
							parent = potentialParent;
485
							if (logger.isDebugEnabled()) {
486
								logger.debug("Parent (" + mappedParentUuid + ") found for child (" + childUuid + ")");
487
							}
488
//							break;
489
//						}
490
//					}
491
					
492
					Taxon parentTaxon = parent.deproxy(parent, Taxon.class);
493
					
494
					if (childTaxon != null && parentTaxon != null) {
495
						
496
						tree.addParentChild(parentTaxon, childTaxon, sourceRef, null);
497
						
498
						if (logger.isDebugEnabled()) {
499
							logger.debug("Parent-child (" + mappedParentUuid + "-" + childUuid + 
500
							") relationship created");
501
						}
502
						if (childTaxon != null && !childSet.contains(childTaxon)) {
503
							
504
							childSet.add(childTaxon);
505
							
506
							if (logger.isTraceEnabled()) {
507
								logger.trace("Child taxon (" + childUuid + ") added to Set");
508
							}
509
							
510
						} else {
511
							if (logger.isDebugEnabled()) {
512
								logger.debug("Duplicated child taxon (" + childUuid + ")");
513
							}
514
						}
515
					} else {
516
						if (logger.isDebugEnabled()) {
517
							logger.debug("Parent(" + mappedParentUuid + ") or child (" + childUuid + " is null");
518
						}
519
					}
520
					
521
				} catch (Exception e) {
522
					logger.error("Error creating taxonomically included relationship parent-child (" + 
523
						mappedParentUuid + "-" + childUuid + ")", e);
524
				}
525

    
526
			}
527
			if (logger.isTraceEnabled()) {
528
				logger.trace("Start saving childSet");
529
			}
530
			getTaxonService().save(childSet);
531
			if (logger.isTraceEnabled()) {
532
				logger.trace("End saving childSet");
533
			}
534

    
535
			parentValuesSet = null;
536
			childSet = null;
537
			children = null;
538
			parents = null;
539
			tree = null;
540
		
541
		return success;
542
	}
543

    
544
	/* Creates misapplied name relationships.
545
	 * Misapplied name-accepted taxon pairs are retrieved in blocks via findByUUID(Set<UUID>) from CDM DB. 
546
	 */
547
	private boolean createMisappliedNameRelationships(FaunaEuropaeaImportState state, Map<UUID, UUID> fromToMap) {
548

    
549
		//gets the taxon "Hydroscaphidae" (family)
550
		
551
		TaxonBase taxon = getTaxonService().find(UUID.fromString(acceptedTaxonUUID));
552
		sourceRef = taxon.getSec();
553
		boolean success = true;
554
		int limit = state.getConfig().getLimitSave();
555
		
556
			Set<TaxonBase> misappliedNameSet = new HashSet<TaxonBase>(limit);
557
			
558
			Set<UUID> misappliedNamesSet = fromToMap.keySet();
559
			Set<UUID> acceptedTaxaSet = new HashSet<UUID>(fromToMap.values());
560
			
561
			if (logger.isTraceEnabled()) {
562
				logger.trace("Start reading misapplied names and accepted taxa");
563
			}
564
			List<TaxonBase> misappliedNames = getTaxonService().find(misappliedNamesSet);
565
			List<TaxonBase> acceptedTaxa = getTaxonService().find(acceptedTaxaSet);
566
			Map<UUID, TaxonBase> acceptedTaxaMap = new HashMap<UUID, TaxonBase>(acceptedTaxa.size());
567
			for (TaxonBase taxonBase : acceptedTaxa){
568
				acceptedTaxaMap.put(taxonBase.getUuid(), taxonBase);
569
			}
570
			
571
			if (logger.isTraceEnabled()) {
572
				logger.info("End reading misapplied names and accepted taxa");
573
				for (UUID uuid : misappliedNamesSet) {
574
					logger.trace("misapplied name uuid query: " + uuid);
575
				}
576
				for (UUID uuid : acceptedTaxaSet) {
577
					logger.trace("accepted taxon uuid query: " + uuid);
578
				}
579
				for (TaxonBase tb : misappliedNames) {
580
					logger.trace("misapplied name uuid result: " + tb.getUuid());
581
				}
582
				for (TaxonBase tb : acceptedTaxa) {
583
					logger.trace("accepted taxon uuid result: " + tb.getUuid());
584
				}
585
			}
586

    
587
			UUID mappedAcceptedTaxonUuid = null;
588
			UUID misappliedNameUuid = null;
589
			Taxon misappliedNameTaxon = null;
590
			TaxonBase acceptedTaxonBase = null;
591
			Taxon acceptedTaxon = null;
592

    
593
			for (TaxonBase misappliedName : misappliedNames) {
594

    
595
				try {
596
					misappliedNameTaxon = misappliedName.deproxy(misappliedName, Taxon.class);
597
					misappliedNameUuid = misappliedNameTaxon.getUuid();
598
					mappedAcceptedTaxonUuid = fromToMap.get(misappliedNameUuid);
599
					acceptedTaxonBase = null;
600
					
601
					acceptedTaxonBase = acceptedTaxaMap.get(mappedAcceptedTaxonUuid);
602
							if (logger.isDebugEnabled()) {
603
								logger.debug("Parent (" + mappedAcceptedTaxonUuid + ") found for child (" + misappliedNameUuid + ")");
604
							}
605
					
606
							acceptedTaxon = acceptedTaxonBase.deproxy(acceptedTaxonBase, Taxon.class);
607
					
608
					if (misappliedNameTaxon != null && acceptedTaxon != null) {
609
						
610
						acceptedTaxon.addMisappliedName(misappliedNameTaxon, sourceRef, null);
611
					
612
						if (logger.isDebugEnabled()) {
613
							logger.debug("Accepted taxon / misapplied name (" + mappedAcceptedTaxonUuid + "-" + misappliedNameUuid + 
614
							") relationship created");
615
						}
616
						if (!misappliedNameSet.contains(misappliedNameTaxon)) {
617
							
618
							misappliedNameSet.add(misappliedNameTaxon);
619
							
620
							if (logger.isTraceEnabled()) {
621
								logger.trace("Misapplied name taxon (" + misappliedNameUuid + ") added to Set");
622
							}
623
							
624
						} else {
625
							if (logger.isDebugEnabled()) {
626
								logger.debug("Duplicated misapplied name taxon (" + misappliedNameUuid + ")");
627
							}
628
						}
629
					} else {
630
						if (logger.isDebugEnabled()) {
631
							logger.debug("Accepted taxon (" + mappedAcceptedTaxonUuid + ") or misapplied name (" + misappliedNameUuid + " is null");
632
						}
633
					}
634
					
635
					if (misappliedNameTaxon != null && !misappliedNameSet.contains(misappliedNameTaxon)) {
636
						misappliedNameSet.add(misappliedNameTaxon);
637
						if (logger.isTraceEnabled()) {
638
							logger.trace("Misapplied name taxon (" + misappliedNameUuid + ") added to Set");
639
						}
640
					} else {
641
						if (logger.isDebugEnabled()) {
642
							logger.debug("Duplicated misapplied name taxon (" + misappliedNameUuid + ")");
643
						}
644
					}
645
					
646
				} catch (Exception e) {
647
					logger.error("Error creating misapplied name relationship accepted taxon-misapplied name (" + 
648
						mappedAcceptedTaxonUuid + "-" + misappliedNameUuid + ")", e);
649
				}
650

    
651
			}
652
			if (logger.isTraceEnabled()) {
653
				logger.trace("Start saving misappliedNameSet");
654
			}
655
			getTaxonService().save(misappliedNameSet);
656
			if (logger.isTraceEnabled()) {
657
				logger.trace("End saving misappliedNameSet");
658
			}
659

    
660
			acceptedTaxaSet = null;
661
			misappliedNameSet = null;
662
			misappliedNames = null;
663
			acceptedTaxa = null;
664
		
665
		return success;
666
	}
667

    
668
	
669
	/* Creates heterotypic synonym relationships.
670
	 * Synonym-accepted taxon pairs are retrieved in blocks via findByUUID(Set<UUID>) from CDM DB. 
671
	 */
672
	private boolean createHeterotypicSynonyms(FaunaEuropaeaImportState state, Map<UUID, UUID> fromToMap) {
673

    
674
		int limit = state.getConfig().getLimitSave();
675
		boolean success = true;
676

    
677
		Set<TaxonBase> synonymSet = new HashSet<TaxonBase>(limit);
678

    
679
		Set<UUID> synonymUuidSet = fromToMap.keySet();
680
		Set<UUID> acceptedTaxaUuidSet = new HashSet<UUID>(fromToMap.values());
681

    
682
		if (logger.isTraceEnabled()) {
683
			logger.trace("Reading synonym names and accepted taxa...");
684
		}
685
		List<TaxonBase> synonyms = getTaxonService().find(synonymUuidSet);
686
		List<TaxonBase> acceptedTaxa = getTaxonService().find(acceptedTaxaUuidSet);
687
		Map<UUID, TaxonBase> acceptedTaxaMap = new HashMap<UUID, TaxonBase>(acceptedTaxa.size());
688
		for (TaxonBase taxonBase : acceptedTaxa){
689
			acceptedTaxaMap.put(taxonBase.getUuid(), taxonBase);
690
		}
691

    
692
		if (logger.isTraceEnabled()) {
693
			logger.trace("End reading synonyms names and accepted taxa");
694
			for (UUID uuid : synonymUuidSet) {
695
				logger.trace("synonym uuid query: " + uuid);
696
			}
697
			for (UUID uuid : acceptedTaxaUuidSet) {
698
				logger.trace("accepted taxon uuid query: " + uuid);
699
			}
700
			for (TaxonBase tb : synonyms) {
701
				logger.trace("synonym uuid result: " + tb.getUuid());
702
			}
703
			for (TaxonBase tb : acceptedTaxa) {
704
				logger.trace("accepted taxon uuid result: " + tb.getUuid());
705
			}
706
		}
707

    
708
		UUID mappedAcceptedTaxonUuid = null;
709
		UUID synonymUuid = null;
710
		Synonym synonym = null;
711
		TaxonBase acceptedTaxonBase = null;
712
		Taxon acceptedTaxon = null;
713

    
714
		for (TaxonBase synonymTaxonBase : synonyms) {
715

    
716
			try {
717
				synonym = synonymTaxonBase.deproxy(synonymTaxonBase, Synonym.class);
718
				synonymUuid = synonym.getUuid();
719
				mappedAcceptedTaxonUuid = fromToMap.get(synonymUuid);
720
				acceptedTaxonBase = null;
721

    
722
				acceptedTaxonBase = acceptedTaxaMap.get(mappedAcceptedTaxonUuid);
723
				if (logger.isDebugEnabled()) {
724
					logger.debug("Parent (" + mappedAcceptedTaxonUuid + ") found for child (" + synonymUuid + ")");
725
				}
726
				acceptedTaxon = acceptedTaxonBase.deproxy(acceptedTaxonBase, Taxon.class);
727

    
728
				if (synonym != null && acceptedTaxon != null) {
729

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

    
733
					if (logger.isDebugEnabled()) {
734
						logger.debug("Accepted taxon - synonym (" + mappedAcceptedTaxonUuid + " - " + synonymUuid + 
735
						") relationship created");
736
					}
737
					if (synonym != null && !synonymSet.contains(synonym)) {
738

    
739
						synonymSet.add(synonym);
740

    
741
						if (logger.isTraceEnabled()) {
742
							logger.trace("Synonym (" + synonymUuid + ") added to Set");
743
						}
744

    
745
					} else {
746
						if (logger.isDebugEnabled()) {
747
							logger.debug("Duplicated synonym (" + synonymUuid + ")");
748
						}
749
					}
750
				} else {
751
					if (logger.isDebugEnabled()) {
752
						logger.debug("Accepted taxon (" + mappedAcceptedTaxonUuid + ") or misapplied name (" + synonymUuid + " is null");
753
					}
754
				}
755
			} catch (Exception e) {
756
				logger.error("Error creating synonym relationship: accepted taxon-synonym (" + 
757
						mappedAcceptedTaxonUuid + "-" + synonymUuid + ")", e);
758
			}
759
		}
760
		if (logger.isTraceEnabled()) {
761
			logger.trace("Start saving synonymSet");
762
		}
763
		getTaxonService().save(synonymSet);
764
		if (logger.isTraceEnabled()) {
765
			logger.trace("End saving synonymSet");
766
		}
767

    
768
		acceptedTaxaUuidSet = null;
769
		synonymSet = null;
770
		synonyms = null;
771
		acceptedTaxa = null;
772

    
773
		return success;
774
	}
775

    
776
}
(12-12/15)