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

    
69
	private Map<UUID, TeamOrPersonBase> agentMap = new HashMap<UUID, TeamOrPersonBase>();
70

    
71

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

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

    
86
		return result;
87
	}
88

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

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

    
108
	@Override
109
	protected void doInvoke(FaunaEuropaeaImportState state) {
110

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

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

    
123
		if(logger.isInfoEnabled()) { logger.info("Start making relationships..."); }
124

    
125

    
126

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

    
131
		Classification tree = getClassificationFor(state, sourceRef);
132
		commitTransaction(txStatus);
133

    
134
		logger.warn("Before processParentsChildren " + state.getConfig().isDoTaxonomicallyIncluded());
135

    
136
		//ProfilerController.memorySnapshot();
137

    
138
		if (state.getConfig().isDoTaxonomicallyIncluded())  {
139
			processParentsChildren(state);
140

    
141
		}
142
		if (state.getConfig().isDoAssociatedSpecialists()){
143
			processAssociatedSpecialists(state);
144
		}
145

    
146
		logger.warn("Before processMissappliedNames " + state.getConfig().isDoMisappliedNames());
147

    
148
		//ProfilerController.memorySnapshot();
149

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

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

    
173
		return;
174
	}
175

    
176
	/**
177
     * @param state
178
     */
179
    private void createAgentMap(FaunaEuropaeaImportState state) {
180

    
181

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

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

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

    
194

    
195
            state.getAgentMap().put(idInSource, agentUuid);
196
        }
197
    }
198

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

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

    
204
		TransactionStatus txStatus = null;
205

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

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

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

    
217
		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";
218

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

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

    
225
		String countQuery =
226
			selectCount + fromClause;
