Project

General

Profile

Download (26.4 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.berlinModel.in;
11

    
12
import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.TAX_REL_IS_HETEROTYPIC_SYNONYM_OF;
13
import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.TAX_REL_IS_HOMOTYPIC_SYNONYM_OF;
14
import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.TAX_REL_IS_INCLUDED_IN;
15
import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.TAX_REL_IS_MISAPPLIED_NAME_OF;
16
import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.TAX_REL_IS_PARTIAL_HETEROTYPIC_SYNONYM_OF;
17
import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.TAX_REL_IS_PARTIAL_HOMOTYPIC_SYNONYM_OF;
18
import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.TAX_REL_IS_PARTIAL_SYN_OF;
19
import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.TAX_REL_IS_PROPARTE_HETEROTYPIC_SYNONYM_OF;
20
import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.TAX_REL_IS_PROPARTE_HOMOTYPIC_SYNONYM_OF;
21
import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.TAX_REL_IS_PROPARTE_SYN_OF;
22
import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.TAX_REL_IS_SYNONYM_OF;
23

    
24
import java.sql.ResultSet;
25
import java.sql.SQLException;
26
import java.util.HashMap;
27
import java.util.HashSet;
28
import java.util.Map;
29
import java.util.Set;
30
import java.util.UUID;
31

    
32
import org.apache.commons.lang.StringUtils;
33
import org.apache.log4j.Logger;
34
import org.springframework.stereotype.Component;
35
import org.springframework.transaction.TransactionStatus;
36

    
37
import eu.etaxonomy.cdm.common.ResultWrapper;
38
import eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer;
39
import eu.etaxonomy.cdm.io.berlinModel.in.validation.BerlinModelTaxonRelationImportValidator;
40
import eu.etaxonomy.cdm.io.common.IOValidator;
41
import eu.etaxonomy.cdm.io.common.ResultSetPartitioner;
42
import eu.etaxonomy.cdm.io.common.Source;
43
import eu.etaxonomy.cdm.model.common.AnnotatableEntity;
44
import eu.etaxonomy.cdm.model.common.CdmBase;
45
import eu.etaxonomy.cdm.model.common.IdentifiableSource;
46
import eu.etaxonomy.cdm.model.reference.Reference;
47
import eu.etaxonomy.cdm.model.taxon.Classification;
48
import eu.etaxonomy.cdm.model.taxon.Synonym;
49
import eu.etaxonomy.cdm.model.taxon.SynonymRelationship;
50
import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;
51
import eu.etaxonomy.cdm.model.taxon.Taxon;
52
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
53
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
54
import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
55
import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
56
import eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException;
57

    
58
/**
59
 * @author a.mueller
60
 * @created 20.03.2008
61
 */
62
@Component
63
public class BerlinModelTaxonRelationImport  extends BerlinModelImportBase  {
64
	private static final Logger logger = Logger.getLogger(BerlinModelTaxonRelationImport.class);
65

    
66
	public static final String TREE_NAMESPACE = "PTRefFk";
67

    
68
	private static int modCount = 30000;
69
	private static final String pluralString = "taxon relations";
70
	private static final String dbTableName = "RelPTaxon";
71

    
72

    
73
	public BerlinModelTaxonRelationImport(){
74
		super(dbTableName, pluralString);
75
	}
76

    
77
	/**
78
	 * Creates a classification for each PTaxon reference which belongs to a taxon that is included at least in one
79
	 * <i>taxonomically included</i> relationship
80
	 * @param state
81
	 * @return
82
	 * @throws SQLException
83
	 */
84
	private void makeClassifications(BerlinModelImportState state) throws SQLException{
85
		logger.info("start make classification ...");
86

    
87
		Set<String> idSet = getTreeReferenceIdSet(state);
88

    
89
		//reference map
90
		String nameSpace = BerlinModelReferenceImport.REFERENCE_NAMESPACE;
91
		Class<?> cdmClass = Reference.class;
92
		Map<String, Reference> refMap = (Map<String, Reference>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
93

    
94
		String treeName = "Classification - No Name";
95

    
96
		ResultSet rs = state.getConfig().getSource().getResultSet(getClassificationQuery(state)) ;
97
		int i = 0;
98
		//for each reference
99
		try {
100
			//TODO handle case useSingleClassification = true && sourceSecId = null, which returns no record
101
			while (rs.next()){
102

    
103
				try {
104
					if ((i++ % modCount) == 0 && i!= 1 ){ logger.info("RelPTaxa handled: " + (i-1));}
105

    
106
					Integer ptRefFkInt = nullSafeInt(rs,"PTRefFk");
107
					String ptRefFk= String.valueOf(ptRefFkInt);
108
					Reference<?> ref = refMap.get(ptRefFk);
109

    
110
					String refCache = rs.getString("RefCache");
111
					if (StringUtils.isNotBlank(refCache)){
112
						treeName = refCache;
113
					}
114
					if (ref != null && StringUtils.isNotBlank(ref.getTitleCache())){
115
						treeName = ref.getTitleCache();
116
					}
117
					Classification tree = Classification.NewInstance(treeName);
118
					tree.setReference(ref);
119
					if (i == 1 && state.getConfig().getClassificationUuid() != null){
120
						tree.setUuid(state.getConfig().getClassificationUuid());
121
					}
122
					IdentifiableSource identifiableSource = IdentifiableSource.NewDataImportInstance(ptRefFk, TREE_NAMESPACE);
123
					tree.addSource(identifiableSource);
124

    
125
					getClassificationService().save(tree);
126
					state.putClassificationUuidInt(ptRefFkInt, tree);
127
				} catch (Exception e) {
128
					logger.error("Error in BerlinModleTaxonRelationImport.makeClassifications: " + e.getMessage());
129
					e.printStackTrace();
130
				}
131
			}
132
		} catch (SQLException e) {
133
			logger.error("Error in BerlinModleTaxonRelationImport.makeClassifications: " + e.getMessage());
134
			throw e;
135
		}
136
		logger.info("end make classification ...");
137

    
138
		return;
139
	}
140

    
141
	/**
142
	 * @return
143
	 * @throws SQLException
144
	 */
145
	private Set<String> getTreeReferenceIdSet(BerlinModelImportState state) throws SQLException {
146
		Source source = state.getConfig().getSource();
147
		Set<String> result = new HashSet<String>();
148
		ResultSet rs = source.getResultSet(getClassificationQuery(state)) ;
149
		while (rs.next()){
150
			Object id = rs.getObject("PTRefFk");
151
			result.add(String.valueOf(id));
152
		}
153
		return result;
154
	}
155

    
156
	/**
157
	 * @return
158
	 */
159
	private String getClassificationQuery(BerlinModelImportState state) {
160
		boolean includeAllClassifications = state.getConfig().isIncludeAllNonMisappliedRelatedClassifications();
161
		String strQuerySelect = "SELECT PTaxon.PTRefFk, r.RefCache ";
162
		String strQueryFrom = " FROM RelPTaxon " +
163
							" INNER JOIN PTaxon AS PTaxon ON RelPTaxon.PTNameFk2 = PTaxon.PTNameFk AND RelPTaxon.PTRefFk2 = PTaxon.PTRefFk " +
164
							" INNER JOIN Reference r ON PTaxon.PTRefFk = r.RefId ";
165
		String strQueryWhere = " WHERE (RelPTaxon.RelQualifierFk = 1) ";
166
		if (includeAllClassifications){
167
			strQueryWhere = " WHERE (RelPTaxon.RelQualifierFk <> 3) ";
168
		}else{
169
			if (state.getConfig().isUseSingleClassification()){
170
				if (state.getConfig().getSourceSecId()!= null){
171
					strQueryWhere += " AND PTaxon.PTRefFk = " + state.getConfig().getSourceSecId() +  " ";
172
				}else{
173
					strQueryWhere += " AND (1=0) ";
174
				}
175
			}
176
		}
177

    
178
		String strQueryGroupBy = " GROUP BY PTaxon.PTRefFk, r.RefCache ";
179
		String strQuery = strQuerySelect + " " + strQueryFrom + " " + strQueryWhere + " " + strQueryGroupBy;
180

    
181

    
182
		if (includeAllClassifications){
183
			//add otherdirection
184
			strQuerySelect = "SELECT PTaxon.PTRefFk, r.RefCache ";
185
			strQueryFrom = " FROM RelPTaxon rel " +
186
								" INNER JOIN PTaxon AS PTaxon ON rel.PTNameFk1 = PTaxon.PTNameFk AND rel.PTRefFk1 = PTaxon.PTRefFk " +
187
								" INNER JOIN Reference r ON PTaxon.PTRefFk = r.RefId ";
188
			strQueryWhere =" WHERE (rel.RelQualifierFk <> 3) ";
189
			String strAllQuery =  strQuerySelect + " " + strQueryFrom + " " + strQueryWhere + " " + strQueryGroupBy;
190
			strQuery = strQuery + " UNION " + strAllQuery;
191
		}
192

    
193

    
194

    
195
		boolean includeFlatClassifications = state.getConfig().isIncludeFlatClassifications();
196
		//concepts with
197
		if (includeFlatClassifications){
198
			String strFlatQuery =
199
					" SELECT pt.PTRefFk AS secRefFk, r.RefCache AS secRef " +
200
					" FROM PTaxon AS pt LEFT OUTER JOIN " +
201
					          " Reference r ON pt.PTRefFk = r.RefId LEFT OUTER JOIN " +
202
					          " RelPTaxon rel1 ON pt.PTNameFk = rel1.PTNameFk2 AND pt.PTRefFk = rel1.PTRefFk2 LEFT OUTER JOIN " +
203
					          " RelPTaxon AS rel2 ON pt.PTNameFk = rel2.PTNameFk1 AND pt.PTRefFk = rel2.PTRefFk1 " +
204
					" WHERE (rel2.RelQualifierFk IS NULL) AND (rel1.RelQualifierFk IS NULL) " +
205
					" GROUP BY pt.PTRefFk, r.RefCache "
206
					;
207

    
208
			strQuery = strQuery + " UNION " + strFlatQuery;
209
		}
210

    
211

    
212

    
213
		if (state.getConfig().getClassificationQuery() != null){
214
			strQuery = state.getConfig().getClassificationQuery();
215
		}
216
		return strQuery;
217
	}
218

    
219
	@Override
220
	protected String getRecordQuery(BerlinModelImportConfigurator config) {
221
		String strQuery =
222
			" SELECT RelPTaxon.*, FromTaxon.RIdentifier as taxon1Id, ToTaxon.RIdentifier as taxon2Id, ToTaxon.PTRefFk as treeRefFk, FromTaxon.PTRefFk as fromRefFk, q.is_concept_relation " +
223
			" FROM PTaxon as FromTaxon " +
224
              	" INNER JOIN RelPTaxon ON FromTaxon.PTNameFk = RelPTaxon.PTNameFk1 AND FromTaxon.PTRefFk = RelPTaxon.PTRefFk1 " +
225
              	" INNER JOIN PTaxon AS ToTaxon ON RelPTaxon.PTNameFk2 = ToTaxon.PTNameFk AND RelPTaxon.PTRefFk2 = ToTaxon.PTRefFk " +
226
              	" INNER JOIN RelPTQualifier q ON q.RelPTQualifierId = RelPTaxon.RelQualifierFk " +
227
            " WHERE RelPTaxon.RelPTaxonId IN ("+ID_LIST_TOKEN+") ORDER BY RelPTaxon.RelPTaxonId ";
228
		return strQuery;
229
	}
230

    
231
	@Override
232
	public boolean doPartition(ResultSetPartitioner partitioner, BerlinModelImportState state) {
233
		boolean success = true ;
234
		BerlinModelImportConfigurator config = state.getConfig();
235
		Set<TaxonBase> taxaToSave = new HashSet<TaxonBase>();
236
		Map<String, TaxonBase> taxonMap = partitioner.getObjectMap(BerlinModelTaxonImport.NAMESPACE);
237
		Map<Integer, Classification> classificationMap = new HashMap<Integer, Classification>();
238
		Map<String, Reference> refMap = partitioner.getObjectMap(BerlinModelReferenceImport.REFERENCE_NAMESPACE);
239

    
240
		ResultSet rs = partitioner.getResultSet();
241

    
242
		try{
243
			int i = 0;
244
			//for each reference
245
			while (rs.next()){
246

    
247
				if ((i++ % modCount) == 0 && i!= 1 ){ logger.info("RelPTaxa handled: " + (i-1));}
248

    
249
				int relPTaxonId = rs.getInt("RelPTaxonId");
250
				Integer taxon1Id = nullSafeInt(rs, "taxon1Id");
251
				Integer taxon2Id = nullSafeInt(rs, "taxon2Id");
252
				try {
253
					Integer relRefFk = nullSafeInt(rs,"relRefFk");
254
					int treeRefFk = rs.getInt("treeRefFk");
255
					int fromRefFk = rs.getInt("fromRefFk");
256

    
257
					int relQualifierFk = rs.getInt("relQualifierFk");
258
					String notes = rs.getString("notes");
259
					boolean isConceptRelationship = rs.getBoolean("is_concept_relation");
260

    
261
					TaxonBase<?> taxon1 = taxonMap.get(String.valueOf(taxon1Id));
262
					TaxonBase<?> taxon2 = taxonMap.get(String.valueOf(taxon2Id));
263

    
264
					String refFk = String.valueOf(relRefFk);
265
					Reference<?> citation = refMap.get(refFk);
266

    
267
					String microcitation = null; //does not exist in RelPTaxon
268

    
269
					if (taxon2 != null && taxon1 != null){
270
						if (!(taxon2 instanceof Taxon)){
271
							logger.error("ToTaxon (ID = " + taxon2.getId()+ ", RIdentifier = " + taxon2Id + ") can't be casted to Taxon. RelPTaxon: " + relPTaxonId );
272
							success = false;
273
							continue;
274
						}
275
						AnnotatableEntity taxonRelationship = null;
276
						Taxon toTaxon = (Taxon)taxon2;
277
						if (isTaxonRelationship(relQualifierFk)){
278
							if (!(taxon1 instanceof Taxon)){
279
								logger.error("TaxonBase (ID = " + taxon1.getId()+ ", RIdentifier = " + taxon1Id + ") for TaxonRelation ("+relPTaxonId+") can't be casted to Taxon");
280
								success = false;
281
								continue;
282
							}
283
							Taxon fromTaxon = (Taxon)taxon1;
284
							if (relQualifierFk == TAX_REL_IS_INCLUDED_IN){
285
								taxonRelationship = makeTaxonomicallyIncluded(state, classificationMap, treeRefFk, fromTaxon, toTaxon, citation, microcitation);
286
							}else if (relQualifierFk == TAX_REL_IS_MISAPPLIED_NAME_OF){
287
								 taxonRelationship = toTaxon.addMisappliedName(fromTaxon, citation, microcitation);
288
							}else{
289
								handleAllRelatedTaxa(state, fromTaxon, classificationMap, fromRefFk);
290
								handleAllRelatedTaxa(state, toTaxon, classificationMap, treeRefFk);
291
								logger.warn("Unhandled taxon relationship: RelId:" + relPTaxonId + "; QualifierId: " + relQualifierFk);
292
							}
293
						}else if (isSynonymRelationship(relQualifierFk)){
294
							if (!(taxon1 instanceof Synonym)){
295
								logger.warn("Validated: Taxon (ID = " + taxon1.getId()+ ", RIdentifier = " + taxon1Id + ") can't be casted to Synonym");
296
								success = false;
297
								continue;
298
							}
299
							handleAllRelatedTaxa(state, toTaxon, classificationMap, treeRefFk);
300
							Synonym synonym = (Synonym)taxon1;
301
							SynonymRelationship synRel = getSynRel(relQualifierFk, toTaxon, synonym, citation, microcitation);
302
							taxonRelationship = synRel;
303

    
304
							if (relQualifierFk == TAX_REL_IS_SYNONYM_OF ||
305
									relQualifierFk == TAX_REL_IS_HOMOTYPIC_SYNONYM_OF ||
306
									relQualifierFk == TAX_REL_IS_HETEROTYPIC_SYNONYM_OF){
307
								addProParteAndPartial(synRel, synonym, config);
308
							}else if (relQualifierFk == TAX_REL_IS_PROPARTE_SYN_OF ||
309
									relQualifierFk == TAX_REL_IS_PROPARTE_HOMOTYPIC_SYNONYM_OF ||
310
									relQualifierFk == TAX_REL_IS_PROPARTE_HETEROTYPIC_SYNONYM_OF ){
311
									synRel.setProParte(true);
312
							}else if(relQualifierFk == TAX_REL_IS_PARTIAL_SYN_OF ||
313
									relQualifierFk == TAX_REL_IS_PARTIAL_HOMOTYPIC_SYNONYM_OF ||
314
									relQualifierFk == TAX_REL_IS_PARTIAL_HETEROTYPIC_SYNONYM_OF ){
315
									synRel.setPartial(true);
316
							}else{
317
								success = false;
318
								logger.warn("Proparte/Partial not yet implemented for TaxonRelationShipType " + relQualifierFk);
319
							}
320
						}else if (isConceptRelationship){
321
							ResultWrapper<Boolean> isInverse = ResultWrapper.NewInstance(false);
322
							ResultWrapper<Boolean> isDoubtful = ResultWrapper.NewInstance(false);
323
							try {
324
								TaxonRelationshipType relType = BerlinModelTransformer.taxonRelId2TaxonRelType(relQualifierFk, isInverse, isDoubtful);
325

    
326
								if (! (taxon1 instanceof Taxon)){
327
									success = false;
328
									logger.error("TaxonBase (ID = " + taxon1.getId()+ ", RIdentifier = " + taxon1Id + ") can't be casted to Taxon");
329
								}else{
330
									Taxon fromTaxon = (Taxon)taxon1;
331
									if (isInverse.getValue() == true){
332
										Taxon tmp = fromTaxon;
333
										fromTaxon = toTaxon;
334
										toTaxon = tmp;
335
									}
336
									taxonRelationship = fromTaxon.addTaxonRelation(toTaxon, relType, citation, microcitation);
337
									handleAllRelatedTaxa(state, toTaxon, classificationMap, treeRefFk);
338
									handleAllRelatedTaxa(state, fromTaxon, classificationMap, fromRefFk);
339
									if (isDoubtful.getValue() == true){
340
										((TaxonRelationship)taxonRelationship).setDoubtful(true);
341
									}
342
								}
343
							} catch (UnknownCdmTypeException e) {
344
								logger.warn("TaxonRelationShipType " + relQualifierFk + " (conceptRelationship) not yet implemented");
345
								success = false;
346
							}
347
						}else {
348
							logger.warn("TaxonRelationShipType " + relQualifierFk + " not yet implemented: RelPTaxonId = " + relPTaxonId );
349
							success = false;
350
						}
351

    
352
						doNotes(taxonRelationship, notes);
353
						taxaToSave.add(taxon2);
354

    
355
						//TODO
356
						//etc.
357
					}else{
358
						if (taxon2 != null && taxon1 == null){
359
							logger.warn("First taxon ("+taxon1Id+") for RelPTaxon " + relPTaxonId + " does not exist in store. RelType: " + relQualifierFk);
360
						}else if (taxon2 == null && taxon1 != null){
361
							logger.warn("Second taxon ("+taxon2Id +") for RelPTaxon " + relPTaxonId + " does not exist in store. RelType: " + relQualifierFk);
362
						}else{
363
							logger.warn("Both taxa ("+taxon1Id+","+taxon2Id +") for RelPTaxon " + relPTaxonId + " do not exist in store. RelType: " + relQualifierFk);
364
						}
365

    
366
						success = false;
367
					}
368
				} catch (Exception e) {
369
					logger.error("Exception occurred when trying to handle taxon relationship " + relPTaxonId + " (" + taxon1Id + ","+ taxon2Id + "): " + e.getMessage());
370
					e.printStackTrace();
371
				}
372
			}
373
		}catch(SQLException e){
374
			throw new RuntimeException(e);
375
		}
376
		logger.info("Taxa to save: " + taxaToSave.size());
377
		partitioner.startDoSave();
378
		getTaxonService().saveOrUpdate(taxaToSave);
379
		classificationMap = null;
380
		taxaToSave = null;
381

    
382
		return success;
383
	}
384

    
385

    
386
	private void handleAllRelatedTaxa(BerlinModelImportState state, Taxon taxon, Map<Integer, Classification> classificationMap, Integer secRefFk) {
387
		if (taxon.getTaxonNodes().size() > 0){
388
			return;
389
		}else{
390
			Classification classification = getClassificationTree(state, classificationMap, secRefFk);
391
			classification.addChildTaxon(taxon, null, null);
392
		}
393
	}
394

    
395
	@Override
396
	protected void doInvoke(BerlinModelImportState state){
397
		try {
398
			makeClassifications(state);
399
			super.doInvoke(state);
400
			makeFlatClassificationTaxa(state);
401
			return;
402
		} catch (SQLException e) {
403
			throw new RuntimeException(e);
404
		}
405

    
406
	}
407

    
408

    
409
	private void makeFlatClassificationTaxa(BerlinModelImportState state) {
410
		//Note: this part still does not use partitions
411
		logger.info("Flat classifications start");
412
		TransactionStatus txStatus = startTransaction();
413
		if (! state.getConfig().isIncludeFlatClassifications()){
414
			return;
415
		}
416
		String sql = " SELECT pt.PTRefFk AS secRefFk, pt.RIdentifier " +
417
						" FROM PTaxon AS pt " +
418
							" LEFT OUTER JOIN RelPTaxon ON pt.PTNameFk = RelPTaxon.PTNameFk2 AND pt.PTRefFk = RelPTaxon.PTRefFk2 " +
419
							"  LEFT OUTER JOIN RelPTaxon AS RelPTaxon_1 ON pt.PTNameFk = RelPTaxon_1.PTNameFk1 AND pt.PTRefFk = RelPTaxon_1.PTRefFk1 " +
420
						" WHERE (RelPTaxon_1.RelQualifierFk IS NULL) AND (dbo.RelPTaxon.RelQualifierFk IS NULL) " +
421
						" ORDER BY pt.PTRefFk "	;
422
		ResultSet rs = state.getConfig().getSource().getResultSet(sql);
423
		Map<Object, Map<String, ? extends CdmBase>> maps = getRelatedObjectsForFlatPartition(rs);
424

    
425
		Map<String, TaxonBase> taxonMap = (Map<String, TaxonBase>) maps.get(BerlinModelTaxonImport.NAMESPACE);
426
		Map<Integer, Classification> classificationMap = new HashMap<Integer, Classification>();
427

    
428
		rs = state.getConfig().getSource().getResultSet(sql);
429
		try {
430
			while (rs.next()){
431
				Integer treeRefFk = rs.getInt("secRefFk");
432
				String taxonId = rs.getString("RIdentifier");
433
				Classification classification = getClassificationTree(state, classificationMap, treeRefFk);
434
				TaxonBase<?> taxon = taxonMap.get(taxonId);
435
				if (taxon == null){
436
					String message = "TaxonBase for taxon id (%s) not found in taxonMap";
437
					logger.warn(String.format(message, taxonId, taxonId));
438
				}else if (taxon.isInstanceOf(Taxon.class)){
439
					classification.addChildTaxon(CdmBase.deproxy(taxon, Taxon.class), null, null);
440
				}else{
441
					String message = "TaxonBase for taxon is not of class Taxon but %s (RIdentifier %s)";
442
					logger.warn(String.format(message, taxon.getClass(), taxonId));
443
				}
444
			}
445
		} catch (SQLException e) {
446
			// TODO Auto-generated catch block
447
			e.printStackTrace();
448
		}
449
		commitTransaction(txStatus);
450
		logger.info("Flat classifications end");
451

    
452
	}
453

    
454
	@Override
455
	protected String getIdQuery(BerlinModelImportState state) {
456
		if (state.getConfig().getRelTaxaIdQuery() != null){
457
			return state.getConfig().getRelTaxaIdQuery();
458
		}else{
459
			return super.getIdQuery(state);
460
		}
461
	}
462

    
463
	@Override
464
	public Map<Object, Map<String, ? extends CdmBase>> getRelatedObjectsForPartition( ResultSet rs, BerlinModelImportState state) {
465
		String nameSpace;
466
		Class<?> cdmClass;
467
		Set<String> idSet;
468
		Map<Object, Map<String, ? extends CdmBase>> result = new HashMap<Object, Map<String, ? extends CdmBase>>();
469

    
470
		try{
471
			Set<String> taxonIdSet = new HashSet<String>();
472
			Set<String> referenceIdSet = new HashSet<String>();
473
//			Set<String> classificationIdSet = new HashSet<String>();
474
			while (rs.next()){
475
				handleForeignKey(rs, taxonIdSet, "taxon1Id");
476
				handleForeignKey(rs, taxonIdSet, "taxon2Id");
477
//				handleForeignKey(rs, classificationIdSet, "treeRefFk");
478
				handleForeignKey(rs, referenceIdSet, "RelRefFk");
479
	}
480

    
481
			//taxon map
482
			nameSpace = BerlinModelTaxonImport.NAMESPACE;
483
			cdmClass = TaxonBase.class;
484
			idSet = taxonIdSet;
485
			Map<String, TaxonBase> taxonMap = (Map<String, TaxonBase>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
486
			result.put(nameSpace, taxonMap);
487

    
488
//			//tree map
489
//			nameSpace = "Classification";
490
//			cdmClass = Classification.class;
491
//			idSet = classificationIdSet;
492
//			Map<String, Classification> treeMap = (Map<String, Classification>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
493
//			result.put(cdmClass, treeMap);
494
//			Set<UUID> treeUuidSet = state
495
//			getClassificationService().find(uuidSet);
496
//
497
			//reference map
498
			nameSpace = BerlinModelReferenceImport.REFERENCE_NAMESPACE;
499
			cdmClass = Reference.class;
500
			idSet = referenceIdSet;
501
			Map<String, Reference> referenceMap = (Map<String, Reference>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
502
			result.put(nameSpace, referenceMap);
503

    
504
		} catch (SQLException e) {
505
			throw new RuntimeException(e);
506
		}
507
		return result;
508
	}
509

    
510

    
511
	private Map<Object, Map<String, ? extends CdmBase>> getRelatedObjectsForFlatPartition( ResultSet rs) {
512
		String nameSpace;
513
		Class cdmClass;
514
		Set<String> idSet;
515
		Map<Object, Map<String, ? extends CdmBase>> result = new HashMap<Object, Map<String, ? extends CdmBase>>();
516

    
517
		try{
518
			Set<String> taxonIdSet = new HashSet<String>();
519
			Set<String> referenceIdSet = new HashSet<String>();
520
//			Set<String> classificationIdSet = new HashSet<String>();
521
			while (rs.next()){
522
				handleForeignKey(rs, taxonIdSet, "RIdentifier");
523
//				handleForeignKey(rs, classificationIdSet, "treeRefFk");
524
	}
525

    
526
			//taxon map
527
			nameSpace = BerlinModelTaxonImport.NAMESPACE;
528
			cdmClass = TaxonBase.class;
529
			idSet = taxonIdSet;
530
			Map<String, TaxonBase> taxonMap = (Map<String, TaxonBase>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
531
			result.put(nameSpace, taxonMap);
532

    
533
//			//tree map
534
//			nameSpace = "Classification";
535
//			cdmClass = Classification.class;
536
//			idSet = classificationIdSet;
537
//			Map<String, Classification> treeMap = (Map<String, Classification>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
538
//			result.put(cdmClass, treeMap);
539
//			Set<UUID> treeUuidSet = state
540
//			getClassificationService().find(uuidSet);
541
//
542

    
543
		} catch (SQLException e) {
544
			throw new RuntimeException(e);
545
		}
546
		return result;
547
	}
548

    
549

    
550
	private SynonymRelationship getSynRel (int relQualifierFk, Taxon toTaxon, Synonym synonym, Reference citation, String microcitation){
551
		SynonymRelationship result;
552
		if (relQualifierFk == TAX_REL_IS_HOMOTYPIC_SYNONYM_OF ||
553
				relQualifierFk == TAX_REL_IS_PROPARTE_HOMOTYPIC_SYNONYM_OF ||
554
				relQualifierFk == TAX_REL_IS_PARTIAL_HOMOTYPIC_SYNONYM_OF){
555
			result = toTaxon.addHomotypicSynonym(synonym, citation, microcitation);
556
		}else if (relQualifierFk == TAX_REL_IS_HETEROTYPIC_SYNONYM_OF ||
557
				relQualifierFk == TAX_REL_IS_PROPARTE_HETEROTYPIC_SYNONYM_OF ||
558
				relQualifierFk == TAX_REL_IS_PARTIAL_HETEROTYPIC_SYNONYM_OF){
559
			result = toTaxon.addSynonym(synonym, SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF(), citation, microcitation);
560
		}else if (relQualifierFk == TAX_REL_IS_SYNONYM_OF ||
561
				relQualifierFk == TAX_REL_IS_PROPARTE_SYN_OF ||
562
				relQualifierFk == TAX_REL_IS_PARTIAL_SYN_OF){
563
			result = toTaxon.addSynonym(synonym, SynonymRelationshipType.SYNONYM_OF(), citation, microcitation);
564
		}else{
565
			logger.warn("SynonymyRelationShipType could not be defined for relQualifierFk " + relQualifierFk + ". 'Unknown'-Type taken instead.");
566
			result = toTaxon.addSynonym(synonym, SynonymRelationshipType.SYNONYM_OF(), citation, microcitation);
567
		}
568
		return result;
569

    
570
	}
571

    
572
	private  boolean isSynonymRelationship(int relQualifierFk){
573
		if (relQualifierFk == TAX_REL_IS_SYNONYM_OF ||
574
			relQualifierFk == TAX_REL_IS_HOMOTYPIC_SYNONYM_OF ||
575
			relQualifierFk == TAX_REL_IS_HETEROTYPIC_SYNONYM_OF ||
576
			relQualifierFk == TAX_REL_IS_PROPARTE_SYN_OF ||
577
			relQualifierFk == TAX_REL_IS_PARTIAL_SYN_OF ||
578
			relQualifierFk == TAX_REL_IS_PROPARTE_HOMOTYPIC_SYNONYM_OF ||
579
			relQualifierFk == TAX_REL_IS_PROPARTE_HETEROTYPIC_SYNONYM_OF ||
580
			relQualifierFk == TAX_REL_IS_PARTIAL_HOMOTYPIC_SYNONYM_OF ||
581
			relQualifierFk == TAX_REL_IS_PARTIAL_HETEROTYPIC_SYNONYM_OF
582
		){
583
			return true;
584
		}else{
585
			return false;
586
		}
587
	}
588

    
589
	private  boolean isTaxonRelationship(int relQualifierFk){
590
		if (relQualifierFk == TAX_REL_IS_INCLUDED_IN ||
591
				relQualifierFk == TAX_REL_IS_MISAPPLIED_NAME_OF){
592
			return true;
593
		}else{
594
			return false;
595
		}
596
	}
597

    
598
	private void addProParteAndPartial(SynonymRelationship synRel, Synonym synonym, BerlinModelImportConfigurator bmiConfig){
599
		if (bmiConfig.isPartialSynonym(synonym)){
600
			synRel.setPartial(true);
601
		}
602
		if (bmiConfig.isProParteSynonym(synonym)){
603
			synRel.setProParte(true);
604
		}
605
	}
606

    
607
	private TaxonNode makeTaxonomicallyIncluded(BerlinModelImportState state, Map<Integer, Classification> classificationMap, int treeRefFk, Taxon child, Taxon parent, Reference citation, String microCitation){
608
		Classification tree = getClassificationTree(state, classificationMap, treeRefFk);
609
		return tree.addParentChild(parent, child, citation, microCitation);
610
	}
611

    
612
	private Classification getClassificationTree(BerlinModelImportState state, Map<Integer, Classification> classificationMap, int treeRefFk) {
613
		if (state.getConfig().isUseSingleClassification()){
614
			if (state.getConfig().getSourceSecId() != null){
615
				treeRefFk = (Integer)state.getConfig().getSourceSecId();
616
			}else{
617
				treeRefFk = 1;
618
			}
619

    
620
		}
621
		Classification tree = classificationMap.get(treeRefFk);
622
		if (tree == null){
623
			UUID treeUuid = state.getTreeUuidByIntTreeKey(treeRefFk);
624
			tree = getClassificationService().find(treeUuid);
625
			classificationMap.put(treeRefFk, tree);
626
		}
627
		if (tree == null){
628
			throw new IllegalStateException("Tree for ToTaxon reference " + treeRefFk + " does not exist.");
629
		}
630
		return tree;
631
	}
632

    
633
	@Override
634
	protected boolean doCheck(BerlinModelImportState state){
635
		IOValidator<BerlinModelImportState> validator = new BerlinModelTaxonRelationImportValidator();
636
		return validator.validate(state);
637
	}
638

    
639
	@Override
640
	protected boolean isIgnore(BerlinModelImportState state){
641
		return ! state.getConfig().isDoRelTaxa();
642
	}
643

    
644

    
645
}
(17-17/21)