Project

General

Profile

Download (27 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.SynonymType;
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.TaxonRelationship;
54
import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
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 long serialVersionUID = -7234926279240842557L;
64

    
65
    private static final Logger logger = Logger.getLogger(BerlinModelTaxonRelationImport.class);
66

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

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

    
73

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

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

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

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

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

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

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

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

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

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

    
139
		return;
140
	}
141

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

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

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

    
182

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

    
194

    
195

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

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

    
212

    
213

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

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

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

    
241
		ResultSet rs = partitioner.getResultSet();
242

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

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

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

    
259
					relQualifierFk = rs.getInt("relQualifierFk");
260
					String notes = rs.getString("notes");
261
					boolean isConceptRelationship = rs.getBoolean("is_concept_relation");
262

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

    
266
					String refFk = String.valueOf(relRefFk);
267
					Reference citation = refMap.get(refFk);
268

    
269
					String microcitation = null; //does not exist in RelPTaxon
270

    
271
					if (taxon2 != null && taxon1 != null){
272
						if (!(taxon2 instanceof Taxon)){
273
							logger.error("ToTaxon (ID = " + taxon2.getId()+ ", RIdentifier = " + taxon2Id + ") can't be casted to Taxon. RelPTaxon: " + relPTaxonId );
274
							success = false;
275
							continue;
276
						}
277
						AnnotatableEntity taxonRelationship = null;
278
						Taxon toTaxon = (Taxon)taxon2;
279
						if (isTaxonRelationship(relQualifierFk)){
280
							if (!(taxon1 instanceof Taxon)){
281
								logger.error("TaxonBase (ID = " + taxon1.getId()+ ", RIdentifier = " + taxon1Id + ") for TaxonRelation ("+relPTaxonId+") can't be casted to Taxon");
282
								success = false;
283
								continue;
284
							}
285
							Taxon fromTaxon = (Taxon)taxon1;
286
							if (relQualifierFk == TAX_REL_IS_INCLUDED_IN){
287
								taxonRelationship = makeTaxonomicallyIncluded(state, classificationMap, treeRefFk, fromTaxon, toTaxon, citation, microcitation);
288
							}else if (relQualifierFk == TAX_REL_IS_MISAPPLIED_NAME_OF){
289
								 taxonRelationship = toTaxon.addMisappliedName(fromTaxon, citation, microcitation);
290
							}else{
291
								handleAllRelatedTaxa(state, fromTaxon, classificationMap, fromRefFk);
292
								handleAllRelatedTaxa(state, toTaxon, classificationMap, treeRefFk);
293
								logger.warn("Unhandled taxon relationship: RelId:" + relPTaxonId + "; QualifierId: " + relQualifierFk);
294
							}
295
						}else if (isSynonymRelationship(relQualifierFk)){
296
							if (!(taxon1 instanceof Synonym)){
297
								logger.warn("Validated: Taxon (ID = " + taxon1.getId()+ ", RIdentifier = " + taxon1Id + ") can't be casted to Synonym");
298
								success = false;
299
								continue;
300
							}
301
							handleAllRelatedTaxa(state, toTaxon, classificationMap, treeRefFk);
302
							Synonym synonym = (Synonym)taxon1;
303
							if (synonym.getAcceptedTaxon()!= null){
304
							    logger.warn("Synonym already has an accepted taxon. Create clone.");
305
							    synonym = (Synonym)synonym.clone();
306
							}
307
							makeSynRel(relQualifierFk, toTaxon, synonym, citation, microcitation);
308
							if (isNotBlank(notes)){
309
	                            logger.warn("Notes for synonym relationship or unknown taxon relationship not handled");
310
	                        }
311

    
312
							if (relQualifierFk == TAX_REL_IS_SYNONYM_OF ||
313
									relQualifierFk == TAX_REL_IS_HOMOTYPIC_SYNONYM_OF ||
314
									relQualifierFk == TAX_REL_IS_HETEROTYPIC_SYNONYM_OF){
315
								//pro parte already set by taxon mapping
316
							}else if (relQualifierFk == TAX_REL_IS_PROPARTE_SYN_OF ||
317
									relQualifierFk == TAX_REL_IS_PROPARTE_HOMOTYPIC_SYNONYM_OF ||
318
									relQualifierFk == TAX_REL_IS_PROPARTE_HETEROTYPIC_SYNONYM_OF ){
319
									synonym.setProParte(true);
320
							}else if(relQualifierFk == TAX_REL_IS_PARTIAL_SYN_OF ||
321
									relQualifierFk == TAX_REL_IS_PARTIAL_HOMOTYPIC_SYNONYM_OF ||
322
									relQualifierFk == TAX_REL_IS_PARTIAL_HETEROTYPIC_SYNONYM_OF ){
323
							        synonym.setPartial(true);
324
							}else{
325
								success = false;
326
								logger.warn("Proparte/Partial not yet implemented for TaxonRelationShipType " + relQualifierFk);
327
							}
328
						}else if (isConceptRelationship){
329
							ResultWrapper<Boolean> isInverse = ResultWrapper.NewInstance(false);
330
							ResultWrapper<Boolean> isDoubtful = ResultWrapper.NewInstance(false);
331
							try {
332
								TaxonRelationshipType relType = BerlinModelTransformer.taxonRelId2TaxonRelType(relQualifierFk, isInverse, isDoubtful);
333

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

    
360
						if (taxonRelationship != null){
361
						    doNotes(taxonRelationship, notes);
362
						}else if (isNotBlank(notes)){
363
						    logger.warn("Notes for synonym relationship or unknown taxon relationship not handled");
364
						}
365
						taxaToSave.add(taxon2);
366

    
367
						//TODO
368
						//etc.
369
					}else{
370
						if (taxon2 != null && taxon1 == null){
371
							logger.warn("First taxon ("+taxon1Id+") for RelPTaxon " + relPTaxonId + " does not exist in store. RelType: " + relQualifierFk);
372
						}else if (taxon2 == null && taxon1 != null){
373
							logger.warn("Second taxon ("+taxon2Id +") for RelPTaxon " + relPTaxonId + " does not exist in store. RelType: " + relQualifierFk);
374
						}else{
375
							logger.warn("Both taxa ("+taxon1Id+","+taxon2Id +") for RelPTaxon " + relPTaxonId + " do not exist in store. RelType: " + relQualifierFk);
376
						}
377

    
378
						success = false;
379
					}
380
				} catch (Exception e) {
381
					logger.error("Exception occurred when trying to handle taxon relationship " + relPTaxonId + " relQualifierFK " + relQualifierFk + " (" + taxon1Id + ","+ taxon2Id + "): " + e.getMessage());
382
					e.printStackTrace();
383
				}
384
			}
