Project

General

Profile

Download (26.5 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.Synonym;
48
import eu.etaxonomy.cdm.model.taxon.SynonymRelationship;
49
import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;
50
import eu.etaxonomy.cdm.model.taxon.Taxon;
51
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
52
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
53
import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
54
import eu.etaxonomy.cdm.model.taxon.Classification;
55
import eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException;
56

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

    
65
	public static final String TREE_NAMESPACE = "PTRefFk";
66
	
67
	private static int modCount = 30000;
68
	private static final String pluralString = "taxon relations";
69
	private static final String dbTableName = "RelPTaxon";
70

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

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

    
88
		//reference map
89
		String nameSpace = BerlinModelReferenceImport.REFERENCE_NAMESPACE;
90
		Class<?> cdmClass = Reference.class;
91
		Map<String, Reference> refMap = (Map<String, Reference>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
92
		
93
		String treeName = "Classification - No Name";
94
		
95
		ResultSet rs = state.getConfig().getSource().getResultSet(getClassificationQuery(state)) ;
96
		int i = 0;
97
		//for each reference
98
		try {
99
			//TODO handle case useSingleClassification = true && sourceSecId = null, which returns no record
100
			while (rs.next()){
101
				
102
				try {
103
					if ((i++ % modCount) == 0 && i!= 1 ){ logger.info("RelPTaxa handled: " + (i-1));}
104
					
105
					Integer ptRefFkInt = nullSafeInt(rs,"PTRefFk");
106
					String ptRefFk= String.valueOf(ptRefFkInt);
107
					Reference<?> ref = refMap.get(ptRefFk);
108
					
109
					String refCache = rs.getString("RefCache");
110
					if (StringUtils.isNotBlank(refCache)){
111
						treeName = refCache;
112
					}
113
					if (ref != null && StringUtils.isNotBlank(ref.getTitleCache())){
114
						treeName = ref.getTitleCache();
115
					}
116
					Classification tree = Classification.NewInstance(treeName);
117
					tree.setReference(ref);
118
					if (i == 1 && state.getConfig().getClassificationUuid() != null){
119
						tree.setUuid(state.getConfig().getClassificationUuid());
120
					}
121
					IdentifiableSource identifiableSource = IdentifiableSource.NewDataImportInstance(ptRefFk, TREE_NAMESPACE);
122
					tree.addSource(identifiableSource);
123
					
124
					getClassificationService().save(tree);
125
					state.putClassificationUuidInt(ptRefFkInt, tree);
126
				} catch (Exception e) {
127
					logger.error("Error in BerlinModleTaxonRelationImport.makeClassifications: " + e.getMessage());
128
					e.printStackTrace();
129
				}
130
			}
131
		} catch (SQLException e) {
132
			logger.error("Error in BerlinModleTaxonRelationImport.makeClassifications: " + e.getMessage());
133
			throw e;
134
		}
135
		logger.info("end make classification ...");
136

    
137
		return;
138
	}
139

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

    
155
	/**
156
	 * @return
157
	 */
158
	private String getClassificationQuery(BerlinModelImportState state) {
159
		boolean includeAllClassifications = state.getConfig().isIncludeAllNonMisappliedRelatedClassifications();
160
		String strQuerySelect = "SELECT PTaxon.PTRefFk, r.RefCache ";  
161
		String strQueryFrom = " FROM RelPTaxon " + 
162
							" INNER JOIN PTaxon AS PTaxon ON RelPTaxon.PTNameFk2 = PTaxon.PTNameFk AND RelPTaxon.PTRefFk2 = PTaxon.PTRefFk " +
163
							" INNER JOIN Reference r ON PTaxon.PTRefFk = r.RefId "; 
164
		String strQueryWhere = " WHERE (RelPTaxon.RelQualifierFk = 1) "; 
165
		if (includeAllClassifications){
166
			strQueryWhere = " WHERE (RelPTaxon.RelQualifierFk <> 3) ";
167
		}else{
168
			if (state.getConfig().isUseSingleClassification()){
169
				if (state.getConfig().getSourceSecId()!= null){
170
					strQueryWhere += " AND PTaxon.PTRefFk = " + state.getConfig().getSourceSecId() +  " ";
171
				}else{
172
					strQueryWhere += " AND (1=0) ";
173
				}
174
			}
175
		}
176
		
177
		String strQueryGroupBy = " GROUP BY PTaxon.PTRefFk, r.RefCache ";
178
		String strQuery = strQuerySelect + " " + strQueryFrom + " " + strQueryWhere + " " + strQueryGroupBy;
179
		
180
		
181
		if (includeAllClassifications){
182
			//add otherdirection
183
			strQuerySelect = "SELECT PTaxon.PTRefFk, r.RefCache ";  
184
			strQueryFrom = " FROM RelPTaxon rel " + 
185
								" INNER JOIN PTaxon AS PTaxon ON rel.PTNameFk1 = PTaxon.PTNameFk AND rel.PTRefFk1 = PTaxon.PTRefFk " +
186
								" INNER JOIN Reference r ON PTaxon.PTRefFk = r.RefId "; 
187
			strQueryWhere =" WHERE (rel.RelQualifierFk <> 3) ";
188
			String strAllQuery =  strQuerySelect + " " + strQueryFrom + " " + strQueryWhere + " " + strQueryGroupBy;
189
			strQuery = strQuery + " UNION " + strAllQuery;
190
		}
191
		
192
		
193
		
194
		boolean includeFlatClassifications = state.getConfig().isIncludeFlatClassifications();
195
		//concepts with 
196
		if (includeFlatClassifications){
197
			String strFlatQuery = 
198
					" SELECT pt.PTRefFk AS secRefFk, r.RefCache AS secRef " +
199
					" FROM PTaxon AS pt LEFT OUTER JOIN " + 
200
					          " Reference r ON pt.PTRefFk = r.RefId LEFT OUTER JOIN " +
201
					          " RelPTaxon rel1 ON pt.PTNameFk = rel1.PTNameFk2 AND pt.PTRefFk = rel1.PTRefFk2 LEFT OUTER JOIN " +
202
					          " RelPTaxon AS rel2 ON pt.PTNameFk = rel2.PTNameFk1 AND pt.PTRefFk = rel2.PTRefFk1 " + 
203
					" WHERE (rel2.RelQualifierFk IS NULL) AND (rel1.RelQualifierFk IS NULL) " + 
204
					" GROUP BY pt.PTRefFk, r.RefCache "
205
					;
206
			
207
			strQuery = strQuery + " UNION " + strFlatQuery;
208
		}
209

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

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

    
239
		ResultSet rs = partitioner.getResultSet();
240
			
241
		try{
242
			int i = 0;
243
			//for each reference
244
			while (rs.next()){
245
				
246
				if ((i++ % modCount) == 0 && i!= 1 ){ logger.info("RelPTaxa handled: " + (i-1));}
247
					
248
				int relPTaxonId = rs.getInt("RelPTaxonId");
249
				Integer taxon1Id = nullSafeInt(rs, "taxon1Id");
250
				Integer taxon2Id = nullSafeInt(rs, "taxon2Id");
251
				try {
252
					Integer relRefFk = nullSafeInt(rs,"relRefFk");
253
					int treeRefFk = rs.getInt("treeRefFk");
254
					int fromRefFk = rs.getInt("fromRefFk");
255
					
256
					int relQualifierFk = rs.getInt("relQualifierFk");
257
					String notes = rs.getString("notes");
258
					boolean isConceptRelationship = rs.getBoolean("is_concept_relation");
259
					
260
					TaxonBase<?> taxon1 = taxonMap.get(String.valueOf(taxon1Id));
261
					TaxonBase<?> taxon2 = taxonMap.get(String.valueOf(taxon2Id));
262
					
263
					String refFk = String.valueOf(relRefFk);
264
					Reference<?> citation = refMap.get(refFk);
265
					
266
					String microcitation = null; //does not exist in RelPTaxon
267

    
268
					if (taxon2 != null && taxon1 != null){
269
						if (!(taxon2 instanceof Taxon)){
270
							logger.error("ToTaxon (ID = " + taxon2.getId()+ ", RIdentifier = " + taxon2Id + ") can't be casted to Taxon. RelPTaxon: " + relPTaxonId );
271
							success = false;
272
							continue;
273
						}
274
						AnnotatableEntity taxonRelationship = null;
275
						Taxon toTaxon = (Taxon)taxon2;
276
						if (isTaxonRelationship(relQualifierFk)){
277
							if (!(taxon1 instanceof Taxon)){
278
								logger.error("TaxonBase (ID = " + taxon1.getId()+ ", RIdentifier = " + taxon1Id + ") for TaxonRelation ("+relPTaxonId+") can't be casted to Taxon");
279
								success = false;
280
								continue;
281
							}
282
							Taxon fromTaxon = (Taxon)taxon1;
283
							if (relQualifierFk == TAX_REL_IS_INCLUDED_IN){
284
								taxonRelationship = makeTaxonomicallyIncluded(state, classificationMap, treeRefFk, fromTaxon, toTaxon, citation, microcitation);
285
							}else if (relQualifierFk == TAX_REL_IS_MISAPPLIED_NAME_OF){
286
								 taxonRelationship = toTaxon.addMisappliedName(fromTaxon, citation, microcitation);
287
							}else{
288
								handleAllRelatedTaxa(state, fromTaxon, classificationMap, fromRefFk);
289
								handleAllRelatedTaxa(state, toTaxon, classificationMap, treeRefFk);
290
								logger.warn("Unhandled taxon relationship: RelId:" + relPTaxonId + "; QualifierId: " + relQualifierFk);
291
							}
292
						}else if (isSynonymRelationship(relQualifierFk)){
293
							if (!(taxon1 instanceof Synonym)){
294
								logger.warn("Validated: Taxon (ID = " + taxon1.getId()+ ", RIdentifier = " + taxon1Id + ") can't be casted to Synonym");
295
								success = false;
296
								continue;
297
							}
298
							handleAllRelatedTaxa(state, toTaxon, classificationMap, treeRefFk);
299
							Synonym synonym = (Synonym)taxon1;
300
							SynonymRelationship synRel = getSynRel(relQualifierFk, toTaxon, synonym, citation, microcitation);
301
							taxonRelationship = synRel;
302
							
303
							if (relQualifierFk == TAX_REL_IS_SYNONYM_OF || 
304
									relQualifierFk == TAX_REL_IS_HOMOTYPIC_SYNONYM_OF ||
305
									relQualifierFk == TAX_REL_IS_HETEROTYPIC_SYNONYM_OF){
306
								addProParteAndPartial(synRel, synonym, config);
307
							}else if (relQualifierFk == TAX_REL_IS_PROPARTE_SYN_OF ||
308
									relQualifierFk == TAX_REL_IS_PROPARTE_HOMOTYPIC_SYNONYM_OF ||
309
									relQualifierFk == TAX_REL_IS_PROPARTE_HETEROTYPIC_SYNONYM_OF ){
310
									synRel.setProParte(true);
311
							}else if(relQualifierFk == TAX_REL_IS_PARTIAL_SYN_OF || 
312
									relQualifierFk == TAX_REL_IS_PARTIAL_HOMOTYPIC_SYNONYM_OF ||
313
									relQualifierFk == TAX_REL_IS_PARTIAL_HETEROTYPIC_SYNONYM_OF ){
314
									synRel.setPartial(true);
315
							}else{
316
								success = false;
317
								logger.warn("Proparte/Partial not yet implemented for TaxonRelationShipType " + relQualifierFk);
318
							}
319
						}else if (isConceptRelationship){
320
							ResultWrapper<Boolean> isInverse = new ResultWrapper<Boolean>();
321
							try {
322
								TaxonRelationshipType relType = BerlinModelTransformer.taxonRelId2TaxonRelType(relQualifierFk, isInverse);	
323
								if (! (taxon1 instanceof Taxon)){
324
									success = false;
325
									logger.error("TaxonBase (ID = " + taxon1.getId()+ ", RIdentifier = " + taxon1Id + ") can't be casted to Taxon");
326
								}else{
327
									Taxon fromTaxon = (Taxon)taxon1;
328
									taxonRelationship = fromTaxon.addTaxonRelation(toTaxon, relType, citation, microcitation);
329
									handleAllRelatedTaxa(state, toTaxon, classificationMap, treeRefFk);
330
									handleAllRelatedTaxa(state, fromTaxon, classificationMap, fromRefFk);
331
								}
332
							} catch (UnknownCdmTypeException e) {
333
								//TODO other relationships
334
								logger.warn("TaxonRelationShipType " + relQualifierFk + " (conceptRelationship) not yet implemented");
335
								success = false;
336
							}
337
						}else {
338
							//TODO
339
							logger.warn("TaxonRelationShipType " + relQualifierFk + " not yet implemented: RelPTaxonId = " + relPTaxonId );
340
							success = false;
341
						}
342
						
343
						doNotes(taxonRelationship, notes);
344
						taxaToSave.add(taxon2);
345
						
346
						//TODO
347
						//etc.
348
					}else{
349
						if (taxon2 != null && taxon1 == null){
350
							logger.warn("First taxon ("+taxon1Id+") for RelPTaxon " + relPTaxonId + " does not exist in store. RelType: " + relQualifierFk);
351
						}else if (taxon2 == null && taxon1 != null){
352
							logger.warn("Second taxon ("+taxon2Id +") for RelPTaxon " + relPTaxonId + " does not exist in store. RelType: " + relQualifierFk);
353
						}else{
354
							logger.warn("Both taxa ("+taxon1Id+","+taxon2Id +") for RelPTaxon " + relPTaxonId + " do not exist in store. RelType: " + relQualifierFk);
355
						}
356
						
357
						success = false;
358
					}
359
				} catch (Exception e) {
360
					logger.error("Exception occurred when trying to handle taxon relationship " + relPTaxonId + " (" + taxon1Id + ","+ taxon2Id + "): " + e.getMessage());
361
//					e.printStackTrace();
362
				}
363
			}
364
		}catch(SQLException e){
365
			throw new RuntimeException(e);
366
		}
367
		logger.info("Taxa to save: " + taxaToSave.size());
368
		partitioner.startDoSave();
369
		getTaxonService().saveOrUpdate(taxaToSave);
370
		classificationMap = null;
371
		taxaToSave = null;
372
			
373
		return success;
374
	}
375
	
376

    
377
	private void handleAllRelatedTaxa(BerlinModelImportState state, Taxon taxon, Map<Integer, Classification> classificationMap, Integer secRefFk) {
378
		if (taxon.getTaxonNodes().size() > 0){
379
			return;
380
		}else{
381
			Classification classification = getClassificationTree(state, classificationMap, secRefFk);
382
			classification.addChildTaxon(taxon, null, null);
383
		}
384
		
385

    
386
		
387
	}
388

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

    
445
	/* (non-Javadoc)
446
	 * @see eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportBase#getIdQuery(eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportState)
447
	 */
448
	@Override
449
	protected String getIdQuery(BerlinModelImportState state) {
450
		if (state.getConfig().getRelTaxaIdQuery() != null){
451
			return state.getConfig().getRelTaxaIdQuery();
452
		}else{
453
			return super.getIdQuery(state);
454
		}
455
	}
456
	
457
	
458
	/* (non-Javadoc)
459
	 * @see eu.etaxonomy.cdm.io.berlinModel.in.IPartitionedIO#getRelatedObjectsForPartition(java.sql.ResultSet)
460
	 */
461
	public Map<Object, Map<String, ? extends CdmBase>> getRelatedObjectsForPartition( ResultSet rs) {
462
		String nameSpace;
463
		Class cdmClass;
464
		Set<String> idSet;
465
		Map<Object, Map<String, ? extends CdmBase>> result = new HashMap<Object, Map<String, ? extends CdmBase>>();
466
		
467
		try{
468
			Set<String> taxonIdSet = new HashSet<String>();
469
			Set<String> referenceIdSet = new HashSet<String>();
470
//			Set<String> classificationIdSet = new HashSet<String>();
471
			while (rs.next()){
472
				handleForeignKey(rs, taxonIdSet, "taxon1Id");
473
				handleForeignKey(rs, taxonIdSet, "taxon2Id");
474
//				handleForeignKey(rs, classificationIdSet, "treeRefFk");
475
				handleForeignKey(rs, referenceIdSet, "RelRefFk");
476
	}
477
	
478
			//taxon map
479
			nameSpace = BerlinModelTaxonImport.NAMESPACE;
480
			cdmClass = TaxonBase.class;
481
			idSet = taxonIdSet;
482
			Map<String, TaxonBase> taxonMap = (Map<String, TaxonBase>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
483
			result.put(nameSpace, taxonMap);
484

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

    
501
		} catch (SQLException e) {
502
			throw new RuntimeException(e);
503
		}
504
		return result;
505
	}
506
	
507
	/* (non-Javadoc)
508
	 * @see eu.etaxonomy.cdm.io.berlinModel.in.IPartitionedIO#getRelatedObjectsForPartition(java.sql.ResultSet)
509
	 */
510
	public Map<Object, Map<String, ? extends CdmBase>> getRelatedObjectsForFlatPartition( ResultSet rs) {
511
		String nameSpace;
512
		Class cdmClass;
513
		Set<String> idSet;
514
		Map<Object, Map<String, ? extends CdmBase>> result = new HashMap<Object, Map<String, ? extends CdmBase>>();
515
		
516
		try{
517
			Set<String> taxonIdSet = new HashSet<String>();
518
			Set<String> referenceIdSet = new HashSet<String>();
519
//			Set<String> classificationIdSet = new HashSet<String>();
520
			while (rs.next()){
521
				handleForeignKey(rs, taxonIdSet, "RIdentifier");
522
//				handleForeignKey(rs, classificationIdSet, "treeRefFk");
523
	}
524
	
525
			//taxon map
526
			nameSpace = BerlinModelTaxonImport.NAMESPACE;
527
			cdmClass = TaxonBase.class;
528
			idSet = taxonIdSet;
529
			Map<String, TaxonBase> taxonMap = (Map<String, TaxonBase>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
530
			result.put(nameSpace, taxonMap);
531

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

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

    
548

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

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

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

    
643
	
644
}
(17-17/21)