Project

General

Profile

Download (26.7 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 = (Map<String, TaxonBase>) partitioner.getObjectMap(BerlinModelTaxonImport.NAMESPACE);
237
		Map<Integer, Classification> classificationMap = new HashMap<Integer, Classification>();
238
		Map<String, Reference> refMap = (Map<String, Reference>)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
								//TODO other relationships
345
								logger.warn("TaxonRelationShipType " + relQualifierFk + " (conceptRelationship) not yet implemented");
346
								success = false;
347
							}
348
						}else {
349
							//TODO
350
							logger.warn("TaxonRelationShipType " + relQualifierFk + " not yet implemented: RelPTaxonId = " + relPTaxonId );
351
							success = false;
352
						}
353
						
354
						doNotes(taxonRelationship, notes);
355
						taxaToSave.add(taxon2);
356
						
357
						//TODO
358
						//etc.
359
					}else{
360
						if (taxon2 != null && taxon1 == null){
361
							logger.warn("First taxon ("+taxon1Id+") for RelPTaxon " + relPTaxonId + " does not exist in store. RelType: " + relQualifierFk);
362
						}else if (taxon2 == null && taxon1 != null){
363
							logger.warn("Second taxon ("+taxon2Id +") for RelPTaxon " + relPTaxonId + " does not exist in store. RelType: " + relQualifierFk);
364
						}else{
365
							logger.warn("Both taxa ("+taxon1Id+","+taxon2Id +") for RelPTaxon " + relPTaxonId + " do not exist in store. RelType: " + relQualifierFk);
366
						}
367
						
368
						success = false;
369
					}
370
				} catch (Exception e) {
371
					logger.error("Exception occurred when trying to handle taxon relationship " + relPTaxonId + " (" + taxon1Id + ","+ taxon2Id + "): " + e.getMessage());
372
//					e.printStackTrace();
373
				}
374
			}
375
		}catch(SQLException e){
376
			throw new RuntimeException(e);
377
		}
378
		logger.info("Taxa to save: " + taxaToSave.size());
379
		partitioner.startDoSave();
380
		getTaxonService().saveOrUpdate(taxaToSave);
381
		classificationMap = null;
382
		taxaToSave = null;
383
			
384
		return success;
385
	}
386
	
387

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

    
397
	@Override
398
	protected void doInvoke(BerlinModelImportState state){				
399
		try {
400
			makeClassifications(state);
401
			super.doInvoke(state);
402
			makeFlatClassificationTaxa(state);
403
			return;
404
		} catch (SQLException e) {
405
			throw new RuntimeException(e);
406
		}
407
		
408
	}
409
	
410
	