385
		}catch(SQLException e){
386
			throw new RuntimeException(e);
387
		}
388
		logger.info("Taxa to save: " + taxaToSave.size());
389
		partitioner.startDoSave();
390
		getTaxonService().saveOrUpdate(taxaToSave);
391
		classificationMap = null;
392
		taxaToSave = null;
393

    
394
		return success;
395
	}
396

    
397

    
398
	private void handleAllRelatedTaxa(BerlinModelImportState state, Taxon taxon, Map<Integer, Classification> classificationMap, Integer secRefFk) {
399
		if (taxon.getTaxonNodes().size() > 0){
400
			return;
401
		}else{
402
			Classification classification = getClassificationTree(state, classificationMap, secRefFk);
403
			classification.addChildTaxon(taxon, null, null);
404
		}
405
	}
406

    
407
	@Override
408
	protected void doInvoke(BerlinModelImportState state){
409
		try {
410
			makeClassifications(state);
411
			super.doInvoke(state);
412
			makeFlatClassificationTaxa(state);
413
			return;
414
		} catch (SQLException e) {
415
			throw new RuntimeException(e);
416
		}
417

    
418
	}
419

    
420

    
421
	private void makeFlatClassificationTaxa(BerlinModelImportState state) {
422
		//Note: this part still does not use partitions
423
		logger.info("Flat classifications start");
424
		TransactionStatus txStatus = startTransaction();
425
		if (! state.getConfig().isIncludeFlatClassifications()){
426
			return;
427
		}
428
		String sql = " SELECT pt.PTRefFk AS secRefFk, pt.RIdentifier " +
429
						" FROM PTaxon AS pt " +
430
							" LEFT OUTER JOIN RelPTaxon ON pt.PTNameFk = RelPTaxon.PTNameFk2 AND pt.PTRefFk = RelPTaxon.PTRefFk2 " +
431
							"  LEFT OUTER JOIN RelPTaxon AS RelPTaxon_1 ON pt.PTNameFk = RelPTaxon_1.PTNameFk1 AND pt.PTRefFk = RelPTaxon_1.PTRefFk1 " +
432
						" WHERE (RelPTaxon_1.RelQualifierFk IS NULL) AND (dbo.RelPTaxon.RelQualifierFk IS NULL) " +
433
						" ORDER BY pt.PTRefFk "	;
434
		ResultSet rs = state.getConfig().getSource().getResultSet(sql);
435
		Map<Object, Map<String, ? extends CdmBase>> maps = getRelatedObjectsForFlatPartition(rs);
436

    
437
		Map<String, TaxonBase> taxonMap = (Map<String, TaxonBase>) maps.get(BerlinModelTaxonImport.NAMESPACE);
438
		Map<Integer, Classification> classificationMap = new HashMap<Integer, Classification>();
439

    
440
		rs = state.getConfig().getSource().getResultSet(sql);
441
		try {
442
			while (rs.next()){
443
				Integer treeRefFk = rs.getInt("secRefFk");
444
				String taxonId = rs.getString("RIdentifier");
445
				Classification classification = getClassificationTree(state, classificationMap, treeRefFk);
446
				TaxonBase<?> taxon = taxonMap.get(taxonId);
447
				if (taxon == null){
448
					String message = "TaxonBase for taxon id (%s) not found in taxonMap";
449
					logger.warn(String.format(message, taxonId, taxonId));
450
				}else if (taxon.isInstanceOf(Taxon.class)){
451
					classification.addChildTaxon(CdmBase.deproxy(taxon, Taxon.class), null, null);
452
				}else{
453
					String message = "TaxonBase for taxon is not of class Taxon but %s (RIdentifier %s)";
454
					logger.warn(String.format(message, taxon.getClass(), taxonId));
455
				}
456
			}
457
		} catch (SQLException e) {
458
			// TODO Auto-generated catch block
459
			e.printStackTrace();
460
		}
461
		commitTransaction(txStatus);
462
		logger.info("Flat classifications end");
463

    
464
	}
