Project

General

Profile

Download (49 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.ArrayList;
17
import java.util.HashMap;
18
import java.util.HashSet;
19
import java.util.List;
20
import java.util.Map;
21
import java.util.Set;
22
import java.util.UUID;
23

    
24
import org.apache.log4j.Logger;
25
import org.hibernate.Query;
26
import org.springframework.stereotype.Component;
27
import org.springframework.transaction.TransactionStatus;
28

    
29
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
30
import eu.etaxonomy.cdm.io.common.ICdmIO;
31
import eu.etaxonomy.cdm.io.common.MapWrapper;
32
import eu.etaxonomy.cdm.io.common.Source;
33
import eu.etaxonomy.cdm.io.pesi.out.PesiTransformer;
34
import eu.etaxonomy.cdm.model.agent.AgentBase;
35
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
36
import eu.etaxonomy.cdm.model.common.CdmBase;
37
import eu.etaxonomy.cdm.model.common.IdentifiableSource;
38
import eu.etaxonomy.cdm.model.common.Marker;
39
import eu.etaxonomy.cdm.model.common.MarkerType;
40
import eu.etaxonomy.cdm.model.name.Rank;
41
import eu.etaxonomy.cdm.model.name.TaxonName;
42
import eu.etaxonomy.cdm.model.reference.Reference;
43
import eu.etaxonomy.cdm.model.taxon.Classification;
44
import eu.etaxonomy.cdm.model.taxon.Synonym;
45
import eu.etaxonomy.cdm.model.taxon.SynonymType;
46
import eu.etaxonomy.cdm.model.taxon.Taxon;
47
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
48
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
49
//import eu.etaxonomy.cdm.profiler.ProfilerController;
50
import eu.etaxonomy.cdm.model.taxon.TaxonNodeAgentRelation;
51

    
52

    
53

    
54
/**
55
 * @author a.babadshanjan
56
 * @since 12.05.2009
57
 */
58
@Component
59
public class FaunaEuropaeaRelTaxonIncludeImport extends FaunaEuropaeaImportBase  {
60

    
61
    private static final long serialVersionUID = 4068337179814111891L;
62
    private static final Logger logger = Logger.getLogger(FaunaEuropaeaRelTaxonIncludeImport.class);
63

    
64
    public static final String OS_NAMESPACE_TAXON = "Taxon";
65
	private static final String AUCT_STRING = "auct.";
66
	//private static final String acceptedTaxonUUID = "A9C24E42-69F5-4681-9399-041E652CF338"; // any accepted taxon uuid, taken from original fauna europaea database
67
	//private static final String acceptedTaxonUUID = "E23E6295-836A-4332-BF72-7D29949C7C60"; //faunaEu_1_3
68
	//private static final String acceptedTaxonUUID = "bab7642e-f733-4a21-848d-a15250d2f4ed"; //for faunEu (2.4)
69
	private static final String acceptedTaxonUUID = "DADA6F44-B7B5-4C0A-9F32-980F54B02C36"; // for MfNFaunaEuropaea
70

    
71
	private Map<UUID, TeamOrPersonBase> agentMap = new HashMap<>();
72

    
73

    
74
	private Reference sourceRef;
75
    private final String parentPluralString = "Taxa";
76
	private static String ALL_SYNONYM_FROM_CLAUSE = " FROM Taxon INNER JOIN Taxon AS Parent " +
77
	" ON Taxon.TAX_TAX_IDPARENT = Parent.TAX_ID " +
78
	" WHERE (Taxon.TAX_VALID = 0) " +
79
	" AND (Taxon.TAX_AUT_ID <> " + A_AUCT + " OR Taxon.TAX_AUT_ID IS NULL)";
80

    
81
	@Override
82
	protected boolean doCheck(FaunaEuropaeaImportState state) {
83
		boolean result = true;
84
		FaunaEuropaeaImportConfigurator fauEuConfig = state.getConfig();
85
		logger.warn("Checking for Taxa not yet fully implemented");
86
		result &= checkTaxonStatus(fauEuConfig);
87

    
88
		return result;
89
	}
90

    
91
	@Override
92
	protected boolean isIgnore(FaunaEuropaeaImportState state) {
93
		return ! (state.getConfig().isDoTaxonomicallyIncluded() ||
94
		state.getConfig().isDoMisappliedNames() || state.getConfig().isDoHeterotypicSynonyms() || state.getConfig().isDoInferredSynonyms());
95
	}
96

    
97
	private boolean checkTaxonStatus(FaunaEuropaeaImportConfigurator fauEuConfig) {
98
		boolean result = true;
99
//		try {
100
			Source source = fauEuConfig.getSource();
101
			String sqlStr = "";
102
			ResultSet rs = source.getResultSet(sqlStr);
103
			return result;
104
//		} catch (SQLException e) {
105
//			e.printStackTrace();
106
//			return false;
107
//		}
108
	}
109

    
110
	@Override
111
	protected void doInvoke(FaunaEuropaeaImportState state) {
112

    
113
		/*logger.warn("Start RelTaxon doInvoke");
114
		ProfilerController.memorySnapshot();
115
		*/
116
	    TransactionStatus txStatus = startTransaction();
117
	    if (state.getAgentMap().isEmpty()){
118
	        createAgentMap(state);
119
	    }
120
		Map<String, MapWrapper<? extends CdmBase>> stores = state.getStores();
121

    
122
		MapWrapper<TeamOrPersonBase> authorStore = (MapWrapper<TeamOrPersonBase>)stores.get(ICdmIO.TEAM_STORE);
123
		authorStore.makeEmpty();
124

    
125
		if(logger.isInfoEnabled()) { logger.info("Start making relationships..."); }
126

    
127

    
128

    
129
		// the uuid of an accepted taxon is needed here. any accepted taxon will do.
130
		TaxonBase<?> taxon = getTaxonService().find(UUID.fromString(acceptedTaxonUUID));
131
		sourceRef = taxon.getSec();
132

    
133
		Classification tree = getClassificationFor(state, sourceRef);
134
		commitTransaction(txStatus);
135

    
136
		logger.warn("Before processParentsChildren " + state.getConfig().isDoTaxonomicallyIncluded());
137

    
138
		//ProfilerController.memorySnapshot();
139

    
140
		if (state.getConfig().isDoTaxonomicallyIncluded())  {
141
			processParentsChildren(state);
142

    
143
		}
144
		if (state.getConfig().isDoAssociatedSpecialists()){
145
			processAssociatedSpecialists(state);
146
		}
147

    
148
		logger.warn("Before processMissappliedNames " + state.getConfig().isDoMisappliedNames());
149

    
150
		//ProfilerController.memorySnapshot();
151

    
152
		if (state.getConfig().isDoMisappliedNames()) {
153
			processMisappliedNames(state);
154
		}
155
		/*
156
		logger.warn("Before heterotypic synonyms");
157
		ProfilerController.memorySnapshot();
158
		*/
159
		if (state.getConfig().isDoHeterotypicSynonyms()) {
160
			if(logger.isInfoEnabled()) {
161
				logger.info("Start making heterotypic synonyms ...");
162
			}
163
			processHeterotypicSynonyms(state, ALL_SYNONYM_FROM_CLAUSE);
164
		}
165

    
166
		if (state.getConfig().isDoInferredSynonyms()){
167
		    processInferredSynonyms(state);
168
		}
169
		/*
170
		logger.warn("End RelTaxon doInvoke");
171
		ProfilerController.memorySnapshot();
172
		*/
173
		logger.info("End making relationships......");
174

    
175
		return;
176
	}
177

    
178
	/**
179
     * @param state
180
     */
181
    private void createAgentMap(FaunaEuropaeaImportState state) {
182

    
183
        List<String> propertyPaths = new ArrayList<String>();
184
        propertyPaths.add("sources");
185

    
186
        Query query =  getAgentService().getSession().createQuery("select ab.uuid, ob.idInSource from AgentBase ab join ab.sources ob where ob.idNamespace like 'User' ");
187
        List<Object[]> result = query.list();
188
       // List<TeamOrPersonBase> agents = getAgentService().list(TeamOrPersonBase.class, 1000, 0, null, null);
189

    
190
        Integer idInSource;
191
        for (Object[] person: result){
192
            idInSource = Integer.valueOf((String)person[1]);
193
            UUID agentUuid = (UUID) person[0];
194
            state.getAgentMap().put(idInSource, agentUuid);
195
        }
196
    }
197

    
198
    /** Retrieve child-parent uuid map from CDM DB */
199
	private void processParentsChildren(FaunaEuropaeaImportState state) {
200

    
201
		int limit = state.getConfig().getLimitSave();
202

    
203
		TransactionStatus txStatus = null;
204

    
205
		Map<UUID, UUID> childParentMap = null;
206

    
207
		Map<UUID, UUID> taxonSpecialistMap = null;
208
		Map<UUID, UUID> taxonGroupCoordinatorMap = null;
209
		FaunaEuropaeaImportConfigurator fauEuConfig = state.getConfig();
210
		Source source = fauEuConfig.getSource();
211
		int i = 0;
212

    
213
		String selectCount =
214
			" SELECT count(*) ";
215

    
216
		String selectColumns = " SELECT Taxon.UUID AS ChildUuid, Taxon.tax_usr_idgc as group_coordinator, Taxon.tax_usr_idsp as specialist, Parent.UUID AS ParentUuid, Parent.tax_usr_idgc as parent_group_coordinator, Parent.tax_usr_idsp as parent_specialist";
217

    
218
		String fromClause = " FROM Taxon INNER JOIN Taxon AS Parent " +
219
		" ON Taxon.TAX_TAX_IDPARENT = Parent.TAX_ID " +
220
		" WHERE (Taxon.TAX_VALID <> 0) AND (Taxon.TAX_AUT_ID <> " + A_AUCT + " OR Taxon.TAX_AUT_ID IS NULL )";
221

    
222
		String orderClause = " ORDER BY Taxon.TAX_RNK_ID ASC";
223

    
224
		String countQuery =
225
			selectCount + fromClause;
226

    
227
		String selectQuery =
228
			selectColumns + fromClause + orderClause;
229

    
230
		if(logger.isInfoEnabled()) { logger.info("Start making taxonomically included relationships..."); }
231

    
232
		try {
233

    
234
			ResultSet rs = source.getResultSet(countQuery);
235
			rs.next();
236
			int count = rs.getInt(1);
237

    
238
			rs = source.getResultSet(selectQuery);
239

    
240
	        if (logger.isInfoEnabled()) {
241
				logger.info("Number of rows: " + count);
242
				logger.info("Count Query: " + countQuery);
243
				logger.info("Select Query: " + selectQuery);
244
			}
245

    
246
	        while (rs.next()) {
247

    
248
				if ((i++ % limit) == 0) {
249

    
250
					txStatus = startTransaction();
251
					childParentMap = new HashMap<UUID, UUID>(limit);
252
					taxonSpecialistMap = new HashMap<UUID,UUID>(limit);
253
					taxonGroupCoordinatorMap = new HashMap<UUID, UUID>(limit);
254
					if(logger.isInfoEnabled()) {
255
						logger.info("Taxonomically included retrieved: " + (i-1));
256
					}
257
				}
258

    
259
				String childUuidStr = rs.getString("ChildUuid");
260
				String parentUuidStr = rs.getString("ParentUuid");
261

    
262
				int group_coordinator_id = rs.getInt("group_coordinator");
263
				int specialist_id = rs.getInt("specialist");
264
				int parent_group_coordinator_id = rs.getInt("parent_group_coordinator");
265
                int parent_specialist_id = rs.getInt("parent_specialist");
266
				UUID childUuid = UUID.fromString(childUuidStr);
267
				UUID parentUuid = UUID.fromString(parentUuidStr);
268

    
269
				if (!childParentMap.containsKey(childUuid)) {
270

    
271
						childParentMap.put(childUuid, parentUuid);
272

    
273

    
274
				} else {
275
					if(logger.isInfoEnabled()) {
276
						logger.info("Duplicated child UUID (" + childUuid + ")");
277
					}
278
				}
279
				if (!taxonSpecialistMap.containsKey(childUuid)) {
280

    
281
				    taxonSpecialistMap.put(childUuid, state.getAgentMap().get(specialist_id));
282
				}
283
				if (!taxonSpecialistMap.containsKey(parentUuid)) {
284

    
285
                    taxonSpecialistMap.put(parentUuid, state.getAgentMap().get(parent_specialist_id));
286
                }
287
				if (!taxonGroupCoordinatorMap.containsKey(childUuid)) {
288

    
289
				    taxonGroupCoordinatorMap.put(childUuid, state.getAgentMap().get(group_coordinator_id));
290
                }
291
                if (!taxonGroupCoordinatorMap.containsKey(parentUuid)) {
292

    
293
                    taxonGroupCoordinatorMap.put(parentUuid, state.getAgentMap().get(parent_group_coordinator_id));
294
                }
295

    
296

    
297
				if (((i % limit) == 0 && i != 1 ) || i == count ) {
298

    
299
					createAndCommitParentChildRelationships(
300
							state, txStatus, childParentMap, taxonSpecialistMap, taxonGroupCoordinatorMap);
301
					childParentMap = null;
302

    
303
					if(logger.isInfoEnabled()) {
304
						logger.info("i = " + i + " - Transaction committed");
305
					}
306
				}
307
			}
308
	        rs = null;
309
	        if (childParentMap != null){
310
	        	logger.info("processParentsChildren... last commit");
311
	        	createAndCommitParentChildRelationships(
312
						state, txStatus, childParentMap,taxonSpecialistMap, taxonGroupCoordinatorMap);
313
	        	childParentMap = null;
314
	        }
315

    
316
		} catch (Exception e) {
317
			logger.error("Exception:" +  e);
318
			state.setUnsuccessfull();
319
		}
320
		agentMap = null;
321
		childParentMap = null;
322
		return;
323
	}
324

    
325
	private Map<UUID, UUID> createAndCommitParentChildRelationships(
326
			FaunaEuropaeaImportState state, TransactionStatus txStatus,
327
			Map<UUID, UUID> childParentMap, Map<UUID, UUID> taxonSpecialistMap, Map<UUID, UUID> taxonGroupCoordinatorMap) {
328
		createParentChildRelationships(state, childParentMap, taxonSpecialistMap, taxonGroupCoordinatorMap, txStatus);
329

    
330

    
331
		commitTransaction(txStatus);
332
		return childParentMap;
333
	}
334

    
335

    
336
	/** Retrieve misapplied name / accepted taxon uuid map from CDM DB */
337
	private void processMisappliedNames(FaunaEuropaeaImportState state) {
338

    
339
		int limit = state.getConfig().getLimitSave();
340

    
341
		TransactionStatus txStatus = null;
342

    
343
		Map<UUID, UUID> childParentMap = null;
344
		FaunaEuropaeaImportConfigurator fauEuConfig = state.getConfig();
345
		Source source = fauEuConfig.getSource();
346
		int i = 0;
347

    
348
		String selectCount =
349
			" SELECT count(*) ";
350

    
351
		String selectColumns = " SELECT Taxon.UUID AS MisappliedUuid, Parent.UUID AS AcceptedUuid ";
352

    
353
		String fromClause = " FROM Taxon INNER JOIN Taxon AS Parent " +
354
		" ON Taxon.TAX_TAX_IDPARENT = Parent.TAX_ID " +
355
		" WHERE (Taxon.TAX_VALID = 0) AND (Taxon.TAX_AUT_ID = " + A_AUCT + ")";
356
		String orderClause = " ORDER BY dbo.Taxon.TAX_RNK_ID ASC ";
357

    
358

    
359
		String countQuery =
360
			selectCount + fromClause;
361

    
362
		String selectQuery =
363
			selectColumns + fromClause + orderClause;
364

    
365
		if(logger.isInfoEnabled()) { logger.info("Start making misapplied name relationships..."); }
366

    
367
		try {
368

    
369
			ResultSet rs = source.getResultSet(countQuery);
370
			rs.next();
371
			int count = rs.getInt(1);
372

    
373
			rs = source.getResultSet(selectQuery);
374

    
375
	        if (logger.isInfoEnabled()) {
376
				logger.info("Number of rows: " + count);
377
				logger.info("Count Query: " + countQuery);
378
				logger.info("Select Query: " + selectQuery);
379
			}
380

    
381
			while (rs.next()) {
382

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

    
385
					txStatus = startTransaction();
386
					childParentMap = new HashMap<UUID, UUID>(limit);
387

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

    
393
				String childUuidStr = rs.getString("MisappliedUuid");
394
				String parentUuidStr = rs.getString("AcceptedUuid");
395
				UUID childUuid = UUID.fromString(childUuidStr);
396
				UUID parentUuid = UUID.fromString(parentUuidStr);
397

    
398
				if (!childParentMap.containsKey(childUuid)) {
399
						childParentMap.put(childUuid, parentUuid);
400
				} else {
401
					if(logger.isDebugEnabled()) {
402
						logger.debug("Duplicated child UUID (" + childUuid + ")");
403
					}
404
				}
405

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

    
408
					createAndCommitMisappliedNameRelationships(state, txStatus,
409
							childParentMap);
410
					childParentMap = null;
411

    
412

    
413
					if(logger.isInfoEnabled()) {
414
						logger.info("i = " + i + " - Transaction committed");
415
					}
416
				}
417
			}
418
			if (childParentMap != null){
419
				logger.info("processMisappliedNames... last commit");
420
				createAndCommitMisappliedNameRelationships(state, txStatus,
421
						childParentMap);
422
				childParentMap = null;
423
			}
424

    
425
		} catch (SQLException e) {
426
			logger.error("SQLException:" +  e);
427
			state.setUnsuccessfull();
428
		}
429
		return;
430
	}
431

    
432
	private void createAndCommitMisappliedNameRelationships(
433
			FaunaEuropaeaImportState state, TransactionStatus txStatus,
434
			Map<UUID, UUID> childParentMap) {
435
		createMisappliedNameRelationships(state, childParentMap);
436
		commitTransaction(txStatus);
437
	}
438

    
439
	/** Retrieve synonyms from FauEuDB DB */
440
	private void processHeterotypicSynonyms(FaunaEuropaeaImportState state, String fromClause) {
441

    
442
		FaunaEuropaeaImportConfigurator fauEuConfig = state.getConfig();
443
		Source source = fauEuConfig.getSource();
444

    
445
		String selectCount =
446
			" SELECT count(*) ";
447

    
448
		String selectColumns = " SELECT Taxon.UUID AS SynonymUuid, Parent.UUID AS AcceptedUuid ";
449

    
450
		String orderClause = " ORDER BY dbo.Taxon.TAX_RNK_ID ASC ";
451

    
452
		String countQuery =
453
			selectCount + fromClause;
454

    
455
		String selectQuery =
456
			selectColumns + fromClause + orderClause;
457
		logger.debug(selectQuery);
458

    
459
		try {
460

    
461
			ResultSet rs = source.getResultSet(countQuery);
462
			rs.next();
463
			int count = rs.getInt(1);
464

    
465
			rs = source.getResultSet(selectQuery);
466

    
467
	        if (logger.isInfoEnabled()) {
468
				logger.info("Number of rows: " + count);
469
				logger.info("Count Query: " + countQuery);
470
				logger.info("Select Query: " + selectQuery);
471
			}
472

    
473
	        storeSynonymRelationships(rs, count, state);
474
	        rs = null;
475
		} catch (SQLException e) {
476
			logger.error("SQLException:" +  e);
477
			state.setUnsuccessfull();
478
		}
479
		return;
480
	}
481

    
482
	private void storeSynonymRelationships(ResultSet rs, int count, FaunaEuropaeaImportState state)
483
	throws SQLException {
484

    
485
		TransactionStatus txStatus = null;
486
		Map<UUID, UUID> synonymAcceptedMap = null;
487
		int i = 0;
488
		int limit = state.getConfig().getLimitSave();
489

    
490
		while (rs.next()) {
491

    
492
			if ((i++ % limit) == 0) {
493

    
494
				txStatus = startTransaction();
495
				synonymAcceptedMap = new HashMap<UUID, UUID>(limit);
496

    
497
				if(logger.isInfoEnabled()) {
498
					logger.info("Synonyms retrieved: " + (i-1));
499
				}
500
			}
501

    
502
			String synonymUuidStr = rs.getString("SynonymUuid");
503
			String acceptedUuidStr = rs.getString("AcceptedUuid");
504
			UUID synonymUuid = UUID.fromString(synonymUuidStr);
505
			UUID acceptedUuid = UUID.fromString(acceptedUuidStr);
506

    
507
			if (!synonymAcceptedMap.containsKey(synonymUuid)) {
508

    
509
				synonymAcceptedMap.put(synonymUuid, acceptedUuid);
510

    
511
			} else {
512
				if(logger.isDebugEnabled()) {
513
					logger.debug("Duplicated synonym UUID (" + synonymUuid + ")");
514
				}
515
			}
516

    
517
			if (((i % limit) == 0 && i != 1 ) || i == count ) {
518

    
519
				synonymAcceptedMap = createAndCommitHeterotypicSynonyms(state,
520
						txStatus, synonymAcceptedMap);
521

    
522
				if(logger.isInfoEnabled()) {
523
					logger.info("i = " + i + " - Transaction committed");
524
				}
525
			}
526
		}
527
		if (synonymAcceptedMap != null){
528
			logger.info("processHeterotypicSynonyms... last commit");
529
			synonymAcceptedMap = createAndCommitHeterotypicSynonyms(state,
530
					txStatus, synonymAcceptedMap);
531
		}
532
		return;
533
	}
534

    
535
	private Map<UUID, UUID> createAndCommitHeterotypicSynonyms(
536
			FaunaEuropaeaImportState state, TransactionStatus txStatus,
537
			Map<UUID, UUID> synonymAcceptedMap) {
538
		createHeterotypicSynonyms(state, synonymAcceptedMap);
539

    
540
		synonymAcceptedMap = null;
541
		commitTransaction(txStatus);
542
		return synonymAcceptedMap;
543
	}
544

    
545
	/* Creates parent-child relationships.
546
	 * Parent-child pairs are retrieved in blocks via findByUUID(Set<UUID>) from CDM DB.
547
	 */
548
	private void createParentChildRelationships(FaunaEuropaeaImportState state, Map<UUID, UUID> childParentMap, Map<UUID, UUID> taxonSpecialistMap, Map<UUID, UUID> taxonGroupCoordinatorMap, TransactionStatus tx) {
549
		//gets the taxon "Hydroscaphidae"(family)
550
		TaxonBase<?> taxon = getTaxonService().find(UUID.fromString(acceptedTaxonUUID));
551
		sourceRef = taxon.getSec();
552
		int limit = state.getConfig().getLimitSave();
553

    
554
		Classification tree = getClassificationFor(state, sourceRef);
555

    
556
		Set<TaxonBase> childSet = new HashSet<>(limit);
557

    
558
		Set<UUID> childKeysSet = childParentMap.keySet();
559
		Set<UUID> parentValuesSet = new HashSet<>(childParentMap.values());
560
		logger.debug("Start reading children and parents");
561
		if (logger.isInfoEnabled()) {
562
			logger.info("Start reading children and parents");
563
		}
564
		List<TaxonBase> children = getTaxonService().find(childKeysSet);
565
		List<TaxonBase> parents = getTaxonService().find(parentValuesSet);
566
		logger.info(children.size() + "children are available");
567
		logger.info(parents.size() + "parents are available");
568
		Map<UUID, TaxonBase> parentsMap = new HashMap<>(parents.size());
569

    
570
		for (TaxonBase<?> taxonBase : parents){
571
			parentsMap.put(taxonBase.getUuid(), taxonBase);
572
		}
573

    
574
		if (logger.isTraceEnabled()) {
575
			logger.debug("End reading children and parents");
576
			for (UUID uuid : childKeysSet) {
577
				logger.trace("child uuid query: " + uuid);
578
			}
579
			for (UUID uuid : parentValuesSet) {
580
				logger.trace("parent uuid query: " + uuid);
581
			}
582
			for (TaxonBase<?> tb : children) {
583
				logger.trace("child uuid result: " + tb.getUuid());
584
			}
585
			for (TaxonBase<?> tb : parents) {
586
				logger.trace("parent uuid result: " + tb.getUuid());
587
			}
588
		}
589

    
590
		UUID mappedParentUuid = null;
591
		UUID childUuid = null;
592
		TaxonNode childNode;
593
		TeamOrPersonBase taxonomicSpecialist = null;
594
		TeamOrPersonBase groupCoordinator = null;
595
		UUID agentUuid = null;
596
		for (TaxonBase child : children) {
597

    
598
			try {
599
				Taxon childTaxon = child.deproxy(child, Taxon.class);
600
				childUuid = childTaxon.getUuid();
601
				mappedParentUuid = childParentMap.get(childUuid);
602
				TaxonBase parent = null;
603

    
604
				TaxonBase potentialParent = parentsMap.get(mappedParentUuid);
605
//					for (TaxonBase potentialParent : parents ) {
606
//						parentUuid = potentialParent.getUuid();
607
//						if(parentUuid.equals(mappedParentUuid)) {
608
						parent = potentialParent;
609
						if (logger.isInfoEnabled()) {
610
							logger.info("Parent (" + mappedParentUuid + ") found for child (" + childUuid + ")");
611
						}
612
//							break;
613
//						}
614
//					}
615

    
616
				Taxon parentTaxon = parent.deproxy(parent, Taxon.class);
617

    
618
				if (childTaxon != null && parentTaxon != null) {
619

    
620
					childNode = tree.addParentChild(parentTaxon, childTaxon, sourceRef, null);
621
					agentUuid = taxonSpecialistMap.get(childTaxon.getUuid());
622

    
623
					taxonomicSpecialist = agentMap.get(agentUuid);
624
					if (taxonomicSpecialist == null){
625
					    taxonomicSpecialist = (TeamOrPersonBase) getAgentService().find(agentUuid);
626
					    if (taxonomicSpecialist != null){
627
					        agentMap.put(agentUuid, taxonomicSpecialist);
628
					        logger.info("get new person: " + agentUuid + " name: " + taxonomicSpecialist.getTitleCache());
629
					    }
630
					}
631
					if (taxonomicSpecialist != null){
632
    				    childNode.addAgentRelation(FaunaEuropaeaTransformer.getTaxonomicSpecialistType(getTermService()),  taxonomicSpecialist);
633
    				} else {
634
    				    logger.info("Taxonomic Specialist for " + childTaxon.getTitleCache() + " - " + childTaxon.getUuid() + " does not exist");
635
    				}
636

    
637

    
638
					agentUuid = taxonGroupCoordinatorMap.get(childTaxon.getUuid());
639
					groupCoordinator = agentMap.get(agentUuid);
640

    
641
					if (groupCoordinator == null){
642
					    groupCoordinator = (TeamOrPersonBase) getAgentService().find(agentUuid);
643
					    if (groupCoordinator != null){
644
					        agentMap.put(agentUuid, groupCoordinator);
645
					        logger.info("get new person: " + agentUuid + " name: " + groupCoordinator.getTitleCache());
646
					    }
647
					}
648
					if (groupCoordinator != null){
649
                        childNode.addAgentRelation(FaunaEuropaeaTransformer.getGroupCoordinatorType(getTermService()),  groupCoordinator);
650
                    } else {
651
                        logger.debug("Group Coordinator for " + childTaxon.getTitleCache() + " - " + childTaxon.getUuid() + " does not exist");
652
                    }
653

    
654
					//TODO: add the specialist and the group coordinator to the node!!
655
					if (logger.isInfoEnabled()) {
656
						logger.info("Parent-child (" + mappedParentUuid + "-" + childUuid +
657
						") relationship created");
658
					}
659
					if (childTaxon != null && !childSet.contains(childTaxon)) {
660

    
661
						childSet.add(childTaxon);
662

    
663
						if (logger.isDebugEnabled()) {
664
							logger.info("Child taxon (" + childUuid + ") added to Set");
665
						}
666

    
667
					} else {
668
						if (logger.isDebugEnabled()) {
669
							logger.info("Duplicated child taxon (" + childUuid + ")");
670
						}
671
					}
672
				} else {
673
					if (logger.isDebugEnabled()) {
674
						logger.info("Parent(" + mappedParentUuid + ") or child (" + childUuid + " is null");
675
					}
676
				}
677

    
678
			} catch (Exception e) {
679
				logger.error("Error creating taxonomically included relationship parent-child (" +
680
					mappedParentUuid + " <----> " + childUuid + ")", e);
681
			}
682

    
683
		}
684
		if (logger.isInfoEnabled()) {
685
			logger.info("Start saving childSet");
686
		}
687

    
688
		getTaxonService().saveOrUpdate(childSet);
689

    
690
		if (logger.isInfoEnabled()) {
691
			logger.info("End saving childSet");
692
		}
693

    
694
		parentValuesSet = null;
695
		childSet = null;
696
		children = null;
697
		parents = null;
698
		tree = null;
699
		this.agentMap = new HashMap<UUID, TeamOrPersonBase>();
700
		return;
701
	}
702

    
703
	/* Creates misapplied name relationships.
704
	 * Misapplied name-accepted taxon pairs are retrieved in blocks via findByUUID(Set<UUID>) from CDM DB.
705
	 */
706
	private void createMisappliedNameRelationships(FaunaEuropaeaImportState state, Map<UUID, UUID> fromToMap) {
707

    
708
		//gets the taxon "Hydroscaphidae" (family)
709

    
710
		TaxonBase taxon = getTaxonService().find(UUID.fromString(acceptedTaxonUUID));
711
		sourceRef = taxon.getSec();
712
		int limit = state.getConfig().getLimitSave();
713

    
714
			Set<TaxonBase> misappliedNameSet = new HashSet<TaxonBase>(limit);
715

    
716
			Set<UUID> misappliedNamesSet = fromToMap.keySet();
717
			Set<UUID> acceptedTaxaSet = new HashSet<UUID>(fromToMap.values());
718

    
719
			if (logger.isTraceEnabled()) {
720
				logger.trace("Start reading misapplied names and accepted taxa");
721
			}
722
			List<TaxonBase> misappliedNames = getTaxonService().find(misappliedNamesSet);
723
			List<TaxonBase> acceptedTaxa = getTaxonService().find(acceptedTaxaSet);
724
			Map<UUID, TaxonBase> acceptedTaxaMap = new HashMap<UUID, TaxonBase>(acceptedTaxa.size());
725
			for (TaxonBase taxonBase : acceptedTaxa){
726
				acceptedTaxaMap.put(taxonBase.getUuid(), taxonBase);
727
			}
728

    
729
			if (logger.isTraceEnabled()) {
730
				logger.info("End reading misapplied names and accepted taxa");
731
				for (UUID uuid : misappliedNamesSet) {
732
					logger.trace("misapplied name uuid query: " + uuid);
733
				}
734
				for (UUID uuid : acceptedTaxaSet) {
735
					logger.trace("accepted taxon uuid query: " + uuid);
736
				}
737
				for (TaxonBase tb : misappliedNames) {
738
					logger.trace("misapplied name uuid result: " + tb.getUuid());
739
				}
740
				for (TaxonBase tb : acceptedTaxa) {
741
					logger.trace("accepted taxon uuid result: " + tb.getUuid());
742
				}
743
			}
744

    
745
			UUID mappedAcceptedTaxonUuid = null;
746
			UUID misappliedNameUuid = null;
747
			Taxon misappliedNameTaxon = null;
748
			TaxonBase acceptedTaxonBase = null;
749
			Taxon acceptedTaxon = null;
750

    
751
			for (TaxonBase misappliedName : misappliedNames) {
752

    
753
				try {
754

    
755
					misappliedNameTaxon = misappliedName.deproxy(misappliedName, Taxon.class);
756
					misappliedName.setAppendedPhrase(AUCT_STRING);
757

    
758
					misappliedNameUuid = misappliedNameTaxon.getUuid();
759
					mappedAcceptedTaxonUuid = fromToMap.get(misappliedNameUuid);
760
					acceptedTaxonBase = null;
761

    
762
					acceptedTaxonBase = acceptedTaxaMap.get(mappedAcceptedTaxonUuid);
763
							if (logger.isDebugEnabled()) {
764
								logger.debug("Parent (" + mappedAcceptedTaxonUuid + ") found for child (" + misappliedNameUuid + ")");
765
							}
766

    
767
							acceptedTaxon = acceptedTaxonBase.deproxy(acceptedTaxonBase, Taxon.class);
768

    
769
					if (misappliedNameTaxon != null && acceptedTaxon != null) {
770

    
771
						acceptedTaxon.addMisappliedName(misappliedNameTaxon, sourceRef, null);
772

    
773
						if (logger.isDebugEnabled()) {
774
							logger.debug("Accepted taxon / misapplied name (" + mappedAcceptedTaxonUuid + "-" + misappliedNameUuid +
775
							") relationship created");
776
						}
777
						if (!misappliedNameSet.contains(misappliedNameTaxon)) {
778

    
779
							misappliedNameSet.add(misappliedNameTaxon);
780

    
781
							if (logger.isTraceEnabled()) {
782
								logger.trace("Misapplied name taxon (" + misappliedNameUuid + ") added to Set");
783
							}
784

    
785
						} else {
786
							if (logger.isDebugEnabled()) {
787
								logger.debug("Duplicated misapplied name taxon (" + misappliedNameUuid + ")");
788
							}
789
						}
790
					} else {
791
						if (logger.isDebugEnabled()) {
792
							logger.debug("Accepted taxon (" + mappedAcceptedTaxonUuid + ") or misapplied name (" + misappliedNameUuid + " is null");
793
						}
794
					}
795

    
796
					if (misappliedNameTaxon != null && !misappliedNameSet.contains(misappliedNameTaxon)) {
797
						misappliedNameSet.add(misappliedNameTaxon);
798
						if (logger.isTraceEnabled()) {
799
							logger.trace("Misapplied name taxon (" + misappliedNameUuid + ") added to Set");
800
						}
801
					} else {
802
						if (logger.isDebugEnabled()) {
803
							logger.debug("Duplicated misapplied name taxon (" + misappliedNameUuid + ")");
804
						}
805
					}
806

    
807
				} catch (Exception e) {
808
					logger.error("Error creating misapplied name relationship accepted taxon-misapplied name (" +
809
						mappedAcceptedTaxonUuid + "-" + misappliedNameUuid + ")", e);
810
				}
811

    
812
			}
813
			if (logger.isTraceEnabled()) {
814
				logger.trace("Start saving misappliedNameSet");
815
			}
816
			getTaxonService().save(misappliedNameSet);
817
			if (logger.isTraceEnabled()) {
818
				logger.trace("End saving misappliedNameSet");
819
			}
820

    
821
			acceptedTaxaSet = null;
822
			misappliedNameSet = null;
823
			misappliedNames = null;
824
			acceptedTaxa = null;
825

    
826
		return;
827
	}
828

    
829

    
830
	/* Creates heterotypic synonyms.
831
	 * Synonym-accepted taxon pairs are retrieved in blocks via findByUUID(Set<UUID>) from CDM DB.
832
	 */
833
	private void createHeterotypicSynonyms(FaunaEuropaeaImportState state, Map<UUID, UUID> fromToMap) {
834

    
835
		int limit = state.getConfig().getLimitSave();
836

    
837
		Set<TaxonBase> synonymSet = new HashSet<TaxonBase>(limit);
838

    
839
		Set<UUID> synonymUuidSet = fromToMap.keySet();
840
		Set<UUID> acceptedTaxaUuidSet = new HashSet<UUID>(fromToMap.values());
841

    
842
		if (logger.isTraceEnabled()) {
843
			logger.trace("Reading synonym names and accepted taxa...");
844
		}
845
		List<TaxonBase> synonyms = getTaxonService().find(synonymUuidSet);
846
		List<TaxonBase> acceptedTaxa = getTaxonService().find(acceptedTaxaUuidSet);
847
		Map<UUID, TaxonBase> acceptedTaxaMap = new HashMap<UUID, TaxonBase>(acceptedTaxa.size());
848
		for (TaxonBase taxonBase : acceptedTaxa){
849
			acceptedTaxaMap.put(taxonBase.getUuid(), taxonBase);
850
		}
851

    
852
		if (logger.isTraceEnabled()) {
853
			logger.trace("End reading synonyms names and accepted taxa");
854
			for (UUID uuid : synonymUuidSet) {
855
				logger.trace("synonym uuid query: " + uuid);
856
			}
857
			for (UUID uuid : acceptedTaxaUuidSet) {
858
				logger.trace("accepted taxon uuid query: " + uuid);
859
			}
860
			for (TaxonBase tb : synonyms) {
861
				logger.trace("synonym uuid result: " + tb.getUuid());
862
			}
863
			for (TaxonBase tb : acceptedTaxa) {
864
				logger.trace("accepted taxon uuid result: " + tb.getUuid());
865
			}
866
		}
867

    
868
		UUID mappedAcceptedTaxonUuid = null;
869
		UUID synonymUuid = null;
870
		Synonym synonym = null;
871
		TaxonBase acceptedTaxonBase = null;
872
		Taxon acceptedTaxon = null;
873

    
874
		for (TaxonBase synonymTaxonBase : synonyms) {
875

    
876
			try {
877
				//check for misapplied names with nec (in Fauna Europaea they have a synonym relationship to the accepted taxon)
878
				if (synonymTaxonBase instanceof Taxon ){
879
					if (((Taxon)synonymTaxonBase).isMisapplication()){
880
						if (logger.isDebugEnabled()) {
881
							logger.debug("misapplied name with exclusion" +  synonymTaxonBase.getTitleCache());
882
						}
883
					}
884
					continue;
885
				}
886
				synonym = HibernateProxyHelper.deproxy(synonymTaxonBase, Synonym.class);
887
				synonymUuid = synonym.getUuid();
888
				mappedAcceptedTaxonUuid = fromToMap.get(synonymUuid);
889
				acceptedTaxonBase = null;
890

    
891
				acceptedTaxonBase = acceptedTaxaMap.get(mappedAcceptedTaxonUuid);
892
				if (logger.isDebugEnabled()) {
893
					logger.debug("Parent (" + mappedAcceptedTaxonUuid + ") found for child (" + synonymUuid + ")");
894
				}
895
				acceptedTaxon = CdmBase.deproxy(acceptedTaxonBase, Taxon.class);
896

    
897
				if (synonym != null && acceptedTaxon != null) {
898

    
899
					//TODO: in case original genus exists must add synonym to original genus instead of to accepted taxon
900
					acceptedTaxon.addSynonym(synonym, SynonymType.HETEROTYPIC_SYNONYM_OF());
901

    
902
					if (logger.isDebugEnabled()) {
903
						logger.debug("Accepted taxon - synonym (" + mappedAcceptedTaxonUuid + " - " + synonymUuid +
904
						") relationship created");
905
					}
906
					if (synonym != null && !synonymSet.contains(synonym)) {
907

    
908
						synonymSet.add(synonym);
909

    
910
						if (logger.isTraceEnabled()) {
911
							logger.trace("Synonym (" + synonymUuid + ") added to Set");
912
						}
913

    
914
					} else {
915
						if (logger.isDebugEnabled()) {
916
							logger.debug("Duplicated synonym (" + synonymUuid + ")");
917
						}
918
					}
919
				} else {
920
					if (logger.isDebugEnabled()) {
921
						logger.debug("Accepted taxon (" + mappedAcceptedTaxonUuid + ") or misapplied name (" + synonymUuid + " is null");
922
					}
923
				}
924
			} catch (Exception e) {
925
				logger.error("Error attaching synonym to accepted taxon (" +
926
						mappedAcceptedTaxonUuid + "-" + synonymUuid + ": "+ synonymTaxonBase.getTitleCache() +")", e);
927
			}
928
		}
929
		if (logger.isTraceEnabled()) {
930
			logger.trace("Start saving synonymSet");
931
		}
932
		getTaxonService().save(synonymSet);
933
		if (logger.isTraceEnabled()) {
934
			logger.trace("End saving synonymSet");
935
		}
936

    
937
		acceptedTaxaUuidSet = null;
938
		synonymSet = null;
939
		synonyms = null;
940
		acceptedTaxa = null;
941

    
942
		return;
943
	}
944

    
945
	private void processAssociatedSpecialists(FaunaEuropaeaImportState state){
946
		int limit = state.getConfig().getLimitSave();
947

    
948
		TransactionStatus txStatus = null;
949
		Set<UUID> taxonUuids = new HashSet<UUID>();
950
		Map<UUID, Set<UUID>> agentUUIDTaxonMap = new HashMap<UUID, Set<UUID>>();
951
		FaunaEuropaeaImportConfigurator fauEuConfig = state.getConfig();
952
		Source source = fauEuConfig.getSource();
953
		int i = 0;
954
		UUID agentUuid;
955
		Set<UUID> agentUuids = new HashSet<UUID>();
956
		Set<UUID> taxaOfAgent = new HashSet<UUID>();
957
		String selectCount =
958
			" SELECT count(*) ";
959

    
960

    
961

    
962
		String selectColumns = "SELECT  u.USR_GROUPNAME as groupName, u.USR_GROUPNOTE groupNote, u.USR_USR_ID as user_user_id, "
963
				+ "		u.usr_id user_id, user2.USR_ID as user2_id, taxon.UUID as tax_uuid ";
964

    
965
		String fromClause = " FROM USERROLE as userrole left join USERS u on userrole.URL_USR_ID = u.USR_ID join USERS user2 on user2.USR_ID = u.USR_USR_ID "
966
						+ " join TAXON taxon on (taxon.TAX_USR_IDSP= user2.USR_ID or taxon.TAX_USR_IDGC= user2.USR_ID) "
967
						+ " where USERROLE.URL_ROL_ID = 7 ";
968
		String orderClause = " ORDER BY taxon.TAX_ID";
969

    
970
		String countQuery =
971
			selectCount + fromClause;
972

    
973
		String selectQuery =
974
			selectColumns + fromClause + orderClause;
975

    
976
		if(logger.isInfoEnabled()) { logger.info("Start making associated specialists..."); }
977

    
978
		try {
979

    
980
			ResultSet rs = source.getResultSet(countQuery);
981
			rs.next();
982
			int count = rs.getInt(1);
983

    
984
			rs = source.getResultSet(selectQuery);
985

    
986
	        if (logger.isInfoEnabled()) {
987
				logger.info("Number of rows: " + count);
988
				logger.info("Count Query: " + countQuery);
989
				logger.info("Select Query: " + selectQuery);
990
			}
991
	        String oldTaxonUuidString = null;
992
	        while (rs.next()) {
993

    
994
                if ((i++ % limit) == 0) {
995
                    txStatus = startTransaction();
996
                    if(logger.isInfoEnabled()) {
997
                        logger.info("Associated specialists: " + (i-1));
998
                    }
999
                }
1000
                String taxonUUID = rs.getString("tax_uuid");
1001

    
1002
				int userId = rs.getInt("user_id");
1003
				int user2Id = rs.getInt("user2_id");
1004
				String groupName = rs.getString("groupName");
1005

    
1006
				taxonUuids.add(UUID.fromString(taxonUUID));
1007
				agentUuid = state.getAgentMap().get(userId);
1008
				agentUuids.add(agentUuid);
1009
				if (agentUUIDTaxonMap.containsKey(agentUuid)){
1010
				    taxaOfAgent = agentUUIDTaxonMap.get(agentUuid);
1011
				} else{
1012
				    taxaOfAgent = new HashSet<UUID>();
1013
				}
1014
				taxaOfAgent.add(UUID.fromString(taxonUUID));
1015
                agentUUIDTaxonMap.put(agentUuid, taxaOfAgent);
1016

    
1017

    
1018
				 if (((i % limit) == 0 && i != 1 ) || i == count ) {
1019

    
1020
				        createTaxonNodeAgentRealtionships(state, taxonUuids, agentUUIDTaxonMap, agentUuids);
1021
		                commitTransaction(txStatus);
1022
		                agentUUIDTaxonMap.clear();
1023
		                taxonUuids= new HashSet<UUID>();
1024
		                agentUuids=new HashSet<UUID>();
1025
		                if(logger.isInfoEnabled()) {
1026
		                    logger.info("i = " + i + " - Transaction committed");
1027
		                }
1028
		            }
1029

    
1030
	        }
1031
		}catch(SQLException e){
1032
			logger.info("Problems during creating associated specialists.", e);
1033
		}
1034
	}
1035

    
1036
	private void createTaxonNodeAgentRealtionships(FaunaEuropaeaImportState state, Set<UUID> taxonUuids, Map<UUID, Set<UUID>> agentUUIDTaxonMap, Set<UUID> agentUUuids){
1037
	    Taxon taxon = null;
1038
	    TaxonBase taxonBase;
1039
        Synonym syn;
1040
        Set<TaxonNode> nodes = new HashSet<TaxonNode>();
1041
        List<TaxonBase> taxonBases = getTaxonService().find(taxonUuids);
1042
        List<AgentBase> agentBases = getAgentService().find(agentUUuids);
1043
        TeamOrPersonBase associatedSpecialist = null;
1044
        TaxonNodeAgentRelation agentRel = null;
1045

    
1046
        TaxonNode taxonNode;
1047
//        Map<UUID, TeamOrPersonBase> agentsMap = new HashMap<UUID,TeamOrPersonBase>();
1048
//        for (AgentBase agent: agentBases){
1049
//            agentsMap.put(agent.getUuid(), (TeamOrPersonBase) agent);
1050
//        }
1051
        Map<UUID, TaxonBase> taxonMap = new HashMap<UUID,TaxonBase>();
1052
        for (TaxonBase tax: taxonBases){
1053
            taxonMap.put(tax.getUuid(), tax);
1054
        }
1055

    
1056
        for (AgentBase agent: agentBases){
1057
            Set<UUID> taxaUuids = agentUUIDTaxonMap.get(agent.getUuid());
1058
            for (UUID taxonUuid: taxaUuids){
1059
                taxonBase = taxonMap.get(taxonUuid);
1060
                    if (taxonBase instanceof Synonym){
1061
                        logger.debug("synonym has relationship to associated specialist. " + taxonBase.getTitleCache());
1062
                        syn = HibernateProxyHelper.deproxy(taxonBase, Synonym.class);
1063
                        if (syn.getAcceptedTaxon() != null){
1064
                            taxon = syn.getAcceptedTaxon();
1065
                            syn = null;
1066
                        }
1067
                    } else{
1068
                        taxon = HibernateProxyHelper.deproxy(taxonBase, Taxon.class);
1069
                    }
1070

    
1071
                    if (taxon != null && !taxon.getTaxonNodes().isEmpty()){
1072
                        taxonNode = taxon.getTaxonNodes().iterator().next();
1073
                    } else {
1074
                        taxonNode = null;
1075
                        logger.debug("There is an associated specialist for a taxon which has no taxonnode.");
1076
                    }
1077

    
1078

    
1079
                    associatedSpecialist = (TeamOrPersonBase)agent;
1080
                    if (associatedSpecialist != null && taxonNode != null){
1081
                        agentRel =taxonNode.addAgentRelation(FaunaEuropaeaTransformer.getAssociateSpecialistType(getTermService()), associatedSpecialist);
1082
                        /*if (!StringUtils.isBlank(groupName)) {
1083
                            agentRel.addAnnotation(Annotation.NewInstance(groupName, Language.DEFAULT()));
1084
                        }*/
1085
                    }
1086

    
1087

    
1088

    
1089
                nodes.add(taxonNode);
1090
              }
1091
            agent = null;
1092
            associatedSpecialist = null;
1093
            taxonNode = null;
1094
        }
1095
        if (!nodes.isEmpty()){
1096
            while (nodes.contains(null)){
1097
                nodes.remove(null);
1098
            }
1099
            getTaxonNodeService().saveOrUpdate(nodes);
1100
            nodes = null;
1101

    
1102
        }
1103
        taxonMap= null;
1104
        agentMap= null;
1105
        taxonBases = null;
1106
        agentBases = null;
1107
       }
1108

    
1109

    
1110

    
1111
	private void processInferredSynonyms(FaunaEuropaeaImportState state){
1112

    
1113
	        int count;
1114
	        int pastCount;
1115
	        boolean success = true;
1116
	        // Get the limit for objects to save within a single transaction.
1117
	        if (! state.getConfig().isDoInferredSynonyms()){
1118
	            logger.info ("Ignore Creating Inferred Synonyms...");
1119
	            return;
1120
	        }
1121

    
1122
	        int limit = state.getConfig().getLimitSave();
1123
	        // Create inferred synonyms for accepted taxa
1124
	        logger.info("Creating Inferred Synonyms...");
1125

    
1126

    
1127
	        count = 0;
1128
	        pastCount = 0;
1129
	        int pageSize = limit/10;
1130
	        int pageNumber = 1;
1131
	        String inferredSynonymPluralString = "Inferred Synonyms";
1132

    
1133
	        // Start transaction
1134
	        TransactionStatus txStatus = startTransaction(true);
1135
	        logger.info("Started new transaction. Fetching some " + parentPluralString + " first (max: " + limit + ") ...");
1136
	        List<Taxon> taxonList = null;
1137
	        Set<TaxonBase> synonymList = new HashSet<>();
1138

    
1139

    
1140
	        while ((taxonList  = getTaxonService().listTaxaByName(Taxon.class, "*", "*", "*", "*", "*", Rank.SPECIES(), pageSize, pageNumber, null)).size() > 0) {
1141
	            HashMap<Integer, TaxonName> inferredSynonymsDataToBeSaved = new HashMap<>();
1142

    
1143
	            logger.info("Fetched " + taxonList.size() + " " + parentPluralString + ". Importing...");
1144
	            synonymList = createInferredSynonymsForTaxonList(state,  taxonList);
1145
	            getTaxonService().save(synonymList);
1146

    
1147
	          //  getTaxonService().saveOrUpdate(taxonList);
1148
	            // Commit transaction
1149
	            commitTransaction(txStatus);
1150
	            logger.debug("Committed transaction.");
1151
	            logger.info("Imported " + (taxonList.size()) + " " + inferredSynonymPluralString + ". Total: " + count);
1152
	            //pastCount = count;
1153

    
1154

    
1155

    
1156
	            // Start transaction
1157
	            txStatus = startTransaction(true);
1158
	            logger.info("Started new transaction. Fetching some " + parentPluralString + " first (max: " + limit + ") ...");
1159

    
1160
	            // Increment pageNumber
1161
	            pageNumber++;
1162
	        }
1163
	        taxonList = null;
1164
	        while ((taxonList  = getTaxonService().listTaxaByName(Taxon.class, "*", "*", "*", "*", "*", Rank.SUBSPECIES(), pageSize, pageNumber, null)).size() > 0) {
1165
	            HashMap<Integer, TaxonName> inferredSynonymsDataToBeSaved = new HashMap<>();
1166

    
1167
	            logger.info("Fetched " + taxonList.size() + " " + parentPluralString  + ". Exporting...");
1168
	            synonymList = createInferredSynonymsForTaxonList(state, taxonList);
1169

    
1170
	            getTaxonService().save(synonymList);
1171
	            // Commit transaction
1172
	            commitTransaction(txStatus);
1173
	            logger.debug("Committed transaction.");
1174
	            logger.info("Exported " + taxonList.size()+ " " + inferredSynonymPluralString + ". Total: " + count);
1175
	            //pastCount = count;
1176

    
1177

    
1178

    
1179
	            // Start transaction
1180
	            txStatus = startTransaction(true);
1181
	            logger.info("Started new transaction. Fetching some " + parentPluralString + " first (max: " + limit + ") ...");
1182

    
1183
	            // Increment pageNumber
1184
	            pageNumber++;
1185
	            inferredSynonymsDataToBeSaved = null;
1186
	        }
1187
	        if (taxonList.size() == 0) {
1188
	            logger.info("No " + parentPluralString + " left to fetch.");
1189
	        }
1190

    
1191
	        taxonList = null;
1192

    
1193
	        // Commit transaction
1194
	        commitTransaction(txStatus);
1195
	        System.gc();
1196

    
1197
	        //ProfilerController.memorySnapshot();
1198
	        logger.debug("Committed transaction.");
1199

    
1200

    
1201
	}
1202

    
1203
	/**
1204
    * @param state
1205
    * @param mapping
1206
    * @param synRelMapping
1207
    * @param currentTaxonId
1208
    * @param taxonList
1209
    * @param inferredSynonymsDataToBeSaved
1210
    * @return
1211
    */
1212
   private Set<TaxonBase> createInferredSynonymsForTaxonList(FaunaEuropaeaImportState state,
1213
            List<Taxon> taxonList) {
1214

    
1215
       Taxon acceptedTaxon;
1216
       Classification classification = null;
1217
       Set<TaxonBase> inferredSynonyms = new HashSet<>();
1218
       List<Synonym> inferredSynonymsLocal= new ArrayList<>();
1219
       boolean localSuccess = true;
1220

    
1221
       HashMap<Integer, TaxonName> inferredSynonymsDataToBeSaved = new HashMap<>();
1222

    
1223
       for (TaxonBase<?> taxonBase : taxonList) {
1224

    
1225
           if (taxonBase.isInstanceOf(Taxon.class)) { // this should always be the case since we should have fetched accepted taxon only, but you never know...
1226
               acceptedTaxon = CdmBase.deproxy(taxonBase, Taxon.class);
1227
               TaxonName taxonName = acceptedTaxon.getName();
1228

    
1229
               if (taxonName.isZoological()) {
1230
                   Set<TaxonNode> taxonNodes = acceptedTaxon.getTaxonNodes();
1231
                   TaxonNode singleNode = null;
1232

    
1233
                   if (taxonNodes.size() > 0) {
1234
                       // Determine the classification of the current TaxonNode
1235

    
1236
                       singleNode = taxonNodes.iterator().next();
1237
                       if (singleNode != null) {
1238
                           classification = singleNode.getClassification();
1239
                       } else {
1240
                           logger.error("A TaxonNode belonging to this accepted Taxon is NULL: " + acceptedTaxon.getUuid() + " (" + acceptedTaxon.getTitleCache() +")");
1241
                       }
1242
                   } else {
1243
                       // Classification could not be determined directly from this TaxonNode
1244
                       // The stored classification from another TaxonNode is used. It's a simple, but not a failsafe fallback solution.
1245
                       if (taxonNodes.size() == 0) {
1246
                           //logger.error("Classification could not be determined directly from this Taxon: " + acceptedTaxon.getUuid() + " is misapplication? "+acceptedTaxon.isMisapplication()+ "). The classification of the last taxon is used");
1247

    
1248
                       }
1249
                   }
1250

    
1251
                   if (classification != null) {
1252
                       try{
1253
                           TaxonName name = acceptedTaxon.getName();
1254

    
1255
                            //if (name.isSpecies() || name.isInfraSpecific()){
1256
                               inferredSynonymsLocal = getTaxonService().createAllInferredSynonyms(acceptedTaxon, classification, true);
1257
                              // logger.info("number of inferred synonyms: " + inferredSynonyms.size());
1258
                           //}
1259
//                             inferredSynonyms = getTaxonService().createInferredSynonyms(classification, acceptedTaxon, SynonymType.INFERRED_GENUS_OF());
1260
                           if (inferredSynonymsLocal != null) {
1261
                               for (TaxonBase synonym : inferredSynonymsLocal) {
1262
//                                 TaxonNameBase<?,?> synonymName = synonym.getName();
1263
                                   MarkerType markerType =getUuidMarkerType(PesiTransformer.uuidMarkerGuidIsMissing, state);
1264

    
1265
                                   synonym.addMarker(Marker.NewInstance(markerType, true));
1266

    
1267

    
1268
                                   //get SynonymRelationship and export
1269
                                   if (((Synonym)synonym).getAcceptedTaxon() == null ){
1270
                                       IdentifiableSource source = ((Synonym)synonym).getSources().iterator().next();
1271
                                       if (source.getIdNamespace().contains("Potential combination")){
1272
                                           acceptedTaxon.addSynonym((Synonym)synonym, SynonymType.POTENTIAL_COMBINATION_OF());
1273
                                           logger.error(synonym.getTitleCache() + " is not attached to " + acceptedTaxon.getTitleCache() + " type is set to potential combination");
1274
                                       } else if (source.getIdNamespace().contains("Inferred Genus")){
1275
                                           acceptedTaxon.addSynonym((Synonym)synonym, SynonymType.INFERRED_GENUS_OF());
1276
                                           logger.error(synonym.getTitleCache() + " is not attached to " + acceptedTaxon.getTitleCache() + " type is set to inferred genus");
1277
                                       } else if (source.getIdNamespace().contains("Inferred Epithet")){
1278
                                           acceptedTaxon.addSynonym((Synonym)synonym, SynonymType.INFERRED_EPITHET_OF());
1279
                                           logger.error(synonym.getTitleCache() + " is not attached to " + acceptedTaxon.getTitleCache() + " type is set to inferred epithet");
1280
                                       } else{
1281
                                           acceptedTaxon.addSynonym((Synonym)synonym, SynonymType.INFERRED_SYNONYM_OF());
1282
                                           logger.error(synonym.getTitleCache() + " is not attached to " + acceptedTaxon.getTitleCache() + " type is set to inferred synonym");
1283
                                       }
1284

    
1285
                                   } else {
1286
                                       if (!localSuccess) {
1287
                                           logger.error("Synonym relationship export failed " + synonym.getTitleCache() + " accepted taxon: " + acceptedTaxon.getUuid() + " (" + acceptedTaxon.getTitleCache()+")");
1288
                                       } else {
1289
                                          // logger.info("Synonym relationship successfully exported: " + synonym.getTitleCache() + "  " +acceptedTaxon.getUuid() + " (" + acceptedTaxon.getTitleCache()+")");
1290
                                       }
1291
                                   }
1292

    
1293
                                   inferredSynonymsDataToBeSaved.put(synonym.getId(), synonym.getName());
1294
                               }
1295

    
1296
                               inferredSynonyms.addAll(inferredSynonymsLocal);
1297
                              //logger.info("inferredSet: " + inferredSet.size());
1298
                               //getTaxonService().save(inferredSynonyms);
1299
                               //commitTransaction(txStatus);
1300

    
1301
                               inferredSynonymsLocal = null;
1302

    
1303
                           }
1304

    
1305

    
1306
                       }catch(Exception e){
1307
                           logger.error(e.getMessage());
1308
                           e.printStackTrace();
1309
                       }
1310
                   } else {
1311
                       logger.error("Classification is NULL. Inferred Synonyms could not be created for this Taxon: " + acceptedTaxon.getUuid() + " (" + acceptedTaxon.getTitleCache() + ")");
1312
                   }
1313
               } else {
1314
//                         logger.error("TaxonName is not a ZoologicalName: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
1315
               }
1316
           } else {
1317
               logger.error("This TaxonBase is not a Taxon even though it should be: " + taxonBase.getUuid() + " (" + taxonBase.getTitleCache() + ")");
1318
           }
1319
       }
1320
       //getTaxonService().saveOrUpdate(taxonList);
1321
       taxonList = null;
1322
       return inferredSynonyms;
1323
   }
1324

    
1325

    
1326
}
(13-13/20)