Project

General

Profile

Download (49.8 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.TaxonNameBase;
42
import eu.etaxonomy.cdm.model.name.ZoologicalName;
43
import eu.etaxonomy.cdm.model.reference.Reference;
44
import eu.etaxonomy.cdm.model.taxon.Classification;
45
import eu.etaxonomy.cdm.model.taxon.Synonym;
46
import eu.etaxonomy.cdm.model.taxon.SynonymRelationship;
47
import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;
48
import eu.etaxonomy.cdm.model.taxon.Taxon;
49
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
50
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
51
//import eu.etaxonomy.cdm.profiler.ProfilerController;
52
import eu.etaxonomy.cdm.model.taxon.TaxonNodeAgentRelation;
53

    
54

    
55

    
56
/**
57
 * @author a.babadshanjan
58
 * @created 12.05.2009
59
 */
60
@Component
61
public class FaunaEuropaeaRelTaxonIncludeImport extends FaunaEuropaeaImportBase  {
62

    
63
	public static final String OS_NAMESPACE_TAXON = "Taxon";
64
	private static final String AUCT_STRING = "auct.";
65
	private static final Logger logger = Logger.getLogger(FaunaEuropaeaRelTaxonIncludeImport.class);
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<UUID, TeamOrPersonBase>();
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 synonym relationships...");
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

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

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

    
191
        Integer idInSource;
192
        for (Object[] person: result){
193
            idInSource = Integer.valueOf((String)person[1]);
194
            UUID agentUuid = (UUID) person[0];
195

    
196

    
197
            state.getAgentMap().put(idInSource, agentUuid);
198
        }
199
    }
200

    
201
    /** Retrieve child-parent uuid map from CDM DB */
202
	private void processParentsChildren(FaunaEuropaeaImportState state) {
203

    
204
		int limit = state.getConfig().getLimitSave();
205

    
206
		TransactionStatus txStatus = null;
207

    
208
		Map<UUID, UUID> childParentMap = null;
209

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

    
216
		String selectCount =
217
			" SELECT count(*) ";
218

    
219
		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";
220

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

    
225
		String orderClause = " ORDER BY Taxon.TAX_RNK_ID ASC";
226

    
227
		String countQuery =
228
			selectCount + fromClause;
229

    
230
		String selectQuery =
231
			selectColumns + fromClause + orderClause;
232

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

    
235
		try {
236

    
237
			ResultSet rs = source.getResultSet(countQuery);
238
			rs.next();
239
			int count = rs.getInt(1);
240

    
241
			rs = source.getResultSet(selectQuery);
242

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

    
249
	        while (rs.next()) {
250

    
251
				if ((i++ % limit) == 0) {
252

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

    
262
				String childUuidStr = rs.getString("ChildUuid");
263
				String parentUuidStr = rs.getString("ParentUuid");
264

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

    
272
				if (!childParentMap.containsKey(childUuid)) {
273

    
274
						childParentMap.put(childUuid, parentUuid);
275

    
276

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

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

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

    
292
				    taxonGroupCoordinatorMap.put(childUuid, state.getAgentMap().get(group_coordinator_id));
293
                }
294
                if (!taxonGroupCoordinatorMap.containsKey(parentUuid)) {
295

    
296
                    taxonGroupCoordinatorMap.put(parentUuid, state.getAgentMap().get(parent_group_coordinator_id));
297
                }
298

    
299

    
300
				if (((i % limit) == 0 && i != 1 ) || i == count ) {
301

    
302
					createAndCommitParentChildRelationships(
303
							state, txStatus, childParentMap, taxonSpecialistMap, taxonGroupCoordinatorMap);
304
					childParentMap = null;
305

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

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

    
328
	private Map<UUID, UUID> createAndCommitParentChildRelationships(
329
			FaunaEuropaeaImportState state, TransactionStatus txStatus,
330
			Map<UUID, UUID> childParentMap, Map<UUID, UUID> taxonSpecialistMap, Map<UUID, UUID> taxonGroupCoordinatorMap) {
331
		createParentChildRelationships(state, childParentMap, taxonSpecialistMap, taxonGroupCoordinatorMap, txStatus);
332

    
333

    
334
		commitTransaction(txStatus);
335
		return childParentMap;
336
	}
337

    
338

    
339
	/** Retrieve misapplied name / accepted taxon uuid map from CDM DB */
340
	private void processMisappliedNames(FaunaEuropaeaImportState state) {
341

    
342
		int limit = state.getConfig().getLimitSave();
343

    
344
		TransactionStatus txStatus = null;
345

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

    
351
		String selectCount =
352
			" SELECT count(*) ";
353

    
354
		String selectColumns = " SELECT Taxon.UUID AS MisappliedUuid, Parent.UUID AS AcceptedUuid ";
355

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

    
361

    
362

    
363

    
364
		String countQuery =
365
			selectCount + fromClause;
366

    
367
		String selectQuery =
368
			selectColumns + fromClause + orderClause;
369

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

    
372
		try {
373

    
374
			ResultSet rs = source.getResultSet(countQuery);
375
			rs.next();
376
			int count = rs.getInt(1);
377

    
378
			rs = source.getResultSet(selectQuery);
379

    
380
	        if (logger.isInfoEnabled()) {
381
				logger.info("Number of rows: " + count);
382
				logger.info("Count Query: " + countQuery);
383
				logger.info("Select Query: " + selectQuery);
384
			}
385

    
386
			while (rs.next()) {
387

    
388
				if ((i++ % limit) == 0) {
389

    
390
					txStatus = startTransaction();
391
					childParentMap = new HashMap<UUID, UUID>(limit);
392

    
393
					if(logger.isInfoEnabled()) {
394
						logger.info("Misapplied names retrieved: " + (i-1) );
395
					}
396
				}
397

    
398
				String childUuidStr = rs.getString("MisappliedUuid");
399
				String parentUuidStr = rs.getString("AcceptedUuid");
400
				UUID childUuid = UUID.fromString(childUuidStr);
401
				UUID parentUuid = UUID.fromString(parentUuidStr);
402

    
403
				if (!childParentMap.containsKey(childUuid)) {
404

    
405
						childParentMap.put(childUuid, parentUuid);
406

    
407
				} else {
408
					if(logger.isDebugEnabled()) {
409
						logger.debug("Duplicated child UUID (" + childUuid + ")");
410
					}
411
				}
412

    
413
				if (((i % limit) == 0 && i != 1 ) || i == count) {
414

    
415
					createAndCommitMisappliedNameRelationships(state, txStatus,
416
							childParentMap);
417
					childParentMap = null;
418

    
419

    
420
					if(logger.isInfoEnabled()) {
421
						logger.info("i = " + i + " - Transaction committed");
422
					}
423
				}
424
			}
425
			if (childParentMap != null){
426
				logger.info("processMisappliedNames... last commit");
427
				createAndCommitMisappliedNameRelationships(state, txStatus,
428
						childParentMap);
429
				childParentMap = null;
430
			}
431

    
432
		} catch (SQLException e) {
433
			logger.error("SQLException:" +  e);
434
			state.setUnsuccessfull();
435
		}
436
		return;
437
	}
438

    
439
	private void createAndCommitMisappliedNameRelationships(
440
			FaunaEuropaeaImportState state, TransactionStatus txStatus,
441
			Map<UUID, UUID> childParentMap) {
442
		createMisappliedNameRelationships(state, childParentMap);
443
		commitTransaction(txStatus);
444
	}
445

    
446

    
447

    
448
	/** Retrieve synonyms from FauEuDB DB */
449
	private void processHeterotypicSynonyms(FaunaEuropaeaImportState state, String fromClause) {
450

    
451
		FaunaEuropaeaImportConfigurator fauEuConfig = state.getConfig();
452
		Source source = fauEuConfig.getSource();
453

    
454
		String selectCount =
455
			" SELECT count(*) ";
456

    
457
		String selectColumns = " SELECT Taxon.UUID AS SynonymUuid, Parent.UUID AS AcceptedUuid ";
458

    
459
		String orderClause = " ORDER BY dbo.Taxon.TAX_RNK_ID ASC ";
460

    
461
		String countQuery =
462
			selectCount + fromClause;
463

    
464
		String selectQuery =
465
			selectColumns + fromClause + orderClause;
466
		logger.debug(selectQuery);
467

    
468
		try {
469

    
470
			ResultSet rs = source.getResultSet(countQuery);
471
			rs.next();
472
			int count = rs.getInt(1);
473

    
474
			rs = source.getResultSet(selectQuery);
475

    
476
	        if (logger.isInfoEnabled()) {
477
				logger.info("Number of rows: " + count);
478
				logger.info("Count Query: " + countQuery);
479
				logger.info("Select Query: " + selectQuery);
480
			}
481

    
482
	        storeSynonymRelationships(rs, count, state);
483
	        rs = null;
484
		} catch (SQLException e) {
485
			logger.error("SQLException:" +  e);
486
			state.setUnsuccessfull();
487
		}
488
		return;
489
	}
490

    
491

    
492

    
493

    
494
	private void storeSynonymRelationships(ResultSet rs, int count, FaunaEuropaeaImportState state)
495
	throws SQLException {
496

    
497
		TransactionStatus txStatus = null;
498
		Map<UUID, UUID> synonymAcceptedMap = null;
499
		int i = 0;
500
		int limit = state.getConfig().getLimitSave();
501

    
502
		while (rs.next()) {
503

    
504
			if ((i++ % limit) == 0) {
505

    
506
				txStatus = startTransaction();
507
				synonymAcceptedMap = new HashMap<UUID, UUID>(limit);
508

    
509
				if(logger.isInfoEnabled()) {
510
					logger.info("Synonyms retrieved: " + (i-1));
511
				}
512
			}
513

    
514
			String synonymUuidStr = rs.getString("SynonymUuid");
515
			String acceptedUuidStr = rs.getString("AcceptedUuid");
516
			UUID synonymUuid = UUID.fromString(synonymUuidStr);
517
			UUID acceptedUuid = UUID.fromString(acceptedUuidStr);
518

    
519
			if (!synonymAcceptedMap.containsKey(synonymUuid)) {
520

    
521
				synonymAcceptedMap.put(synonymUuid, acceptedUuid);
522

    
523
			} else {
524
				if(logger.isDebugEnabled()) {
525
					logger.debug("Duplicated synonym UUID (" + synonymUuid + ")");
526
				}
527
			}
528

    
529
			if (((i % limit) == 0 && i != 1 ) || i == count ) {
530

    
531
				synonymAcceptedMap = createAndCommitHeterotypicSynonyms(state,
532
						txStatus, synonymAcceptedMap);
533

    
534
				if(logger.isInfoEnabled()) {
535
					logger.info("i = " + i + " - Transaction committed");
536
				}
537
			}
538
		}
539
		if (synonymAcceptedMap != null){
540
			logger.info("processHeterotypicSynonyms... last commit");
541
			synonymAcceptedMap = createAndCommitHeterotypicSynonyms(state,
542
					txStatus, synonymAcceptedMap);
543
		}
544
		return;
545
	}
546

    
547
	private Map<UUID, UUID> createAndCommitHeterotypicSynonyms(
548
			FaunaEuropaeaImportState state, TransactionStatus txStatus,
549
			Map<UUID, UUID> synonymAcceptedMap) {
550
		createHeterotypicSynonyms(state, synonymAcceptedMap);
551

    
552
		synonymAcceptedMap = null;
553
		commitTransaction(txStatus);
554
		return synonymAcceptedMap;
555
	}
556

    
557

    
558

    
559

    
560

    
561
	/* Creates parent-child relationships.
562
	 * Parent-child pairs are retrieved in blocks via findByUUID(Set<UUID>) from CDM DB.
563
	 */
564
	private void createParentChildRelationships(FaunaEuropaeaImportState state, Map<UUID, UUID> childParentMap, Map<UUID, UUID> taxonSpecialistMap, Map<UUID, UUID> taxonGroupCoordinatorMap, TransactionStatus tx) {
565
		//gets the taxon "Hydroscaphidae"(family)
566
		TaxonBase taxon = getTaxonService().find(UUID.fromString(acceptedTaxonUUID));
567
		sourceRef = taxon.getSec();
568
		int limit = state.getConfig().getLimitSave();
569

    
570
		Classification tree = getClassificationFor(state, sourceRef);
571

    
572
		Set<TaxonBase> childSet = new HashSet<TaxonBase>(limit);
573

    
574
		Set<UUID> childKeysSet = childParentMap.keySet();
575
		Set<UUID> parentValuesSet = new HashSet<UUID>(childParentMap.values());
576
		logger.debug("Start reading children and parents");
577
		if (logger.isInfoEnabled()) {
578
			logger.info("Start reading children and parents");
579
		}
580
		List<TaxonBase> children = getTaxonService().find(childKeysSet);
581
		List<TaxonBase> parents = getTaxonService().find(parentValuesSet);
582
		logger.info(children.size() + "children are available");
583
		logger.info(parents.size() + "parents are available");
584
		Map<UUID, TaxonBase> parentsMap = new HashMap<UUID, TaxonBase>(parents.size());
585

    
586
		for (TaxonBase taxonBase : parents){
587
			parentsMap.put(taxonBase.getUuid(), taxonBase);
588
		}
589

    
590
		if (logger.isTraceEnabled()) {
591
			logger.debug("End reading children and parents");
592
			for (UUID uuid : childKeysSet) {
593
				logger.trace("child uuid query: " + uuid);
594
			}
595
			for (UUID uuid : parentValuesSet) {
596
				logger.trace("parent uuid query: " + uuid);
597
			}
598
			for (TaxonBase tb : children) {
599
				logger.trace("child uuid result: " + tb.getUuid());
600
			}
601
			for (TaxonBase tb : parents) {
602
				logger.trace("parent uuid result: " + tb.getUuid());
603
			}
604
		}
605

    
606
		UUID mappedParentUuid = null;
607
		UUID childUuid = null;
608
		TaxonNode childNode;
609
		TeamOrPersonBase taxonomicSpecialist = null;
610
		TeamOrPersonBase groupCoordinator = null;
611
		UUID agentUuid = null;
612
		for (TaxonBase child : children) {
613

    
614
			try {
615
				Taxon childTaxon = child.deproxy(child, Taxon.class);
616
				childUuid = childTaxon.getUuid();
617
				mappedParentUuid = childParentMap.get(childUuid);
618
				TaxonBase parent = null;
619

    
620
				TaxonBase potentialParent = parentsMap.get(mappedParentUuid);
621
//					for (TaxonBase potentialParent : parents ) {
622
//						parentUuid = potentialParent.getUuid();
623
//						if(parentUuid.equals(mappedParentUuid)) {
624
						parent = potentialParent;
625
						if (logger.isInfoEnabled()) {
626
							logger.info("Parent (" + mappedParentUuid + ") found for child (" + childUuid + ")");
627
						}
628
//							break;
629
//						}
630
//					}
631

    
632
				Taxon parentTaxon = parent.deproxy(parent, Taxon.class);
633

    
634
				if (childTaxon != null && parentTaxon != null) {
635

    
636
					childNode = tree.addParentChild(parentTaxon, childTaxon, sourceRef, null);
637
					agentUuid = taxonSpecialistMap.get(childTaxon.getUuid());
638

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

    
653

    
654
					agentUuid = taxonGroupCoordinatorMap.get(childTaxon.getUuid());
655
					groupCoordinator = agentMap.get(agentUuid);
656

    
657
					if (groupCoordinator == null){
658
					    groupCoordinator = (TeamOrPersonBase) getAgentService().find(agentUuid);
659
					    if (groupCoordinator != null){
660
					        agentMap.put(agentUuid, groupCoordinator);
661
					        logger.info("get new person: " + agentUuid + " name: " + groupCoordinator.getTitleCache());
662
					    }
663
					}
664
					if (groupCoordinator != null){
665
                        childNode.addAgentRelation(FaunaEuropaeaTransformer.getGroupCoordinatorType(getTermService()),  groupCoordinator);
666
                    } else {
667
                        logger.debug("Group Coordinator for " + childTaxon.getTitleCache() + " - " + childTaxon.getUuid() + " does not exist");
668
                    }
669

    
670
					//TODO: add the specialist and the group coordinator to the node!!
671
					if (logger.isInfoEnabled()) {
672
						logger.info("Parent-child (" + mappedParentUuid + "-" + childUuid +
673
						") relationship created");
674
					}
675
					if (childTaxon != null && !childSet.contains(childTaxon)) {
676

    
677
						childSet.add(childTaxon);
678

    
679
						if (logger.isDebugEnabled()) {
680
							logger.info("Child taxon (" + childUuid + ") added to Set");
681
						}
682

    
683
					} else {
684
						if (logger.isDebugEnabled()) {
685
							logger.info("Duplicated child taxon (" + childUuid + ")");
686
						}
687
					}
688
				} else {
689
					if (logger.isDebugEnabled()) {
690
						logger.info("Parent(" + mappedParentUuid + ") or child (" + childUuid + " is null");
691
					}
692
				}
693

    
694
			} catch (Exception e) {
695
				logger.error("Error creating taxonomically included relationship parent-child (" +
696
					mappedParentUuid + " <----> " + childUuid + ")", e);
697
			}
698

    
699
		}
700
		if (logger.isInfoEnabled()) {
701
			logger.info("Start saving childSet");
702
		}
703

    
704
		getTaxonService().saveOrUpdate(childSet);
705

    
706
		if (logger.isInfoEnabled()) {
707
			logger.info("End saving childSet");
708
		}
709

    
710
		parentValuesSet = null;
711
		childSet = null;
712
		children = null;
713
		parents = null;
714
		tree = null;
715
		this.agentMap = new HashMap<UUID, TeamOrPersonBase>();
716
		return;
717
	}
718

    
719
	/* Creates misapplied name relationships.
720
	 * Misapplied name-accepted taxon pairs are retrieved in blocks via findByUUID(Set<UUID>) from CDM DB.
721
	 */
722
	private void createMisappliedNameRelationships(FaunaEuropaeaImportState state, Map<UUID, UUID> fromToMap) {
723

    
724
		//gets the taxon "Hydroscaphidae" (family)
725

    
726
		TaxonBase taxon = getTaxonService().find(UUID.fromString(acceptedTaxonUUID));
727
		sourceRef = taxon.getSec();
728
		int limit = state.getConfig().getLimitSave();
729

    
730
			Set<TaxonBase> misappliedNameSet = new HashSet<TaxonBase>(limit);
731

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

    
735
			if (logger.isTraceEnabled()) {
736
				logger.trace("Start reading misapplied names and accepted taxa");
737
			}
738
			List<TaxonBase> misappliedNames = getTaxonService().find(misappliedNamesSet);
739
			List<TaxonBase> acceptedTaxa = getTaxonService().find(acceptedTaxaSet);
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.info("End reading misapplied names and accepted taxa");
747
				for (UUID uuid : misappliedNamesSet) {
748
					logger.trace("misapplied name uuid query: " + uuid);
749
				}
750
				for (UUID uuid : acceptedTaxaSet) {
751
					logger.trace("accepted taxon uuid query: " + uuid);
752
				}
753
				for (TaxonBase tb : misappliedNames) {
754
					logger.trace("misapplied name 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 misappliedNameUuid = null;
763
			Taxon misappliedNameTaxon = null;
764
			TaxonBase acceptedTaxonBase = null;
765
			Taxon acceptedTaxon = null;
766

    
767
			for (TaxonBase misappliedName : misappliedNames) {
768

    
769
				try {
770

    
771
					misappliedNameTaxon = misappliedName.deproxy(misappliedName, Taxon.class);
772
					misappliedName.setAppendedPhrase(AUCT_STRING);
773

    
774
					misappliedNameUuid = misappliedNameTaxon.getUuid();
775
					mappedAcceptedTaxonUuid = fromToMap.get(misappliedNameUuid);
776
					acceptedTaxonBase = null;
777

    
778
					acceptedTaxonBase = acceptedTaxaMap.get(mappedAcceptedTaxonUuid);
779
							if (logger.isDebugEnabled()) {
780
								logger.debug("Parent (" + mappedAcceptedTaxonUuid + ") found for child (" + misappliedNameUuid + ")");
781
							}
782

    
783
							acceptedTaxon = acceptedTaxonBase.deproxy(acceptedTaxonBase, Taxon.class);
784

    
785
					if (misappliedNameTaxon != null && acceptedTaxon != null) {
786

    
787
						acceptedTaxon.addMisappliedName(misappliedNameTaxon, sourceRef, null);
788

    
789
						if (logger.isDebugEnabled()) {
790
							logger.debug("Accepted taxon / misapplied name (" + mappedAcceptedTaxonUuid + "-" + misappliedNameUuid +
791
							") relationship created");
792
						}
793
						if (!misappliedNameSet.contains(misappliedNameTaxon)) {
794

    
795
							misappliedNameSet.add(misappliedNameTaxon);
796

    
797
							if (logger.isTraceEnabled()) {
798
								logger.trace("Misapplied name taxon (" + misappliedNameUuid + ") added to Set");
799
							}
800

    
801
						} else {
802
							if (logger.isDebugEnabled()) {
803
								logger.debug("Duplicated misapplied name taxon (" + misappliedNameUuid + ")");
804
							}
805
						}
806
					} else {
807
						if (logger.isDebugEnabled()) {
808
							logger.debug("Accepted taxon (" + mappedAcceptedTaxonUuid + ") or misapplied name (" + misappliedNameUuid + " is null");
809
						}
810
					}
811

    
812
					if (misappliedNameTaxon != null && !misappliedNameSet.contains(misappliedNameTaxon)) {
813
						misappliedNameSet.add(misappliedNameTaxon);
814
						if (logger.isTraceEnabled()) {
815
							logger.trace("Misapplied name taxon (" + misappliedNameUuid + ") added to Set");
816
						}
817
					} else {
818
						if (logger.isDebugEnabled()) {
819
							logger.debug("Duplicated misapplied name taxon (" + misappliedNameUuid + ")");
820
						}
821
					}
822

    
823
				} catch (Exception e) {
824
					logger.error("Error creating misapplied name relationship accepted taxon-misapplied name (" +
825
						mappedAcceptedTaxonUuid + "-" + misappliedNameUuid + ")", e);
826
				}
827

    
828
			}
829
			if (logger.isTraceEnabled()) {
830
				logger.trace("Start saving misappliedNameSet");
831
			}
832
			getTaxonService().save(misappliedNameSet);
833
			if (logger.isTraceEnabled()) {
834
				logger.trace("End saving misappliedNameSet");
835
			}
836

    
837
			acceptedTaxaSet = null;
838
			misappliedNameSet = null;
839
			misappliedNames = null;
840
			acceptedTaxa = null;
841

    
842
		return;
843
	}
844

    
845

    
846
	/* Creates heterotypic synonym relationships.
847
	 * Synonym-accepted taxon pairs are retrieved in blocks via findByUUID(Set<UUID>) from CDM DB.
848
	 */
849
	private void createHeterotypicSynonyms(FaunaEuropaeaImportState state, Map<UUID, UUID> fromToMap) {
850

    
851
		int limit = state.getConfig().getLimitSave();
852

    
853
		Set<TaxonBase> synonymSet = new HashSet<TaxonBase>(limit);
854

    
855
		Set<UUID> synonymUuidSet = fromToMap.keySet();
856
		Set<UUID> acceptedTaxaUuidSet = new HashSet<UUID>(fromToMap.values());
857

    
858
		if (logger.isTraceEnabled()) {
859
			logger.trace("Reading synonym names and accepted taxa...");
860
		}
861
		List<TaxonBase> synonyms = getTaxonService().find(synonymUuidSet);
862
		List<TaxonBase> acceptedTaxa = getTaxonService().find(acceptedTaxaUuidSet);
863
		Map<UUID, TaxonBase> acceptedTaxaMap = new HashMap<UUID, TaxonBase>(acceptedTaxa.size());
864
		for (TaxonBase taxonBase : acceptedTaxa){
865
			acceptedTaxaMap.put(taxonBase.getUuid(), taxonBase);
866
		}
867

    
868
		if (logger.isTraceEnabled()) {
869
			logger.trace("End reading synonyms names and accepted taxa");
870
			for (UUID uuid : synonymUuidSet) {
871
				logger.trace("synonym uuid query: " + uuid);
872
			}
873
			for (UUID uuid : acceptedTaxaUuidSet) {
874
				logger.trace("accepted taxon uuid query: " + uuid);
875
			}
876
			for (TaxonBase tb : synonyms) {
877
				logger.trace("synonym uuid result: " + tb.getUuid());
878
			}
879
			for (TaxonBase tb : acceptedTaxa) {
880
				logger.trace("accepted taxon uuid result: " + tb.getUuid());
881
			}
882
		}
883

    
884
		UUID mappedAcceptedTaxonUuid = null;
885
		UUID synonymUuid = null;
886
		Synonym synonym = null;
887
		TaxonBase acceptedTaxonBase = null;
888
		Taxon acceptedTaxon = null;
889

    
890
		for (TaxonBase synonymTaxonBase : synonyms) {
891

    
892
			try {
893
				//check for misapplied names with nec (in Fauna Europaea they have a synonym relationship to the accepted taxon)
894
				if (synonymTaxonBase instanceof Taxon ){
895
					if (((Taxon)synonymTaxonBase).isMisapplication()){
896
						if (logger.isDebugEnabled()) {
897
							logger.debug("misapplied name with exclusion" +  synonymTaxonBase.getTitleCache());
898
						}
899
					}
900
					continue;
901
				}
902
				synonym = HibernateProxyHelper.deproxy(synonymTaxonBase, Synonym.class);
903
				synonymUuid = synonym.getUuid();
904
				mappedAcceptedTaxonUuid = fromToMap.get(synonymUuid);
905
				acceptedTaxonBase = null;
906

    
907
				acceptedTaxonBase = acceptedTaxaMap.get(mappedAcceptedTaxonUuid);
908
				if (logger.isDebugEnabled()) {
909
					logger.debug("Parent (" + mappedAcceptedTaxonUuid + ") found for child (" + synonymUuid + ")");
910
				}
911
				acceptedTaxon = CdmBase.deproxy(acceptedTaxonBase, Taxon.class);
912

    
913
				if (synonym != null && acceptedTaxon != null) {
914

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

    
918
					if (logger.isDebugEnabled()) {
919
						logger.debug("Accepted taxon - synonym (" + mappedAcceptedTaxonUuid + " - " + synonymUuid +
920
						") relationship created");
921
					}
922
					if (synonym != null && !synonymSet.contains(synonym)) {
923

    
924
						synonymSet.add(synonym);
925

    
926
						if (logger.isTraceEnabled()) {
927
							logger.trace("Synonym (" + synonymUuid + ") added to Set");
928
						}
929

    
930
					} else {
931
						if (logger.isDebugEnabled()) {
932
							logger.debug("Duplicated synonym (" + synonymUuid + ")");
933
						}
934
					}
935
				} else {
936
					if (logger.isDebugEnabled()) {
937
						logger.debug("Accepted taxon (" + mappedAcceptedTaxonUuid + ") or misapplied name (" + synonymUuid + " is null");
938
					}
939
				}
940
			} catch (Exception e) {
941
				logger.error("Error creating synonym relationship: accepted taxon-synonym (" +
942
						mappedAcceptedTaxonUuid + "-" + synonymUuid + ": "+ synonymTaxonBase.getTitleCache() +")", e);
943
			}
944
		}
945
		if (logger.isTraceEnabled()) {
946
			logger.trace("Start saving synonymSet");
947
		}
948
		getTaxonService().save(synonymSet);
949
		if (logger.isTraceEnabled()) {
950
			logger.trace("End saving synonymSet");
951
		}
952

    
953
		acceptedTaxaUuidSet = null;
954
		synonymSet = null;
955
		synonyms = null;
956
		acceptedTaxa = null;
957

    
958
		return;
959
	}
960

    
961
	private void processAssociatedSpecialists(FaunaEuropaeaImportState state){
962
		int limit = state.getConfig().getLimitSave();
963

    
964
		TransactionStatus txStatus = null;
965
		Set<UUID> taxonUuids = new HashSet<UUID>();
966
		Map<UUID, Set<UUID>> agentUUIDTaxonMap = new HashMap<UUID, Set<UUID>>();
967
		FaunaEuropaeaImportConfigurator fauEuConfig = state.getConfig();
968
		Source source = fauEuConfig.getSource();
969
		int i = 0;
970
		UUID agentUuid;
971
		Set<UUID> agentUuids = new HashSet<UUID>();
972
		Set<UUID> taxaOfAgent = new HashSet<UUID>();
973
		String selectCount =
974
			" SELECT count(*) ";
975

    
976

    
977

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

    
981
		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 "
982
						+ " join TAXON taxon on (taxon.TAX_USR_IDSP= user2.USR_ID or taxon.TAX_USR_IDGC= user2.USR_ID) "
983
						+ " where USERROLE.URL_ROL_ID = 7 ";
984
		String orderClause = " ORDER BY taxon.TAX_ID";
985

    
986
		String countQuery =
987
			selectCount + fromClause;
988

    
989
		String selectQuery =
990
			selectColumns + fromClause + orderClause;
991

    
992
		if(logger.isInfoEnabled()) { logger.info("Start making associated specialists..."); }
993

    
994
		try {
995

    
996
			ResultSet rs = source.getResultSet(countQuery);
997
			rs.next();
998
			int count = rs.getInt(1);
999

    
1000
			rs = source.getResultSet(selectQuery);
1001

    
1002
	        if (logger.isInfoEnabled()) {
1003
				logger.info("Number of rows: " + count);
1004
				logger.info("Count Query: " + countQuery);
1005
				logger.info("Select Query: " + selectQuery);
1006
			}
1007
	        String oldTaxonUuidString = null;
1008
	        while (rs.next()) {
1009

    
1010
                if ((i++ % limit) == 0) {
1011
                    txStatus = startTransaction();
1012
                    if(logger.isInfoEnabled()) {
1013
                        logger.info("Associated specialists: " + (i-1));
1014
                    }
1015
                }
1016
                String taxonUUID = rs.getString("tax_uuid");
1017

    
1018
				int userId = rs.getInt("user_id");
1019
				int user2Id = rs.getInt("user2_id");
1020
				String groupName = rs.getString("groupName");
1021

    
1022
				taxonUuids.add(UUID.fromString(taxonUUID));
1023
				agentUuid = state.getAgentMap().get(userId);
1024
				agentUuids.add(agentUuid);
1025
				if (agentUUIDTaxonMap.containsKey(agentUuid)){
1026
				    taxaOfAgent = agentUUIDTaxonMap.get(agentUuid);
1027
				} else{
1028
				    taxaOfAgent = new HashSet<UUID>();
1029
				}
1030
				taxaOfAgent.add(UUID.fromString(taxonUUID));
1031
                agentUUIDTaxonMap.put(agentUuid, taxaOfAgent);
1032

    
1033

    
1034
				 if (((i % limit) == 0 && i != 1 ) || i == count ) {
1035

    
1036
				        createTaxonNodeAgentRealtionships(state, taxonUuids, agentUUIDTaxonMap, agentUuids);
1037
		                commitTransaction(txStatus);
1038
		                agentUUIDTaxonMap.clear();
1039
		                taxonUuids= new HashSet<UUID>();
1040
		                agentUuids=new HashSet<UUID>();
1041
		                if(logger.isInfoEnabled()) {
1042
		                    logger.info("i = " + i + " - Transaction committed");
1043
		                }
1044
		            }
1045

    
1046
	        }
1047
		}catch(SQLException e){
1048
			logger.info("Problems during creating associated specialists.", e);
1049
		}
1050
	}
1051

    
1052
	private void createTaxonNodeAgentRealtionships(FaunaEuropaeaImportState state, Set<UUID> taxonUuids, Map<UUID, Set<UUID>> agentUUIDTaxonMap, Set<UUID> agentUUuids){
1053
	    Taxon taxon = null;
1054
	    TaxonBase taxonBase;
1055
        Synonym syn;
1056
        Set<TaxonNode> nodes = new HashSet<TaxonNode>();
1057
        List<TaxonBase> taxonBases = getTaxonService().find(taxonUuids);
1058
        List<AgentBase> agentBases = getAgentService().find(agentUUuids);
1059
        TeamOrPersonBase associatedSpecialist = null;
1060
        TaxonNodeAgentRelation agentRel = null;
1061

    
1062
        TaxonNode taxonNode;
1063
//        Map<UUID, TeamOrPersonBase> agentsMap = new HashMap<UUID,TeamOrPersonBase>();
1064
//        for (AgentBase agent: agentBases){
1065
//            agentsMap.put(agent.getUuid(), (TeamOrPersonBase) agent);
1066
//        }
1067
        Map<UUID, TaxonBase> taxonMap = new HashMap<UUID,TaxonBase>();
1068
        for (TaxonBase tax: taxonBases){
1069
            taxonMap.put(tax.getUuid(), tax);
1070
        }
1071

    
1072
        for (AgentBase agent: agentBases){
1073
            Set<UUID> taxaUuids = agentUUIDTaxonMap.get(agent.getUuid());
1074
            for (UUID taxonUuid: taxaUuids){
1075
                taxonBase = taxonMap.get(taxonUuid);
1076
                    if (taxonBase instanceof Synonym){
1077
                        logger.debug("synonym has relationship to associated specialist. " + taxonBase.getTitleCache());
1078
                        syn = HibernateProxyHelper.deproxy(taxonBase, Synonym.class);
1079
                        if (!syn.getAcceptedTaxa().isEmpty()){
1080
                            taxon = syn.getAcceptedTaxa().iterator().next();
1081
                            syn = null;
1082
                        }
1083
                    } else{
1084
                        taxon = HibernateProxyHelper.deproxy(taxonBase, Taxon.class);
1085
                    }
1086

    
1087
                    if (taxon != null && !taxon.getTaxonNodes().isEmpty()){
1088
                        taxonNode = taxon.getTaxonNodes().iterator().next();
1089
                    } else {
1090
                        taxonNode = null;
1091
                        logger.debug("There is an associated specialist for a taxon which has no taxonnode.");
1092
                    }
1093

    
1094

    
1095
                    associatedSpecialist = (TeamOrPersonBase)agent;
1096
                    if (associatedSpecialist != null && taxonNode != null){
1097
                        agentRel =taxonNode.addAgentRelation(FaunaEuropaeaTransformer.getAssociateSpecialistType(getTermService()), associatedSpecialist);
1098
                        /*if (!StringUtils.isBlank(groupName)) {
1099
                            agentRel.addAnnotation(Annotation.NewInstance(groupName, Language.DEFAULT()));
1100
                        }*/
1101
                    }
1102

    
1103

    
1104

    
1105
                nodes.add(taxonNode);
1106
              }
1107
            agent = null;
1108
            associatedSpecialist = null;
1109
            taxonNode = null;
1110
        }
1111
        if (!nodes.isEmpty()){
1112
            while (nodes.contains(null)){
1113
                nodes.remove(null);
1114
            }
1115
            getTaxonNodeService().saveOrUpdate(nodes);
1116
            nodes = null;
1117

    
1118
        }
1119
        taxonMap= null;
1120
        agentMap= null;
1121
        taxonBases = null;
1122
        agentBases = null;
1123
       }
1124

    
1125

    
1126

    
1127
	private void processInferredSynonyms(FaunaEuropaeaImportState state){
1128

    
1129
	        int count;
1130
	        int pastCount;
1131
	        boolean success = true;
1132
	        // Get the limit for objects to save within a single transaction.
1133
	        if (! state.getConfig().isDoInferredSynonyms()){
1134
	            logger.info ("Ignore Creating Inferred Synonyms...");
1135
	            return;
1136
	        }
1137

    
1138
	        int limit = state.getConfig().getLimitSave();
1139
	        // Create inferred synonyms for accepted taxa
1140
	        logger.info("Creating Inferred Synonyms...");
1141

    
1142

    
1143
	        count = 0;
1144
	        pastCount = 0;
1145
	        int pageSize = limit/10;
1146
	        int pageNumber = 1;
1147
	        String inferredSynonymPluralString = "Inferred Synonyms";
1148

    
1149
	        // Start transaction
1150
	        TransactionStatus txStatus = startTransaction(true);
1151
	        logger.info("Started new transaction. Fetching some " + parentPluralString + " first (max: " + limit + ") ...");
1152
	        List<TaxonBase> taxonList = null;
1153
	        Set<TaxonBase> synonymList = new HashSet<TaxonBase>();
1154

    
1155

    
1156
	        while ((taxonList  = getTaxonService().listTaxaByName(Taxon.class, "*", "*", "*", "*", Rank.SPECIES(), pageSize, pageNumber)).size() > 0) {
1157
	            HashMap<Integer, TaxonNameBase<?,?>> inferredSynonymsDataToBeSaved = new HashMap<Integer, TaxonNameBase<?,?>>();
1158

    
1159
	            logger.info("Fetched " + taxonList.size() + " " + parentPluralString + ". Importing...");
1160
	            synonymList = createInferredSynonymsForTaxonList(state,  taxonList);
1161
	            getTaxonService().save(synonymList);
1162

    
1163
	          //  getTaxonService().saveOrUpdate(taxonList);
1164
	            // Commit transaction
1165
	            commitTransaction(txStatus);
1166
	            logger.debug("Committed transaction.");
1167
	            logger.info("Imported " + (taxonList.size()) + " " + inferredSynonymPluralString + ". Total: " + count);
1168
	            //pastCount = count;
1169

    
1170

    
1171

    
1172
	            // Start transaction
1173
	            txStatus = startTransaction(true);
1174
	            logger.info("Started new transaction. Fetching some " + parentPluralString + " first (max: " + limit + ") ...");
1175

    
1176
	            // Increment pageNumber
1177
	            pageNumber++;
1178
	        }
1179
	        taxonList = null;
1180
	        while ((taxonList  = getTaxonService().listTaxaByName(Taxon.class, "*", "*", "*", "*", Rank.SUBSPECIES(), pageSize, pageNumber)).size() > 0) {
1181
	            HashMap<Integer, TaxonNameBase<?,?>> inferredSynonymsDataToBeSaved = new HashMap<Integer, TaxonNameBase<?,?>>();
1182

    
1183
	            logger.info("Fetched " + taxonList.size() + " " + parentPluralString  + ". Exporting...");
1184
	            synonymList = createInferredSynonymsForTaxonList(state, taxonList);
1185

    
1186
	            getTaxonService().save(synonymList);
1187
	            // Commit transaction
1188
	            commitTransaction(txStatus);
1189
	            logger.debug("Committed transaction.");
1190
	            logger.info("Exported " + taxonList.size()+ " " + inferredSynonymPluralString + ". Total: " + count);
1191
	            //pastCount = count;
1192

    
1193

    
1194

    
1195
	            // Start transaction
1196
	            txStatus = startTransaction(true);
1197
	            logger.info("Started new transaction. Fetching some " + parentPluralString + " first (max: " + limit + ") ...");
1198

    
1199
	            // Increment pageNumber
1200
	            pageNumber++;
1201
	            inferredSynonymsDataToBeSaved = null;
1202
	        }
1203
	        if (taxonList.size() == 0) {
1204
	            logger.info("No " + parentPluralString + " left to fetch.");
1205
	        }
1206

    
1207
	        taxonList = null;
1208

    
1209
	        // Commit transaction
1210
	        commitTransaction(txStatus);
1211
	        System.gc();
1212

    
1213
	        //ProfilerController.memorySnapshot();
1214
	        logger.debug("Committed transaction.");
1215

    
1216

    
1217
	}
1218

    
1219
	/**
1220
    * @param state
1221
    * @param mapping
1222
    * @param synRelMapping
1223
    * @param currentTaxonId
1224
    * @param taxonList
1225
    * @param inferredSynonymsDataToBeSaved
1226
    * @return
1227
    */
1228
   private Set<TaxonBase> createInferredSynonymsForTaxonList(FaunaEuropaeaImportState state,
1229
            List<TaxonBase> taxonList) {
1230

    
1231
       Taxon acceptedTaxon;
1232
       Classification classification = null;
1233
       Set<TaxonBase> inferredSynonyms = new HashSet<TaxonBase>();
1234
       List<Synonym> inferredSynonymsLocal= new ArrayList<Synonym>();
1235
       boolean localSuccess = true;
1236

    
1237
       HashMap<Integer, TaxonNameBase<?,?>> inferredSynonymsDataToBeSaved = new HashMap<Integer, TaxonNameBase<?,?>>();
1238

    
1239
       for (TaxonBase<?> taxonBase : taxonList) {
1240

    
1241
           if (taxonBase.isInstanceOf(Taxon.class)) { // this should always be the case since we should have fetched accepted taxon only, but you never know...
1242
               acceptedTaxon = CdmBase.deproxy(taxonBase, Taxon.class);
1243
               TaxonNameBase<?,?> taxonName = acceptedTaxon.getName();
1244

    
1245
               if (taxonName.isInstanceOf(ZoologicalName.class)) {
1246
                   Set<TaxonNode> taxonNodes = acceptedTaxon.getTaxonNodes();
1247
                   TaxonNode singleNode = null;
1248

    
1249
                   if (taxonNodes.size() > 0) {
1250
                       // Determine the classification of the current TaxonNode
1251

    
1252
                       singleNode = taxonNodes.iterator().next();
1253
                       if (singleNode != null) {
1254
                           classification = singleNode.getClassification();
1255
                       } else {
1256
                           logger.error("A TaxonNode belonging to this accepted Taxon is NULL: " + acceptedTaxon.getUuid() + " (" + acceptedTaxon.getTitleCache() +")");
1257
                       }
1258
                   } else {
1259
                       // Classification could not be determined directly from this TaxonNode
1260
                       // The stored classification from another TaxonNode is used. It's a simple, but not a failsafe fallback solution.
1261
                       if (taxonNodes.size() == 0) {
1262
                           //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");
1263

    
1264
                       }
1265
                   }
1266

    
1267
                   if (classification != null) {
1268
                       try{
1269
                           TaxonNameBase name = acceptedTaxon.getName();
1270

    
1271
                            //if (name.isSpecies() || name.isInfraSpecific()){
1272
                               inferredSynonymsLocal = getTaxonService().createAllInferredSynonyms(acceptedTaxon, classification, true);
1273
                              // logger.info("number of inferred synonyms: " + inferredSynonyms.size());
1274
                           //}
1275
//                             inferredSynonyms = getTaxonService().createInferredSynonyms(classification, acceptedTaxon, SynonymRelationshipType.INFERRED_GENUS_OF());
1276
                           if (inferredSynonymsLocal != null) {
1277
                               for (TaxonBase synonym : inferredSynonymsLocal) {
1278
//                                 TaxonNameBase<?,?> synonymName = synonym.getName();
1279
                                   MarkerType markerType =getUuidMarkerType(PesiTransformer.uuidMarkerGuidIsMissing, state);
1280

    
1281
                                   synonym.addMarker(Marker.NewInstance(markerType, true));
1282

    
1283

    
1284
                                   //get SynonymRelationship and export
1285
                                   if (((Synonym)synonym).getSynonymRelations().isEmpty() ){
1286
                                       SynonymRelationship synRel;
1287
                                       IdentifiableSource source = ((Synonym)synonym).getSources().iterator().next();
1288
                                       if (source.getIdNamespace().contains("Potential combination")){
1289
                                           synRel = acceptedTaxon.addSynonym((Synonym)synonym, SynonymRelationshipType.POTENTIAL_COMBINATION_OF());
1290
                                           logger.error(synonym.getTitleCache() + " has no synonym relationship to " + acceptedTaxon.getTitleCache() + " type is set to potential combination");
1291
                                       } else if (source.getIdNamespace().contains("Inferred Genus")){
1292
                                           synRel = acceptedTaxon.addSynonym((Synonym)synonym, SynonymRelationshipType.INFERRED_GENUS_OF());
1293
                                           logger.error(synonym.getTitleCache() + " has no synonym relationship to " + acceptedTaxon.getTitleCache() + " type is set to inferred genus");
1294
                                       } else if (source.getIdNamespace().contains("Inferred Epithet")){
1295
                                           synRel = acceptedTaxon.addSynonym((Synonym)synonym, SynonymRelationshipType.INFERRED_EPITHET_OF());
1296
                                           logger.error(synonym.getTitleCache() + " has no synonym relationship to " + acceptedTaxon.getTitleCache() + " type is set to inferred epithet");
1297
                                       } else{
1298
                                           synRel = acceptedTaxon.addSynonym((Synonym)synonym, SynonymRelationshipType.INFERRED_SYNONYM_OF());
1299
                                           logger.error(synonym.getTitleCache() + " has no synonym relationship to " + acceptedTaxon.getTitleCache() + " type is set to inferred synonym");
1300
                                       }
1301

    
1302

    
1303

    
1304
                                       synRel = null;
1305
                                   } else {
1306
                                       for (SynonymRelationship synRel: ((Synonym)synonym).getSynonymRelations()){
1307
                                           if (!localSuccess) {
1308
                                               logger.error("Synonym relationship export failed " + synonym.getTitleCache() + " accepted taxon: " + acceptedTaxon.getUuid() + " (" + acceptedTaxon.getTitleCache()+")");
1309
                                           } else {
1310
                                              // logger.info("Synonym relationship successfully exported: " + synonym.getTitleCache() + "  " +acceptedTaxon.getUuid() + " (" + acceptedTaxon.getTitleCache()+")");
1311
                                           }
1312
                                           synRel = null;
1313
                                       }
1314
                                   }
1315

    
1316
                                   inferredSynonymsDataToBeSaved.put(synonym.getId(), synonym.getName());
1317
                               }
1318

    
1319
                               inferredSynonyms.addAll(inferredSynonymsLocal);
1320
                              //logger.info("inferredSet: " + inferredSet.size());
1321
                               //getTaxonService().save(inferredSynonyms);
1322
                               //commitTransaction(txStatus);
1323

    
1324
                               inferredSynonymsLocal = null;
1325

    
1326
                           }
1327

    
1328

    
1329
                       }catch(Exception e){
1330
                           logger.error(e.getMessage());
1331
                           e.printStackTrace();
1332
                       }
1333
                   } else {
1334
                       logger.error("Classification is NULL. Inferred Synonyms could not be created for this Taxon: " + acceptedTaxon.getUuid() + " (" + acceptedTaxon.getTitleCache() + ")");
1335
                   }
1336
               } else {
1337
//                         logger.error("TaxonName is not a ZoologicalName: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
1338
               }
1339
           } else {
1340
               logger.error("This TaxonBase is not a Taxon even though it should be: " + taxonBase.getUuid() + " (" + taxonBase.getTitleCache() + ")");
1341
           }
1342
       }
1343
       //getTaxonService().saveOrUpdate(taxonList);
1344
       taxonList = null;
1345
       return inferredSynonyms;
1346
   }
1347

    
1348

    
1349
}
(13-13/20)