227

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

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

    
233
		try {
234

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

    
239
			rs = source.getResultSet(selectQuery);
240

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

    
247
	        while (rs.next()) {
248

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

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

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

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

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

    
272
						childParentMap.put(childUuid, parentUuid);
273

    
274

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

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

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

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

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

    
297

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

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

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

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

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

    
331

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

    
336

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

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

    
342
		TransactionStatus txStatus = null;
343

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

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

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

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

    
359

    
360

    
361

    
362
		String countQuery =
363
			selectCount + fromClause;
364

    
365
		String selectQuery =
366
			selectColumns + fromClause + orderClause;
367

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

    
370
		try {
371

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

    
376
			rs = source.getResultSet(selectQuery);
377

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

    
384
			while (rs.next()) {
385

    
386
				if ((i++ % limit) == 0) {
387

    
388
					txStatus = startTransaction();
389
					childParentMap = new HashMap<UUID, UUID>(limit);
390

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

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

    
401
				if (!childParentMap.containsKey(childUuid)) {
402

    
403
						childParentMap.put(childUuid, parentUuid);
404

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

    
411
				if (((i % limit) == 0 && i != 1 ) || i == count) {
412

    
413
					createAndCommitMisappliedNameRelationships(state, txStatus,
414
							childParentMap);
415
					childParentMap = null;
416

    
417

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

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

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

    
444

    
445

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

    
449
		FaunaEuropaeaImportConfigurator fauEuConfig = state.getConfig();
450
		Source source = fauEuConfig.getSource();
451

    
452
		String selectCount =
453
			" SELECT count(*) ";
454

    
455
		String selectColumns = " SELECT Taxon.UUID AS SynonymUuid, Parent.UUID AS AcceptedUuid ";
456

    
457
		String orderClause = " ORDER BY dbo.Taxon.TAX_RNK_ID ASC ";
458

    
459
		String countQuery =
460
			selectCount + fromClause;
461

    
462
		String selectQuery =
463
			selectColumns + fromClause + orderClause;
464
		logger.debug(selectQuery);
465

    
466
		try {
467

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

    
472
			rs = source.getResultSet(selectQuery);
473

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

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

    
489

    
490

    
491

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

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

    
500
		while (rs.next()) {
501

    
502
			if ((i++ % limit) == 0) {
503

    
504
				txStatus = startTransaction();
505
				synonymAcceptedMap = new HashMap<UUID, UUID>(limit);
506

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

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

    
517
			if (!synonymAcceptedMap.containsKey(synonymUuid)) {
518

    
519
				synonymAcceptedMap.put(synonymUuid, acceptedUuid);
520

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

    
527
			if (((i % limit) == 0 && i != 1 ) || i == count ) {
528

    
529
				synonymAcceptedMap = createAndCommitHeterotypicSynonyms(state,
530
						txStatus, synonymAcceptedMap);
531

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

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

    
550
		synonymAcceptedMap = null;
551
		commitTransaction(txStatus);
552
		return synonymAcceptedMap;
553
	}
554

    
555

    
556

    
557

    
558

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

    
568
		Classification tree = getClassificationFor(state, sourceRef);
569

    
570
		Set<TaxonBase> childSet = new HashSet<TaxonBase>(limit);
571

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

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

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

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

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

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

    
630
				Taxon parentTaxon = parent.deproxy(parent, Taxon.class);
631

    
632
				if (childTaxon != null && parentTaxon != null) {
633

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

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

    
651

    
652
					agentUuid = taxonGroupCoordinatorMap.get(childTaxon.getUuid());
653
					groupCoordinator = agentMap.get(agentUuid);
654

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

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

    
675
						childSet.add(childTaxon);
676

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

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

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

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

    
702
		getTaxonService().saveOrUpdate(childSet);
703

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

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

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

    
722
		//gets the taxon "Hydroscaphidae" (family)
723

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

    
728
			Set<TaxonBase> misappliedNameSet = new HashSet<TaxonBase>(limit);
729

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

    
733
			if (logger.isTraceEnabled()) {
734
				logger.trace("Start reading misapplied names and accepted taxa");
735
			}
736
			List<TaxonBase> misappliedNames = getTaxonService().find(misappliedNamesSet);
737
			List<TaxonBase> acceptedTaxa = getTaxonService().find(acceptedTaxaSet);
738
			Map<UUID, TaxonBase> acceptedTaxaMap = new HashMap<UUID, TaxonBase>(acceptedTaxa.size());
739
			for (TaxonBase taxonBase : acceptedTaxa){
740
				acceptedTaxaMap.put(taxonBase.getUuid(), taxonBase);
741
			}
742

    
743
			if (logger.isTraceEnabled()) {
744
				logger.info("End reading misapplied names and accepted taxa");
745
				for (UUID uuid : misappliedNamesSet) {
746
					logger.trace("misapplied name uuid query: " + uuid);
747
				}
748
				for (UUID uuid : acceptedTaxaSet) {
749
					logger.trace("accepted taxon uuid query: " + uuid);
750
				}
751
				for (TaxonBase tb : misappliedNames) {
752
					logger.trace("misapplied name uuid result: " + tb.getUuid());
753
				}
754
				for (TaxonBase tb : acceptedTaxa) {
755
					logger.trace("accepted taxon uuid result: " + tb.getUuid());
756
				}
757
			}
758

    
759
			UUID mappedAcceptedTaxonUuid = null;
760
			UUID misappliedNameUuid = null;
761
			Taxon misappliedNameTaxon = null;
762
			TaxonBase acceptedTaxonBase = null;
763
			Taxon acceptedTaxon = null;
764

    
765
			for (TaxonBase misappliedName : misappliedNames) {
766

    
767
				try {
768

    
769
					misappliedNameTaxon = misappliedName.deproxy(misappliedName, Taxon.class);
770
					misappliedName.setAppendedPhrase(AUCT_STRING);
771

    
772
					misappliedNameUuid = misappliedNameTaxon.getUuid();
773
					mappedAcceptedTaxonUuid = fromToMap.get(misappliedNameUuid);
774
					acceptedTaxonBase = null;
775

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

    
781
							acceptedTaxon = acceptedTaxonBase.deproxy(acceptedTaxonBase, Taxon.class);
782

    
783
					if (misappliedNameTaxon != null && acceptedTaxon != null) {
784

    
785
						acceptedTaxon.addMisappliedName(misappliedNameTaxon, sourceRef, null);
786

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

    
793
							misappliedNameSet.add(misappliedNameTaxon);
794

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

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

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

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

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

    
835
			acceptedTaxaSet = null;
836
			misappliedNameSet = null;
837
			misappliedNames = null;
838
			acceptedTaxa = null;
839

    
840
		return;
841
	}
842

    
843

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

    
849
		int limit = state.getConfig().getLimitSave();
850

    
851
		Set<TaxonBase> synonymSet = new HashSet<TaxonBase>(limit);
852

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

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

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

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

    
888
		for (TaxonBase synonymTaxonBase : synonyms) {
889

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

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

    
911
				if (synonym != null && acceptedTaxon != null) {
912

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

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

    
922
						synonymSet.add(synonym);
923

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

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

    
951
		acceptedTaxaUuidSet = null;
952
		synonymSet = null;
953
		synonyms = null;
954
		acceptedTaxa = null;
955

    
956
		return;
957
	}
958

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

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

    
974

    
975

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

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

    
984
		String countQuery =
985
			selectCount + fromClause;
986

    
987
		String selectQuery =
988
			selectColumns + fromClause + orderClause;
989

    
990
		if(logger.isInfoEnabled()) { logger.info("Start making associated specialists..."); }
991

    
992
		try {
993

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

    
998
			rs = source.getResultSet(selectQuery);
999

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

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

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

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

    
1031

    
1032
				 if (((i % limit) == 0 && i != 1 ) || i == count ) {
1033

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

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

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

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

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

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

    
1092

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

    
1101

    
1102

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

    
1116
        }
1117
        taxonMap= null;
1118
        agentMap= null;
1119
        taxonBases = null;
1120
        agentBases = null;
1121
       }
1122

    
1123

    
1124

    
1125
	private void processInferredSynonyms(FaunaEuropaeaImportState state){
1126

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

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

    
1140

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

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

    
1153

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

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

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

    
1168

    
1169

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

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

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

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

    
1191

    
1192

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

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

    
1205
	        taxonList = null;
1206

    
1207
	        // Commit transaction
1208
	        commitTransaction(txStatus);
1209
	        System.gc();
1210

    
1211
	        //ProfilerController.memorySnapshot();
1212
	        logger.debug("Committed transaction.");
1213

    
1214

    
1215
	}
1216

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

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

    
1235
       HashMap<Integer, TaxonName> inferredSynonymsDataToBeSaved = new HashMap<>();
1236

    
1237
       for (TaxonBase<?> taxonBase : taxonList) {
1238

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

    
1243
               if (taxonName.isZoological()) {
1244
                   Set<TaxonNode> taxonNodes = acceptedTaxon.getTaxonNodes();
1245
                   TaxonNode singleNode = null;
1246

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

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

    
1262
                       }
1263
                   }
1264

    
1265
                   if (classification != null) {
1266
                       try{
1267
                           TaxonName name = acceptedTaxon.getName();
1268

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

    
1279
                                   synonym.addMarker(Marker.NewInstance(markerType, true));
1280

    
1281

    
1282
                                   //get SynonymRelationship and export
1283
                                   if (((Synonym)synonym).getAcceptedTaxon() == null ){
1284
                                       IdentifiableSource source = ((Synonym)synonym).getSources().iterator().next();
1285
                                       if (source.getIdNamespace().contains("Potential combination")){
1286
                                           acceptedTaxon.addSynonym((Synonym)synonym, SynonymType.POTENTIAL_COMBINATION_OF());
1287
                                           logger.error(synonym.getTitleCache() + " is not attached to " + acceptedTaxon.getTitleCache() + " type is set to potential combination");
1288
                                       } else if (source.getIdNamespace().contains("Inferred Genus")){
1289
                                           acceptedTaxon.addSynonym((Synonym)synonym, SynonymType.INFERRED_GENUS_OF());
1290
                                           logger.error(synonym.getTitleCache() + " is not attached to " + acceptedTaxon.getTitleCache() + " type is set to inferred genus");
1291
                                       } else if (source.getIdNamespace().contains("Inferred Epithet")){
1292
                                           acceptedTaxon.addSynonym((Synonym)synonym, SynonymType.INFERRED_EPITHET_OF());
1293
                                           logger.error(synonym.getTitleCache() + " is not attached to " + acceptedTaxon.getTitleCache() + " type is set to inferred epithet");
1294
                                       } else{
1295
                                           acceptedTaxon.addSynonym((Synonym)synonym, SynonymType.INFERRED_SYNONYM_OF());
1296
                                           logger.error(synonym.getTitleCache() + " is not attached to " + acceptedTaxon.getTitleCache() + " type is set to inferred synonym");
1297
                                       }
1298

    
1299
                                   } else {
1300
                                       if (!localSuccess) {
1301
                                           logger.error("Synonym relationship export failed " + synonym.getTitleCache() + " accepted taxon: " + acceptedTaxon.getUuid() + " (" + acceptedTaxon.getTitleCache()+")");
1302
                                       } else {
1303
                                          // logger.info("Synonym relationship successfully exported: " + synonym.getTitleCache() + "  " +acceptedTaxon.getUuid() + " (" + acceptedTaxon.getTitleCache()+")");
1304
                                       }
1305
                                   }
1306

    
1307
                                   inferredSynonymsDataToBeSaved.put(synonym.getId(), synonym.getName());
1308
                               }
1309

    
1310
                               inferredSynonyms.addAll(inferredSynonymsLocal);
1311
                              //logger.info("inferredSet: " + inferredSet.size());
1312
                               //getTaxonService().save(inferredSynonyms);
1313
                               //commitTransaction(txStatus);
1314

    
1315
                               inferredSynonymsLocal = null;
1316

    
1317
                           }
1318

    
1319

    
1320
                       }catch(Exception e){
1321
                           logger.error(e.getMessage());
1322
                           e.printStackTrace();
1323
                       }
1324
                   } else {
1325
                       logger.error("Classification is NULL. Inferred Synonyms could not be created for this Taxon: " + acceptedTaxon.getUuid() + " (" + acceptedTaxon.getTitleCache() + ")");
1326
                   }
1327
               } else {
1328
//                         logger.error("TaxonName is not a ZoologicalName: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
1329
               }
1330
           } else {
1331
               logger.error("This TaxonBase is not a Taxon even though it should be: " + taxonBase.getUuid() + " (" + taxonBase.getTitleCache() + ")");
1332
           }
1333
       }
1334
       //getTaxonService().saveOrUpdate(taxonList);
1335
       taxonList = null;
1336
       return inferredSynonyms;
1337
   }
1338

    
1339

    
1340
}
(13-13/20)