Project

General

Profile

Download (49.2 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.SynonymType;
47
import eu.etaxonomy.cdm.model.taxon.Taxon;
48
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
49
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
50
//import eu.etaxonomy.cdm.profiler.ProfilerController;
51
import eu.etaxonomy.cdm.model.taxon.TaxonNodeAgentRelation;
52

    
53

    
54

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

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

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

    
72

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

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

    
87
		return result;
88
	}
89

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

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

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

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

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

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

    
126

    
127

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

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

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

    
137
		//ProfilerController.memorySnapshot();
138

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

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

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

    
149
		//ProfilerController.memorySnapshot();
150

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

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

    
174
		return;
175
	}
176

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

    
182

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

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

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

    
195

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

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

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

    
205
		TransactionStatus txStatus = null;
206

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

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

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

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

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

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

    
226
		String countQuery =
227
			selectCount + fromClause;
228

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

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

    
234
		try {
235

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

    
240
			rs = source.getResultSet(selectQuery);
241

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

    
248
	        while (rs.next()) {
249

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

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

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

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

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

    
273
						childParentMap.put(childUuid, parentUuid);
274

    
275

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

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

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

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

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

    
298

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

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

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

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

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

    
332

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

    
337

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

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

    
343
		TransactionStatus txStatus = null;
344

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

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

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

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

    
360

    
361

    
362

    
363
		String countQuery =
364
			selectCount + fromClause;
365

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

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

    
371
		try {
372

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

    
377
			rs = source.getResultSet(selectQuery);
378

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

    
385
			while (rs.next()) {
386

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

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

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

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

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

    
404
						childParentMap.put(childUuid, parentUuid);
405

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

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

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

    
418

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

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

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

    
445

    
446

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

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

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

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

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

    
460
		String countQuery =
461
			selectCount + fromClause;
462

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

    
467
		try {
468

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

    
473
			rs = source.getResultSet(selectQuery);
474

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

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

    
490

    
491

    
492

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

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

    
501
		while (rs.next()) {
502

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

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

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

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

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

    
520
				synonymAcceptedMap.put(synonymUuid, acceptedUuid);
521

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

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

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

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

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

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

    
556

    
557

    
558

    
559

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

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

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

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

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

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

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

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

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

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

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

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

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

    
652

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

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

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

    
676
						childSet.add(childTaxon);
677

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

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

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

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

    
703
		getTaxonService().saveOrUpdate(childSet);
704

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

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

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

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

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

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

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

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

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

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

    
766
			for (TaxonBase misappliedName : misappliedNames) {
767

    
768
				try {
769

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

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

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

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

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

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

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

    
794
							misappliedNameSet.add(misappliedNameTaxon);
795

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

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

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

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

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

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

    
841
		return;
842
	}
843

    
844

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

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

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

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

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

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

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

    
889
		for (TaxonBase synonymTaxonBase : synonyms) {
890

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

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

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

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

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

    
923
						synonymSet.add(synonym);
924

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

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

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

    
957
		return;
958
	}
959

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

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

    
975

    
976

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

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

    
985
		String countQuery =
986
			selectCount + fromClause;
987

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

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

    
993
		try {
994

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

    
999
			rs = source.getResultSet(selectQuery);
1000

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

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

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

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

    
1032

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

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

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

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

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

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

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

    
1093

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

    
1102

    
1103

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

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

    
1124

    
1125

    
1126
	private void processInferredSynonyms(FaunaEuropaeaImportState state){
1127

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

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

    
1141

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

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

    
1154

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

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

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

    
1169

    
1170

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

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

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

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

    
1192

    
1193

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

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

    
1206
	        taxonList = null;
1207

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

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

    
1215

    
1216
	}
1217

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

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

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

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

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

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

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

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

    
1263
                       }
1264
                   }
1265

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

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

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

    
1282

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

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

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

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

    
1316
                               inferredSynonymsLocal = null;
1317

    
1318
                           }
1319

    
1320

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

    
1340

    
1341
}
(13-13/20)