411
	private void makeFlatClassificationTaxa(BerlinModelImportState state) {
412
		//Note: this part still does not use partitions
413
		logger.info("Flat classifications start");
414
		TransactionStatus txStatus = startTransaction();
415
		if (! state.getConfig().isIncludeFlatClassifications()){
416
			return;
417
		}
418
		String sql = " SELECT pt.PTRefFk AS secRefFk, pt.RIdentifier " +
419
						" FROM PTaxon AS pt " +
420
							" LEFT OUTER JOIN RelPTaxon ON pt.PTNameFk = RelPTaxon.PTNameFk2 AND pt.PTRefFk = RelPTaxon.PTRefFk2 " +
421
							"  LEFT OUTER JOIN RelPTaxon AS RelPTaxon_1 ON pt.PTNameFk = RelPTaxon_1.PTNameFk1 AND pt.PTRefFk = RelPTaxon_1.PTRefFk1 " +
422
						" WHERE (RelPTaxon_1.RelQualifierFk IS NULL) AND (dbo.RelPTaxon.RelQualifierFk IS NULL) " +
423
						" ORDER BY pt.PTRefFk "	;
424
		ResultSet rs = state.getConfig().getSource().getResultSet(sql);
425
		Map<Object, Map<String, ? extends CdmBase>> maps = getRelatedObjectsForFlatPartition(rs);
426
		
427
		Map<String, TaxonBase> taxonMap = (Map<String, TaxonBase>) maps.get(BerlinModelTaxonImport.NAMESPACE);
428
		Map<Integer, Classification> classificationMap = new HashMap<Integer, Classification>();
429
				
430
		rs = state.getConfig().getSource().getResultSet(sql);
431
		try {
432
			while (rs.next()){
433
				Integer treeRefFk = rs.getInt("secRefFk");
434
				String taxonId = rs.getString("RIdentifier");
435
				Classification classification = getClassificationTree(state, classificationMap, treeRefFk);
436
				TaxonBase<?> taxon = taxonMap.get(taxonId);
437
				if (taxon == null){
438
					String message = "TaxonBase for taxon id (%s) not found in taxonMap";
439
					logger.warn(String.format(message, taxonId, taxonId));
440
				}else if (taxon.isInstanceOf(Taxon.class)){
441
					classification.addChildTaxon(CdmBase.deproxy(taxon, Taxon.class), null, null);
442
				}else{
443
					String message = "TaxonBase for taxon is not of class Taxon but %s (RIdentifier %s)";
444
					logger.warn(String.format(message, taxon.getClass(), taxonId));
445
				}
446
			}
447
		} catch (SQLException e) {
448
			// TODO Auto-generated catch block
449
			e.printStackTrace();
450
		}
451
		commitTransaction(txStatus);
452
		logger.info("Flat classifications end");
453
		
454
	}
455

    
456
	@Override
457
	protected String getIdQuery(BerlinModelImportState state) {
458
		if (state.getConfig().getRelTaxaIdQuery() != null){
459
			return state.getConfig().getRelTaxaIdQuery();
460
		}else{
461
			return super.getIdQuery(state);
462
		}
463
	}
464
	
465
	@Override
