Project

General

Profile

Download (26.6 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
				int relQualifierFk = 0;
253
				try {
254
					Integer relRefFk = nullSafeInt(rs,"relRefFk");
255
					int treeRefFk = rs.getInt("treeRefFk");
256
					int fromRefFk = rs.getInt("fromRefFk");
257

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

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

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

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

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

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

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

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

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

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

    
383
		return success;
384
	}
385

    
386

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

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

    
407
	}
408

    
409

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

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

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

    
453
	}
454

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

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

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

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

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

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

    
511

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

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

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

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

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

    
550

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

    
571
	}
572

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

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

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

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

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

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

    
637
	@Override
638
	protected boolean doCheck(BerlinModelImportState state){
639
		IOValidator<BerlinModelImportState> validator = new BerlinModelTaxonRelationImportValidator();
640
		return validator.validate(state);
641
	}
642

    
643
	@Override
644
	protected boolean isIgnore(BerlinModelImportState state){
645
		return ! state.getConfig().isDoRelTaxa();
646
	}
647

    
648

    
649
}
(17-17/21)