465

    
466
	@Override
467
	protected String getIdQuery(BerlinModelImportState state) {
468
		if (state.getConfig().getRelTaxaIdQuery() != null){
469
			return state.getConfig().getRelTaxaIdQuery();
470
		}else{
471
			return super.getIdQuery(state);
472
		}
473
	}
474

    
475
	@Override
476
	public Map<Object, Map<String, ? extends CdmBase>> getRelatedObjectsForPartition( ResultSet rs, BerlinModelImportState state) {
477
		String nameSpace;
478
		Class<?> cdmClass;
479
		Set<String> idSet;
480
		Map<Object, Map<String, ? extends CdmBase>> result = new HashMap<Object, Map<String, ? extends CdmBase>>();
481

    
482
		try{
483
			Set<String> taxonIdSet = new HashSet<String>();
484
			Set<String> referenceIdSet = new HashSet<String>();
485
//			Set<String> classificationIdSet = new HashSet<String>();
486
			while (rs.next()){
487
				handleForeignKey(rs, taxonIdSet, "taxon1Id");
488
				handleForeignKey(rs, taxonIdSet, "taxon2Id");
489
//				handleForeignKey(rs, classificationIdSet, "treeRefFk");
490
				handleForeignKey(rs, referenceIdSet, "RelRefFk");
491
	}
492

    
493
			//taxon map
494
			nameSpace = BerlinModelTaxonImport.NAMESPACE;
495
			cdmClass = TaxonBase.class;
496
			idSet = taxonIdSet;
497
			Map<String, TaxonBase> taxonMap = (Map<String, TaxonBase>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
498
			result.put(nameSpace, taxonMap);
499

    
500
//			//tree map
501
//			nameSpace = "Classification";
502
//			cdmClass = Classification.class;
503
//			idSet = classificationIdSet;
504
//			Map<String, Classification> treeMap = (Map<String, Classification>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
505
//			result.put(cdmClass, treeMap);
506
//			Set<UUID> treeUuidSet = state
507
//			getClassificationService().find(uuidSet);
508
//
509
			//reference map
510
			nameSpace = BerlinModelReferenceImport.REFERENCE_NAMESPACE;
511
			cdmClass = Reference.class;
512
			idSet = referenceIdSet;
513
			Map<String, Reference> referenceMap = (Map<String, Reference>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
514
			result.put(nameSpace, referenceMap);
515

    
516
		} catch (SQLException e) {
517
			throw new RuntimeException(e);
518
		}
519
		return result;
520
	}
521

    
522

    
523
	private Map<Object, Map<String, ? extends CdmBase>> getRelatedObjectsForFlatPartition( ResultSet rs) {
524
		String nameSpace;
525
		Class cdmClass;
526
		Set<String> idSet;
527
		Map<Object, Map<String, ? extends CdmBase>> result = new HashMap<Object, Map<String, ? extends CdmBase>>();
528

    
529
		try{
530
			Set<String> taxonIdSet = new HashSet<String>();
531
			Set<String> referenceIdSet = new HashSet<String>();
532
//			Set<String> classificationIdSet = new HashSet<String>();
533
			while (rs.next()){
534
				handleForeignKey(rs, taxonIdSet, "RIdentifier");
535
//				handleForeignKey(rs, classificationIdSet, "treeRefFk");
536
	}
537

    
538
			//taxon map
539
			nameSpace = BerlinModelTaxonImport.NAMESPACE;
540
			cdmClass = TaxonBase.class;
541
			idSet = taxonIdSet;
542
			Map<String, TaxonBase> taxonMap = (Map<String, TaxonBase>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
543
			result.put(nameSpace, taxonMap);
544

    
545
//			//tree map
546
//			nameSpace = "Classification";
547
//			cdmClass = Classification.class;
548
//			idSet = classificationIdSet;
549
//			Map<String, Classification> treeMap = (Map<String, Classification>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
550
//			result.put(cdmClass, treeMap);
551
//			Set<UUID> treeUuidSet = state
552
//			getClassificationService().find(uuidSet);
553
//
554

    
555
		} catch (SQLException e) {
556
			throw new RuntimeException(e);
557
		}
558
		return result;
559
	}
560

    
561

    
562
	private void makeSynRel (int relQualifierFk, Taxon toTaxon, Synonym synonym, Reference citation, String microcitation){
563
		if (citation != null && !citation.equals(synonym.getSec())){
564
		    logger.warn("A synonym relationship citation is given and differs from synonym secundum. This can not be handled in CDM");
565
		}
566
		if (isNotBlank(microcitation)  && !microcitation.equals(synonym.getSecMicroReference())){
567
            logger.warn("A synonym relationship microcitation is given and differs from synonym secundum micro reference. This can not be handled in CDM");
568
        }
569
	    if (relQualifierFk == TAX_REL_IS_HOMOTYPIC_SYNONYM_OF ||
570
				relQualifierFk == TAX_REL_IS_PROPARTE_HOMOTYPIC_SYNONYM_OF ||
571
				relQualifierFk == TAX_REL_IS_PARTIAL_HOMOTYPIC_SYNONYM_OF){
572
			toTaxon.addHomotypicSynonym(synonym);
573
		}else if (relQualifierFk == TAX_REL_IS_HETEROTYPIC_SYNONYM_OF ||
574
				relQualifierFk == TAX_REL_IS_PROPARTE_HETEROTYPIC_SYNONYM_OF ||
575
				relQualifierFk == TAX_REL_IS_PARTIAL_HETEROTYPIC_SYNONYM_OF){
576
			toTaxon.addSynonym(synonym, SynonymType.HETEROTYPIC_SYNONYM_OF());
577
		}else if (relQualifierFk == TAX_REL_IS_SYNONYM_OF ||
578
				relQualifierFk == TAX_REL_IS_PROPARTE_SYN_OF ||
579
				relQualifierFk == TAX_REL_IS_PARTIAL_SYN_OF){
580
			toTaxon.addSynonym(synonym, SynonymType.SYNONYM_OF());
581
		}else{
582
			logger.warn("SynonymyRelationShipType could not be defined for relQualifierFk " + relQualifierFk + ". 'Unknown'-Type taken instead.");
583
			toTaxon.addSynonym(synonym, SynonymType.SYNONYM_OF());
584
		}
585
		return;
586

    
587
	}
588

    
589
	private  boolean isSynonymRelationship(int relQualifierFk){
590
		if (relQualifierFk == TAX_REL_IS_SYNONYM_OF ||
591
			relQualifierFk == TAX_REL_IS_HOMOTYPIC_SYNONYM_OF ||
592
			relQualifierFk == TAX_REL_IS_HETEROTYPIC_SYNONYM_OF ||
593
			relQualifierFk == TAX_REL_IS_PROPARTE_SYN_OF ||
594
			relQualifierFk == TAX_REL_IS_PARTIAL_SYN_OF ||
595
			relQualifierFk == TAX_REL_IS_PROPARTE_HOMOTYPIC_SYNONYM_OF ||
596
			relQualifierFk == TAX_REL_IS_PROPARTE_HETEROTYPIC_SYNONYM_OF ||
597
			relQualifierFk == TAX_REL_IS_PARTIAL_HOMOTYPIC_SYNONYM_OF ||
598
			relQualifierFk == TAX_REL_IS_PARTIAL_HETEROTYPIC_SYNONYM_OF
599
		){
600
			return true;
601
		}else{
602
			return false;
603
		}
604
	}
605

    
606
	private  boolean isTaxonRelationship(int relQualifierFk){
607
		if (relQualifierFk == TAX_REL_IS_INCLUDED_IN ||
608
				relQualifierFk == TAX_REL_IS_MISAPPLIED_NAME_OF){
609
			return true;
610
		}else{
611
			return false;
612
		}
613
	}
614

    
615
	private TaxonNode makeTaxonomicallyIncluded(BerlinModelImportState state, Map<Integer, Classification> classificationMap, int treeRefFk, Taxon child, Taxon parent, Reference citation, String microCitation){
616
		Classification tree = getClassificationTree(state, classificationMap, treeRefFk);
617
		return tree.addParentChild(parent, child, citation, microCitation);
618
	}
619

    
620
	private Classification getClassificationTree(BerlinModelImportState state, Map<Integer, Classification> classificationMap, int treeRefFk) {
621
		if (state.getConfig().isUseSingleClassification()){
622
			if (state.getConfig().getSourceSecId() != null){
623
				treeRefFk = (Integer)state.getConfig().getSourceSecId();
624
			}else{
625
				treeRefFk = 1;
626
			}
627

    
628
		}
629
		Classification tree = classificationMap.get(treeRefFk);
630
		if (tree == null){
631
			UUID treeUuid = state.getTreeUuidByIntTreeKey(treeRefFk);
632
			if (treeUuid == null){
633
				throw new IllegalStateException("treeUUID does not exist in state for " + treeRefFk );
634
			}
635
			tree = getClassificationService().find(treeUuid);
636
			classificationMap.put(treeRefFk, tree);
637
		}
638
		if (tree == null){
639
			throw new IllegalStateException("Tree for ToTaxon reference " + treeRefFk + " does not exist.");
640
		}
641
		return tree;
642
	}
643

    
644
	@Override
645
	protected boolean doCheck(BerlinModelImportState state){
646
		IOValidator<BerlinModelImportState> validator = new BerlinModelTaxonRelationImportValidator();
647
		return validator.validate(state);
648
	}
649

    
650
	@Override
651
	protected boolean isIgnore(BerlinModelImportState state){
652
		return ! state.getConfig().isDoRelTaxa();
653
	}
654

    
655

    
656
}
(17-17/21)