466
	public Map<Object, Map<String, ? extends CdmBase>> getRelatedObjectsForPartition( ResultSet rs, BerlinModelImportState state) {
467
		String nameSpace;
468
		Class<?> cdmClass;
469
		Set<String> idSet;
470
		Map<Object, Map<String, ? extends CdmBase>> result = new HashMap<Object, Map<String, ? extends CdmBase>>();
471
		
472
		try{
473
			Set<String> taxonIdSet = new HashSet<String>();
474
			Set<String> referenceIdSet = new HashSet<String>();
475
//			Set<String> classificationIdSet = new HashSet<String>();
476
			while (rs.next()){
477
				handleForeignKey(rs, taxonIdSet, "taxon1Id");
478
				handleForeignKey(rs, taxonIdSet, "taxon2Id");
479
//				handleForeignKey(rs, classificationIdSet, "treeRefFk");
480
				handleForeignKey(rs, referenceIdSet, "RelRefFk");
481
	}
482
	
483
			//taxon map
484
			nameSpace = BerlinModelTaxonImport.NAMESPACE;
485
			cdmClass = TaxonBase.class;
486
			idSet = taxonIdSet;
487
			Map<String, TaxonBase> taxonMap = (Map<String, TaxonBase>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
488
			result.put(nameSpace, taxonMap);
489

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

    
506
		} catch (SQLException e) {
507
			throw new RuntimeException(e);
508
		}
509
		return result;
510
	}
511
	
512

    
513
	private Map<Object, Map<String, ? extends CdmBase>> getRelatedObjectsForFlatPartition( ResultSet rs) {
514
		String nameSpace;
515
		Class cdmClass;
516
		Set<String> idSet;
517
		Map<Object, Map<String, ? extends CdmBase>> result = new HashMap<Object, Map<String, ? extends CdmBase>>();
518
		
519
		try{
520
			Set<String> taxonIdSet = new HashSet<String>();
521
			Set<String> referenceIdSet = new HashSet<String>();
522
//			Set<String> classificationIdSet = new HashSet<String>();
523
			while (rs.next()){
524
				handleForeignKey(rs, taxonIdSet, "RIdentifier");
525
//				handleForeignKey(rs, classificationIdSet, "treeRefFk");
526
	}
527
	
528
			//taxon map
529
			nameSpace = BerlinModelTaxonImport.NAMESPACE;
530
			cdmClass = TaxonBase.class;
531
			idSet = taxonIdSet;
532
			Map<String, TaxonBase> taxonMap = (Map<String, TaxonBase>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
533
			result.put(nameSpace, taxonMap);
534

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

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

    
551

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

    
572
	}
573
	
574
	private  boolean isSynonymRelationship(int relQualifierFk){
575
		if (relQualifierFk == TAX_REL_IS_SYNONYM_OF || 
576
			relQualifierFk == TAX_REL_IS_HOMOTYPIC_SYNONYM_OF || 
577
			relQualifierFk == TAX_REL_IS_HETEROTYPIC_SYNONYM_OF ||
578
			relQualifierFk == TAX_REL_IS_PROPARTE_SYN_OF || 
579
			relQualifierFk == TAX_REL_IS_PARTIAL_SYN_OF ||
580
			relQualifierFk == TAX_REL_IS_PROPARTE_HOMOTYPIC_SYNONYM_OF ||
581
			relQualifierFk == TAX_REL_IS_PROPARTE_HETEROTYPIC_SYNONYM_OF ||
582
			relQualifierFk == TAX_REL_IS_PARTIAL_HOMOTYPIC_SYNONYM_OF ||
583
			relQualifierFk == TAX_REL_IS_PARTIAL_HETEROTYPIC_SYNONYM_OF
584
		){
585
			return true;
586
		}else{
587
			return false;
588
		}
589
	}
590
	
591
	private  boolean isTaxonRelationship(int relQualifierFk){
592
		if (relQualifierFk == TAX_REL_IS_INCLUDED_IN || 
593
				relQualifierFk == TAX_REL_IS_MISAPPLIED_NAME_OF){
594
			return true;
595
		}else{
596
			return false;
597
		}
598
	}
599
	
600
	private void addProParteAndPartial(SynonymRelationship synRel, Synonym synonym, BerlinModelImportConfigurator bmiConfig){
601
		if (bmiConfig.isPartialSynonym(synonym)){
602
			synRel.setPartial(true);
603
		}
604
		if (bmiConfig.isProParteSynonym(synonym)){
605
			synRel.setProParte(true);
606
		}
607
	}
608
	
609
	private TaxonNode makeTaxonomicallyIncluded(BerlinModelImportState state, Map<Integer, Classification> classificationMap, int treeRefFk, Taxon child, Taxon parent, Reference citation, String microCitation){
610
		Classification tree = getClassificationTree(state, classificationMap, treeRefFk);
611
		return tree.addParentChild(parent, child, citation, microCitation);
612
	}
613

    
614
	private Classification getClassificationTree(BerlinModelImportState state, Map<Integer, Classification> classificationMap, int treeRefFk) {
615
		if (state.getConfig().isUseSingleClassification()){
616
			if (state.getConfig().getSourceSecId() != null){
617
				treeRefFk = (Integer)state.getConfig().getSourceSecId();	
618
			}else{
619
				treeRefFk = 1;
620
			}
621
			
622
		}
623
		Classification tree = classificationMap.get(treeRefFk);
624
		if (tree == null){
625
			UUID treeUuid = state.getTreeUuidByIntTreeKey(treeRefFk);
626
			tree = getClassificationService().find(treeUuid);
627
			classificationMap.put(treeRefFk, tree);
628
		}
629
		if (tree == null){
630
			throw new IllegalStateException("Tree for ToTaxon reference " + treeRefFk + " does not exist.");
631
		}
632
		return tree;
633
	}
634
	
635
	@Override
636
	protected boolean doCheck(BerlinModelImportState state){
637
		IOValidator<BerlinModelImportState> validator = new BerlinModelTaxonRelationImportValidator();
638
		return validator.validate(state);
639
	}
640
	
641
	@Override
642
	protected boolean isIgnore(BerlinModelImportState state){
643
		return ! state.getConfig().isDoRelTaxa();
644
	}
645

    
646
	
647
}
(17-17/21)