Project

General

Profile

« Previous | Next » 

Revision 608b3df3

Added by Andreas Müller about 2 years ago

minor

View differences:

cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/tcsxml/in/TcsXmlTaxonRelationsImport.java
1
/**
2
* Copyright (C) 2009 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.tcsxml.in;
11

  
12
import java.io.InputStream;
13
import java.util.ArrayList;
14
import java.util.HashSet;
15
import java.util.List;
16
import java.util.Map;
17
import java.util.Set;
18

  
19
import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;
20
import org.jdom.Element;
21
import org.jdom.Namespace;
22
import org.springframework.beans.factory.annotation.Autowired;
23
import org.springframework.stereotype.Component;
24

  
25
import eu.etaxonomy.cdm.common.CdmUtils;
26
import eu.etaxonomy.cdm.common.ResultWrapper;
27
import eu.etaxonomy.cdm.common.XmlHelp;
28
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
29
import eu.etaxonomy.cdm.io.common.ICdmIO;
30
import eu.etaxonomy.cdm.io.common.MapWrapper;
31
import eu.etaxonomy.cdm.io.tcsrdf.TcsRdfImportConfigurator;
32
import eu.etaxonomy.cdm.io.tcsrdf.TcsRdfTaxonNameImport;
33
import eu.etaxonomy.cdm.io.tcsxml.TcsXmlTransformer;
34
import eu.etaxonomy.cdm.model.common.CdmBase;
35
import eu.etaxonomy.cdm.model.common.RelationshipTermBase;
36
import eu.etaxonomy.cdm.model.description.CommonTaxonName;
37
import eu.etaxonomy.cdm.model.description.TaxonDescription;
38
import eu.etaxonomy.cdm.model.name.TaxonName;
39
import eu.etaxonomy.cdm.model.name.TaxonNameFactory;
40
import eu.etaxonomy.cdm.model.reference.OriginalSourceType;
41
import eu.etaxonomy.cdm.model.reference.Reference;
42
import eu.etaxonomy.cdm.model.taxon.Classification;
43
import eu.etaxonomy.cdm.model.taxon.Synonym;
44
import eu.etaxonomy.cdm.model.taxon.SynonymType;
45
import eu.etaxonomy.cdm.model.taxon.Taxon;
46
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
47
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
48
import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
49
import eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException;
50

  
51

  
52
/**
53
 * @author a.mueller
54
 *
55
 */
56
@Component
57
public class TcsXmlTaxonRelationsImport extends TcsXmlImportBase implements ICdmIO<TcsXmlImportState> {
58
    private static final long serialVersionUID = 6632990505515905663L;
59

  
60
    private static final Logger logger = LogManager.getLogger(TcsXmlTaxonRelationsImport.class);
61

  
62
	private static int modCount = 30000;
63

  
64
	@Autowired
65
	private TcsRdfTaxonNameImport rdfNameImport;
66
	private TcsRdfImportConfigurator rdfConfig = TcsRdfImportConfigurator.NewInstance(null, null);
67

  
68
	public TcsXmlTaxonRelationsImport(){
69
		super();
70

  
71
	}
72

  
73
	@Override
74
	public boolean doCheck(TcsXmlImportState state){
75
		boolean result = true;
76
		logger.warn("Checking for TaxonRelations not yet implemented");
77
		logger.warn("Creation of homotypic relations is still problematic");
78
		//result &= checkArticlesWithoutJournal(bmiConfig);
79
		//result &= checkPartOfJournal(bmiConfig);
80

  
81
		return result;
82
	}
83

  
84
	@Override
85
	public void doInvoke(TcsXmlImportState state){
86

  
87

  
88
		logger.info("start make taxon relations ...");
89
		MapWrapper<TaxonBase> taxonMap = (MapWrapper<TaxonBase>)state.getStore(ICdmIO.TAXON_STORE);
90
		MapWrapper<TaxonName> taxonNameMap = (MapWrapper<TaxonName>)state.getStore(ICdmIO.TAXONNAME_STORE);
91
		MapWrapper<Reference> referenceMap = (MapWrapper<Reference>)state.getStore(ICdmIO.REFERENCE_STORE);
92

  
93
		Set<TaxonBase> taxonStore = new HashSet<TaxonBase>();
94

  
95
		ResultWrapper<Boolean> success = ResultWrapper.NewInstance(true);
96
		String childName;
97
		boolean obligatory;
98
		String idNamespace = "TaxonRelationDTO";
99

  
100
		TcsXmlImportConfigurator config = state.getConfig();
101
		Element elDataSet = super.getDataSetElement(config);
102
		Namespace tcsNamespace = config.getTcsXmlNamespace();
103

  
104
		childName = "TaxonConcepts";
105
		obligatory = false;
106
		Element elTaxonConcepts = XmlHelp.getSingleChildElement(success, elDataSet, childName, tcsNamespace, obligatory);
107

  
108
		childName = "TaxonConcept";
109
		List<Element> elTaxonConceptList =  elTaxonConcepts == null ? new ArrayList<Element>() : elTaxonConcepts.getChildren(childName, tcsNamespace);
110

  
111
		int i = 0;
112
		int taxonRelCount = 0;
113

  
114
		//for each taxonConcept
115
		logger.info("NUmber of taxon concepts: " + elTaxonConceptList.size());
116
		for (Element elTaxonConcept : elTaxonConceptList){
117
			if ((i++ % modCount) == 0){ logger.info("Taxa handled: " + (i-1));}
118
			taxonRelCount += makeTaxonConcept(state, taxonMap, taxonStore, elTaxonConcept, tcsNamespace, success);
119
		}//elTaxonConcept
120
		logger.info("Taxa handled: " + taxonStore.size());
121
		//TaxonRelationshipAssertions
122
		taxonRelCount += makeTaxonRelationshipAssertion(state, taxonMap, referenceMap, taxonStore, elDataSet, tcsNamespace, success);
123

  
124
		logger.info("Taxa to save: " + taxonStore.size());
125
		getTaxonService().save(taxonStore);
126

  
127
		//do basionym relationships
128
		childName = "TaxonNames";
129
		obligatory = false;
130
		Element elTaxonNames = XmlHelp.getSingleChildElement(success, elDataSet, childName, tcsNamespace, obligatory);
131

  
132
		childName = "TaxonName";
133
		List<Element> elTaxonNameList =  elTaxonNames == null ? new ArrayList<Element>() : elTaxonNames.getChildren(childName, tcsNamespace);
134

  
135
		logger.info("NUmber of taxon concepts: " + elTaxonNameList.size());
136
		for (Element elTaxonName : elTaxonNameList){
137
			if ((i++ % modCount) == 0){ logger.info("Taxa handled: " + (i-1));}
138
			taxonRelCount += makeBasionymRelations(state, taxonMap, taxonNameMap, taxonStore, elTaxonName, tcsNamespace, success);
139
		}//elTaxonConcept
140
		logger.info("Taxa handled: " + taxonStore.size());
141

  
142

  
143
		taxonStore = null;
144
		logger.info("end make taxon relations ...");
145
		if (!success.getValue()){
146
			state.setUnsuccessfull();
147
		}
148
		return;
149
	}
150

  
151
	private int makeBasionymRelations(TcsXmlImportState state,
152
			MapWrapper<TaxonBase> taxonMap, MapWrapper<TaxonName> taxonNameMap, Set<TaxonBase> taxonStore,
153
			Element elTaxonName, Namespace tcsNamespace,
154
			ResultWrapper<Boolean> success) {
155

  
156
		/*
157
		 * <tcs:Basionym>
158
				<tcs:RelatedName ref="urn:lsid:ipni.org:names:50000063-1">Caryophyllaceae</tcs:RelatedName>
159
			</tcs:Basionym>
160
		 */
161

  
162

  
163
		String childName = "Basionym";
164
		boolean obligatory = false;
165
		Element elBasionymRelationships = XmlHelp.getSingleChildElement(success, elTaxonName, childName, tcsNamespace, obligatory);
166
		if (elBasionymRelationships != null){
167
			childName = "RelatedName";
168
			obligatory = false;
169
			Element elBasionym = XmlHelp.getSingleChildElement(success, elBasionymRelationships, childName, tcsNamespace, obligatory);
170

  
171
			String id = elTaxonName.getAttributeValue("id");
172
			TaxonName name = taxonNameMap.get(removeVersionOfRef(id));
173

  
174
			TaxonBase taxonBase = (TaxonBase)name.getTaxonBases().iterator().next();
175

  
176
			String ref = elBasionym.getAttributeValue("ref");
177
			TaxonName basionymName = taxonNameMap.get(removeVersionOfRef(ref));
178

  
179
			if (basionymName != null){
180
				basionymName = HibernateProxyHelper.deproxy(basionymName, TaxonName.class);
181
				TaxonBase basionym;
182
				if (basionymName.getTaxonBases().isEmpty()){
183
					 basionym = Synonym.NewInstance(basionymName, null);
184
				}else{
185
					basionym = (TaxonBase)basionymName.getTaxonBases().iterator().next();
186
				}
187
				//Synonym basionymSyn;
188
				if (basionym instanceof Taxon){
189

  
190
					if (!(taxonBase instanceof Synonym)){
191
						logger.debug("The taxon " + basionymName.getTitleCache() + " is used in a concept and can not be a synonym " + name.getTitleCache() + "but will be added as basionym for the homotypical group");
192
						name.addBasionym(basionymName);
193
						//basionymName.getHomotypicalGroup().addTypifiedName(name);
194
					} else if (taxonBase instanceof Synonym){
195
						Synonym synonym = (Synonym) taxonBase;
196
						((Taxon)basionym).addSynonym(synonym, SynonymType.HOMOTYPIC_SYNONYM_OF());
197
						basionym.getHomotypicGroup().setGroupBasionym(basionymName);
198
						taxonStore.add(basionym);
199
					}
200
				}else{
201
					if (taxonBase instanceof Taxon){
202
						Synonym synonym = (Synonym) basionym;
203
						((Taxon)taxonBase).addSynonym(synonym, SynonymType.HOMOTYPIC_SYNONYM_OF());
204
						taxonBase.getHomotypicGroup().setGroupBasionym(basionymName);
205
						taxonStore.add(taxonBase);
206
					} else{
207
					    Taxon acc = ((Synonym)taxonBase).getAcceptedTaxon();
208
						if (acc != null){
209
							acc.addHomotypicSynonym((Synonym)basionym);
210
							basionymName.getHomotypicalGroup().setGroupBasionym(basionymName);
211
						}
212
					}
213
				}
214

  
215

  
216
			} else{
217
				basionymName = TaxonNameFactory.NewNonViralInstance(name.getRank());
218
				childName = "RelatedName";
219
				obligatory = true;
220
				Element elName = XmlHelp.getSingleChildElement(success, elBasionym, childName, tcsNamespace, obligatory);
221
				String strName = (elName == null)? "" : elName.getTextNormalize();
222
				basionymName.setTitleCache(strName, false);
223
				Synonym basionymSyn = Synonym.NewInstance(basionymName, unknownSec());
224
				if (taxonBase instanceof Taxon){
225
					Taxon taxon = (Taxon)taxonBase;
226
					taxon.addSynonym(basionymSyn, SynonymType.HOMOTYPIC_SYNONYM_OF());
227
					taxon.getHomotypicGroup().setGroupBasionym(basionymName);
228
					taxonStore.add(taxon);
229
				} else{
230
					Synonym syn = (Synonym) taxonBase;
231
					if (syn.getAcceptedTaxon() != null){
232
						Taxon accTaxon = syn.getAcceptedTaxon();
233
						accTaxon.addSynonym(basionymSyn, SynonymType.HOMOTYPIC_SYNONYM_OF());
234
						accTaxon.getHomotypicGroup().setGroupBasionym(basionymName);
235
						taxonStore.add(accTaxon);
236
					}
237
				}
238
			}
239
		}
240
		return 1;
241
	}
242

  
243
	private int makeTaxonConcept(TcsXmlImportState state, MapWrapper<TaxonBase> taxonMap, Set<TaxonBase> taxonStore, Element elTaxonConcept, Namespace tcsNamespace, ResultWrapper<Boolean> success){
244
		int taxonRelCount = 0;
245

  
246
		String childName = "TaxonRelationships";
247
		boolean obligatory = false;
248
		Element elTaxonRelationships = XmlHelp.getSingleChildElement(success, elTaxonConcept, childName, tcsNamespace, obligatory);
249

  
250
		if (elTaxonRelationships != null){
251
			//Relationships
252
			String tcsElementName = "TaxonRelationship";
253
			List<Element> elTaxonRelationshipList = elTaxonRelationships.getChildren(tcsElementName, tcsNamespace);
254
			logger.info("Number of taxonrelationships: " + elTaxonRelationshipList.size());
255
			for (Element elTaxonRelationship: elTaxonRelationshipList){
256

  
257
				taxonRelCount++;
258
				logger.debug("TaxonRelationship "+  taxonRelCount);
259

  
260
				String strId = elTaxonConcept.getAttributeValue("id");
261
				//TODO
262
//				String strConceptType = elTaxonConcept.getAttributeValue("type"); //original, revision, incomplete, aggregate, nominal
263
//				String strPrimary = elTaxonConcept.getAttributeValue("primary"); //If primary='true' the concept is the first level response to a query. If 'false' the concept may be a secondary concept linked directly or indirectly to the definition of a primary concept.
264
//				String strForm = elTaxonConcept.getAttributeValue("form");  //anamorph, teleomorph, hybrid
265

  
266
				TaxonBase fromTaxon = taxonMap.get(removeVersionOfRef(strId));
267
				makeRelationshipType(state, elTaxonRelationship, taxonMap, taxonStore, fromTaxon, success);
268

  
269
				if (fromTaxon instanceof Taxon){
270
					makeHomotypicSynonymRelations((Taxon)fromTaxon);
271
				}
272
			}// end Relationship
273
		}
274
		return taxonRelCount;
275
	}
276

  
277
	private int makeTaxonRelationshipAssertion(
278
			TcsXmlImportState state,
279
			MapWrapper<TaxonBase> taxonMap,
280
			MapWrapper<Reference> referenceMap,
281
			Set<TaxonBase> taxonStore,
282
			Element elDataSet,
283
			Namespace tcsNamespace,
284
			ResultWrapper<Boolean> success){
285

  
286
		int i = 0;
287
		String childName = "TaxonRelationshipAssertions";
288
		boolean obligatory = false;
289
		Element elTaxonRelationshipAssertions = XmlHelp.getSingleChildElement(success, elDataSet, childName, tcsNamespace, obligatory);
290
		if(elTaxonRelationshipAssertions == null){
291
			return 0;
292
		}
293

  
294
		childName = "TaxonRelationshipAssertion";
295
		List<Element> elTaxonRelationshipAssertionList = elTaxonRelationshipAssertions.getChildren(childName, tcsNamespace);
296
		//for each taxon relationship assertion
297
		for (Element elTaxonRelationshipAssertion : elTaxonRelationshipAssertionList){
298
			if ((i++ % modCount) == 0){ logger.info("TaxonRelationshipAssertions handled: " + (i-1));}
299
			String strId = elTaxonRelationshipAssertion.getAttributeValue("id");
300
			//TODO id
301

  
302
			childName = "AccordingTo";
303
			obligatory = true;
304
			Element elAccordingTo = XmlHelp.getSingleChildElement(success, elTaxonRelationshipAssertion, childName, tcsNamespace, obligatory);
305
			Reference ref = makeAccordingTo(elAccordingTo, referenceMap, success);
306

  
307
			childName = "FromTaxonConcept";
308
			obligatory = true;
309
			Element elFromTaxonConcept = XmlHelp.getSingleChildElement(success, elTaxonRelationshipAssertion, childName, tcsNamespace, obligatory);
310

  
311
			Class<? extends TaxonBase> clazz = Taxon.class;
312
			//TODO if synonym
313
			TaxonBase fromTaxon = makeReferenceType(elFromTaxonConcept, clazz, taxonMap, success);
314

  
315
			makeRelationshipType(state, elTaxonRelationshipAssertion, taxonMap, taxonStore, fromTaxon, success);
316
		}//elTaxonRelationshipAssertion
317

  
318
		return i;
319
	}
320

  
321

  
322
	/**
323
	 * Handles the TCS RelationshipType element.
324
	 * @param tcsConfig
325
	 * @param elRelationship
326
	 * @param taxonMap
327
	 * @param taxonStore
328
	 * @param fromTaxon
329
	 * @param success
330
	 */
331
	private void makeRelationshipType(
332
			TcsXmlImportState state
333
			, Element elRelationship
334
			, MapWrapper<TaxonBase> taxonMap
335
			, Set<TaxonBase> taxonStore
336
			, TaxonBase fromTaxon
337
			, ResultWrapper<Boolean> success
338
			){
339

  
340
		if (elRelationship == null){
341
			success.setValue(false);
342
		}
343
		String strRelType = elRelationship.getAttributeValue("type");
344

  
345

  
346
		try {
347
			ResultWrapper<Boolean> isInverse = new ResultWrapper<Boolean>();
348
			isInverse.setValue(false);
349
			if ("has vernacular".equalsIgnoreCase(strRelType)){
350
				handleVernacular(success, state, elRelationship, fromTaxon);
351
			}else{
352
				RelationshipTermBase<?> relType = TcsXmlTransformer.tcsRelationshipType2Relationship(strRelType, isInverse);
353

  
354
				//toTaxon (should be part of relationshipType)
355
				boolean isSynonym = (relType instanceof SynonymType);
356
				TaxonBase toTaxon = getToTaxon(elRelationship, taxonMap, state.getMissingConceptLSIDs(), isSynonym, success, state);
357

  
358
				if (toTaxon != null && fromTaxon != null){
359
					//exchange taxa if relationship is inverse
360
					if (isInverse.getValue() == true ){
361
						TaxonBase tmp = toTaxon;
362
						toTaxon = fromTaxon;
363
						fromTaxon = tmp;
364
					}
365

  
366
					//Create relationship
367
					if (! (toTaxon instanceof Taxon)){
368
						logger.warn("TaxonBase toTaxon is not of Type 'Taxon'. Relationship is not added.");
369
						success.setValue(false);
370
					}else{
371
						Taxon taxonTo = (Taxon)toTaxon;
372
						if (relType instanceof SynonymType){
373
							SynonymType synRelType = (SynonymType)relType;
374
							if (! (fromTaxon instanceof Synonym )){
375
								logger.warn("TaxonBase fromTaxon is not of Type 'Synonym'. Relationship is not added.");
376
								success.setValue(false);
377
							}else{
378
								Synonym synonym = (Synonym)fromTaxon;
379
								TaxonName synName = synonym.getName();
380
								TaxonName accName = taxonTo.getName();
381
								if (synName != null && accName != null && synName.isHomotypic(accName)
382
											&& ( synRelType.equals(SynonymType.SYNONYM_OF()))){
383
									synRelType = SynonymType.HOMOTYPIC_SYNONYM_OF();
384
								}
385
								if (! relationExists(taxonTo, synonym, synRelType)){
386
									taxonTo.addSynonym(synonym, synRelType);
387
								}else{
388
									//TODO citation, microReference
389
									//TODO different synRelTypes -> warning
390
									success.setValue(false);
391
								}
392
							}
393
						}else if (relType instanceof TaxonRelationshipType){
394
							Reference citation = null;
395
							String microReference = null;
396
						    makeTaxonRelationship(state, (TaxonRelationshipType)relType, fromTaxon, taxonTo, citation, microReference, success);
397
						}else{
398
							logger.warn("Unknown Relationshiptype");
399
							success.setValue(false);
400
						}
401
						taxonStore.add(toTaxon);
402
					}
403
				}else{
404
					if (toTaxon == null){
405
					//	logger.warn("toTaxon (" + /*strToTaxon + */ ") could  not be found in taxonMap. Relationship of type " + strRelType + " was not added to CDM");
406
					}
407
					if (fromTaxon == null){
408
					//	logger.warn("fromTaxon (" + /*strTaxonAbout + */") could not be found in taxonMap. Relationship was not added to CDM");
409
					}
410
					success.setValue(false);
411
				}
412
			}
413
		} catch (UnknownCdmTypeException e) {
414
			//TODO
415
			logger.warn("relationshipType " + strRelType + " not yet implemented");
416
			success.setValue(false);
417
		}
418
		return;
419
	}
420

  
421
	private void handleVernacular(ResultWrapper<Boolean> success, TcsXmlImportState state, Element elRelationship, TaxonBase taxonBase) {
422
		if (! taxonBase.isInstanceOf(Taxon.class)){
423
			logger.warn("From Taxon is not of type Taxon but of type " +  taxonBase.getClass().getSimpleName());
424
			success.setValue(false);
425
			return;
426
		}else{
427
			Taxon taxon = CdmBase.deproxy(taxonBase, Taxon.class);
428
			Map<String, CommonTaxonName> commonNameMap = state.getCommonNameMap();
429
			CommonTaxonName commonTaxonName = getCommonName(elRelationship, commonNameMap, success);
430
			TaxonDescription description = getDescription(taxon);
431
			description.addElement(commonTaxonName);
432
		}
433
	}
434

  
435
	private TaxonDescription getDescription(Taxon taxon) {
436
		if (taxon.getDescriptions().isEmpty()){
437
			return TaxonDescription.NewInstance(taxon);
438
		}else{
439
			//TODO only if the description represents this TCS file
440
			return taxon.getDescriptions().iterator().next();
441
		}
442
	}
443

  
444
	private CommonTaxonName getCommonName(Element elTaxonRelationship, Map<String, CommonTaxonName> commonNameMap, ResultWrapper<Boolean> success){
445
		CommonTaxonName result = null;
446
		if (elTaxonRelationship == null || commonNameMap == null){
447
			success.setValue(false);
448
		}else{
449
			String childName = "ToTaxonConcept";
450
			boolean obligatory = true;
451
			Element elToTaxonConcept = XmlHelp.getSingleChildElement(success, elTaxonRelationship, childName, elTaxonRelationship.getNamespace(), obligatory);
452

  
453
			String linkType = elToTaxonConcept.getAttributeValue("linkType");
454
			if (linkType == null || linkType.equals("local")){
455
				String ref = elToTaxonConcept.getAttributeValue("ref");
456
				if (ref != null){
457
					result = commonNameMap.get(ref);
458
				}else{
459
					logger.warn("Non ref not yet implemented for vernacular name relationship");
460
				}
461
			}else{
462
				logger.warn("External link types for vernacular name not yet implemented");
463
			}
464
		}
465
		return result;
466
	}
467

  
468
	private void makeTaxonRelationship(TcsXmlImportState state, TaxonRelationshipType relType, TaxonBase fromTaxon, Taxon taxonTo, Reference citation, String microReference, ResultWrapper<Boolean> success){
469
		TaxonRelationshipType taxRelType = relType;
470
		if (! (fromTaxon instanceof Taxon )){
471
			logger.warn("TaxonBase fromTaxon " + /*strTaxonAbout +*/ "is not of Type 'Taxon'. Relationship is not added.");
472
			success.setValue(false);
473
		}else{
474
			Taxon taxonFrom = (Taxon)fromTaxon;
475
			if (relType.equals(TaxonRelationshipType.TAXONOMICALLY_INCLUDED_IN())){
476
				makeTaxonomicallyIncluded(state, taxonTo, taxonFrom, citation, microReference);
477
			}else{
478
				taxonFrom.addTaxonRelation(taxonTo, taxRelType, citation, microReference);
479
			}
480
		}
481
	}
482

  
483
	private boolean makeTaxonomicallyIncluded(TcsXmlImportState state, Taxon toTaxon, Taxon fromTaxon, Reference citation, String microCitation){
484
		Reference sec = toTaxon.getSec();
485
		Classification tree = state.getTree(sec);
486
		if (tree == null){
487
			tree = makeTree(state, sec);
488
		}
489
		TaxonNode childNode = tree.addParentChild(toTaxon, fromTaxon, citation, microCitation);
490
		return (childNode != null);
491
	}
492

  
493

  
494
	@SuppressWarnings("rawtypes")
495
	private TaxonBase getToTaxon(Element elTaxonRelationship, MapWrapper<TaxonBase> map, List<String> missingNameID,boolean isSynonym, ResultWrapper<Boolean> success, TcsXmlImportState state){
496
		TaxonBase result = null;
497
		if (elTaxonRelationship == null || map == null){
498
			success.setValue(false);
499
		}else{
500
			String childName = "ToTaxonConcept";
501
			boolean obligatory = true;
502
			Element elToTaxonConcept = XmlHelp.getSingleChildElement(success, elTaxonRelationship, childName, elTaxonRelationship.getNamespace(), obligatory);
503

  
504

  
505
			String linkType = elToTaxonConcept.getAttributeValue("linkType");
506
			if (linkType == null || linkType.equals("local")){
507
				String ref = elToTaxonConcept.getAttributeValue("ref");
508
				if (ref != null){
509
					result = map.get(ref);
510
					if (result == null && state.getConfig().isDoGetMissingNames()){
511

  
512

  
513
						String[] split= ref.split(":");
514
						String id = split[split.length-1];
515
						logger.info("get name for id " + id);
516
						if (missingNameID.contains(id)){
517
						    return null;
518
						}
519
						InputStream nameStream = service.getNamesById(id);
520

  
521

  
522
						try{
523
							String nameUri = "urn:lsid:ipni.org:names:"+ id;
524
							TaxonName name = rdfNameImport.handleRdfElementFromStream(nameStream, rdfConfig, (MapWrapper<TaxonName>)state.getStore(ICdmIO.TAXONNAME_STORE), nameUri);
525
							if (name != null){
526
								if (name.getTaxa().isEmpty()){
527

  
528
									result = Taxon.NewInstance(name, null);
529
								}else{
530
									result = (TaxonBase)name.getTaxa().iterator().next();
531
								}
532
								name.addSource(OriginalSourceType.Import, ref, "TaxonConcept", null, null);
533
								result.addSource(OriginalSourceType.Import, ref, "TaxonConcept", null, null);
534

  
535
								map.put(removeVersionOfRef(ref), result);
536
							} else{
537
							    missingNameID.add(id);
538
							}
539
						}catch(Exception e){
540
							logger.debug(e.getMessage());
541
							e.printStackTrace();
542
						}
543
					}
544
				}else{
545
					String title = elToTaxonConcept.getTextNormalize();
546
					//TODO synonym?
547
					TaxonName taxonName = TaxonNameFactory.NewNonViralInstance(null);
548
					taxonName.setTitleCache(title, true);
549
					logger.warn("Free text related taxon seems to be bug in TCS");
550
					if (isSynonym){
551
						result = Synonym.NewInstance(taxonName, TcsXmlTaxonImport.unknownSec());
552
					}else{
553
						result = Taxon.NewInstance(taxonName, TcsXmlTaxonImport.unknownSec());
554
					}
555
					result.setTitleCache(title, true);
556
				}
557
			}else{
558
				logger.warn("External link types for synonym not yet implemented");
559
			}
560
		}
561
		return result;
562
	}
563

  
564
	private boolean relationExists(Taxon taxonTo, Synonym synonym, SynonymType synRelType){
565
		if (synonym == null || taxonTo == null
566
		        || !taxonTo.equals(synonym.getAcceptedTaxon())){
567
			return false;
568
		}else{
569
		    return CdmUtils.nullSafeEqual(synonym.getType(),synRelType);
570
		}
571
	}
572

  
573
	private boolean makeHomotypicSynonymRelations(Taxon aboutTaxon){
574
		TaxonName aboutName = aboutTaxon.getName();
575
		if (aboutName != null){
576
			Set<TaxonName> typifiedNames = aboutName.getHomotypicalGroup().getTypifiedNames();
577
			for (TaxonName typifiedName : typifiedNames){
578
				//TODO check if name is part of this tcs file
579
				if (typifiedName.equals(aboutName)){
580
					continue;
581
				}
582
				Set<Synonym> syns = typifiedName.getSynonyms();
583
				for(Synonym syn:syns){
584
					aboutTaxon.addSynonym(syn, SynonymType.HOMOTYPIC_SYNONYM_OF());
585
				}
586
			}
587
		}
588
		return true;
589
	}
590

  
591
	@Override
592
    protected boolean isIgnore(TcsXmlImportState state){
593
		return ! state.getConfig().isDoRelTaxa();
594
	}
595
}
1
/**
2
* Copyright (C) 2009 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.tcsxml.in;
11

  
12
import java.io.InputStream;
13
import java.util.ArrayList;
14
import java.util.HashSet;
15
import java.util.List;
16
import java.util.Map;
17
import java.util.Set;
18

  
19
import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;
20
import org.jdom.Element;
21
import org.jdom.Namespace;
22
import org.springframework.beans.factory.annotation.Autowired;
23
import org.springframework.stereotype.Component;
24

  
25
import eu.etaxonomy.cdm.common.CdmUtils;
26
import eu.etaxonomy.cdm.common.ResultWrapper;
27
import eu.etaxonomy.cdm.common.XmlHelp;
28
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
29
import eu.etaxonomy.cdm.io.common.ICdmIO;
30
import eu.etaxonomy.cdm.io.common.MapWrapper;
31
import eu.etaxonomy.cdm.io.tcsrdf.TcsRdfImportConfigurator;
32
import eu.etaxonomy.cdm.io.tcsrdf.TcsRdfTaxonNameImport;
33
import eu.etaxonomy.cdm.io.tcsxml.TcsXmlTransformer;
34
import eu.etaxonomy.cdm.model.common.CdmBase;
35
import eu.etaxonomy.cdm.model.common.RelationshipTermBase;
36
import eu.etaxonomy.cdm.model.description.CommonTaxonName;
37
import eu.etaxonomy.cdm.model.description.TaxonDescription;
38
import eu.etaxonomy.cdm.model.name.TaxonName;
39
import eu.etaxonomy.cdm.model.name.TaxonNameFactory;
40
import eu.etaxonomy.cdm.model.reference.OriginalSourceType;
41
import eu.etaxonomy.cdm.model.reference.Reference;
42
import eu.etaxonomy.cdm.model.taxon.Classification;
43
import eu.etaxonomy.cdm.model.taxon.Synonym;
44
import eu.etaxonomy.cdm.model.taxon.SynonymType;
45
import eu.etaxonomy.cdm.model.taxon.Taxon;
46
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
47
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
48
import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
49
import eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException;
50

  
51

  
52
/**
53
 * @author a.mueller
54
 *
55
 */
56
@Component
57
public class TcsXmlTaxonRelationsImport extends TcsXmlImportBase implements ICdmIO<TcsXmlImportState> {
58
    private static final long serialVersionUID = 6632990505515905663L;
59

  
60
    private static final Logger logger = LogManager.getLogger(TcsXmlTaxonRelationsImport.class);
61

  
62
	private static int modCount = 30000;
63

  
64
	@Autowired
65
	private TcsRdfTaxonNameImport rdfNameImport;
66
	private TcsRdfImportConfigurator rdfConfig = TcsRdfImportConfigurator.NewInstance(null, null);
67

  
68
	public TcsXmlTaxonRelationsImport(){
69
		super();
70

  
71
	}
72

  
73
	@Override
74
	public boolean doCheck(TcsXmlImportState state){
75
		boolean result = true;
76
		logger.warn("Checking for TaxonRelations not yet implemented");
77
		logger.warn("Creation of homotypic relations is still problematic");
78
		//result &= checkArticlesWithoutJournal(bmiConfig);
79
		//result &= checkPartOfJournal(bmiConfig);
80

  
81
		return result;
82
	}
83

  
84
	@Override
85
	public void doInvoke(TcsXmlImportState state){
86

  
87

  
88
		logger.info("start make taxon relations ...");
89
		MapWrapper<TaxonBase> taxonMap = (MapWrapper<TaxonBase>)state.getStore(ICdmIO.TAXON_STORE);
90
		MapWrapper<TaxonName> taxonNameMap = (MapWrapper<TaxonName>)state.getStore(ICdmIO.TAXONNAME_STORE);
91
		MapWrapper<Reference> referenceMap = (MapWrapper<Reference>)state.getStore(ICdmIO.REFERENCE_STORE);
92

  
93
		Set<TaxonBase> taxonStore = new HashSet<TaxonBase>();
94

  
95
		ResultWrapper<Boolean> success = ResultWrapper.NewInstance(true);
96
		String childName;
97
		boolean obligatory;
98
		String idNamespace = "TaxonRelationDTO";
99

  
100
		TcsXmlImportConfigurator config = state.getConfig();
101
		Element elDataSet = super.getDataSetElement(config);
102
		Namespace tcsNamespace = config.getTcsXmlNamespace();
103

  
104
		childName = "TaxonConcepts";
105
		obligatory = false;
106
		Element elTaxonConcepts = XmlHelp.getSingleChildElement(success, elDataSet, childName, tcsNamespace, obligatory);
107

  
108
		childName = "TaxonConcept";
109
		List<Element> elTaxonConceptList =  elTaxonConcepts == null ? new ArrayList<Element>() : elTaxonConcepts.getChildren(childName, tcsNamespace);
110

  
111
		int i = 0;
112
		int taxonRelCount = 0;
113

  
114
		//for each taxonConcept
115
		logger.info("NUmber of taxon concepts: " + elTaxonConceptList.size());
116
		for (Element elTaxonConcept : elTaxonConceptList){
117
			if ((i++ % modCount) == 0){ logger.info("Taxa handled: " + (i-1));}
118
			taxonRelCount += makeTaxonConcept(state, taxonMap, taxonStore, elTaxonConcept, tcsNamespace, success);
119
		}//elTaxonConcept
120
		logger.info("Taxa handled: " + taxonStore.size());
121
		//TaxonRelationshipAssertions
122
		taxonRelCount += makeTaxonRelationshipAssertion(state, taxonMap, referenceMap, taxonStore, elDataSet, tcsNamespace, success);
123

  
124
		logger.info("Taxa to save: " + taxonStore.size());
125
		getTaxonService().save(taxonStore);
126

  
127
		//do basionym relationships
128
		childName = "TaxonNames";
129
		obligatory = false;
130
		Element elTaxonNames = XmlHelp.getSingleChildElement(success, elDataSet, childName, tcsNamespace, obligatory);
131

  
132
		childName = "TaxonName";
133
		List<Element> elTaxonNameList =  elTaxonNames == null ? new ArrayList<Element>() : elTaxonNames.getChildren(childName, tcsNamespace);
134

  
135
		logger.info("NUmber of taxon concepts: " + elTaxonNameList.size());
136
		for (Element elTaxonName : elTaxonNameList){
137
			if ((i++ % modCount) == 0){ logger.info("Taxa handled: " + (i-1));}
138
			taxonRelCount += makeBasionymRelations(state, taxonMap, taxonNameMap, taxonStore, elTaxonName, tcsNamespace, success);
139
		}//elTaxonConcept
140
		logger.info("Taxa handled: " + taxonStore.size());
141

  
142

  
143
		taxonStore = null;
144
		logger.info("end make taxon relations ...");
145
		if (!success.getValue()){
146
			state.setUnsuccessfull();
147
		}
148
		return;
149
	}
150

  
151
	private int makeBasionymRelations(TcsXmlImportState state,
152
			MapWrapper<TaxonBase> taxonMap, MapWrapper<TaxonName> taxonNameMap, Set<TaxonBase> taxonStore,
153
			Element elTaxonName, Namespace tcsNamespace,
154
			ResultWrapper<Boolean> success) {
155

  
156
		/*
157
		 * <tcs:Basionym>
158
				<tcs:RelatedName ref="urn:lsid:ipni.org:names:50000063-1">Caryophyllaceae</tcs:RelatedName>
159
			</tcs:Basionym>
160
		 */
161

  
162

  
163
		String childName = "Basionym";
164
		boolean obligatory = false;
165
		Element elBasionymRelationships = XmlHelp.getSingleChildElement(success, elTaxonName, childName, tcsNamespace, obligatory);
166
		if (elBasionymRelationships != null){
167
			childName = "RelatedName";
168
			obligatory = false;
169
			Element elBasionym = XmlHelp.getSingleChildElement(success, elBasionymRelationships, childName, tcsNamespace, obligatory);
170

  
171
			String id = elTaxonName.getAttributeValue("id");
172
			TaxonName name = taxonNameMap.get(removeVersionOfRef(id));
173

  
174
			TaxonBase taxonBase = (TaxonBase)name.getTaxonBases().iterator().next();
175

  
176
			String ref = elBasionym.getAttributeValue("ref");
177
			TaxonName basionymName = taxonNameMap.get(removeVersionOfRef(ref));
178

  
179
			if (basionymName != null){
180
				basionymName = HibernateProxyHelper.deproxy(basionymName, TaxonName.class);
181
				TaxonBase basionym;
182
				if (basionymName.getTaxonBases().isEmpty()){
183
					 basionym = Synonym.NewInstance(basionymName, null);
184
				}else{
185
					basionym = (TaxonBase)basionymName.getTaxonBases().iterator().next();
186
				}
187
				//Synonym basionymSyn;
188
				if (basionym instanceof Taxon){
189

  
190
					if (!(taxonBase instanceof Synonym)){
191
						logger.debug("The taxon " + basionymName.getTitleCache() + " is used in a concept and can not be a synonym " + name.getTitleCache() + "but will be added as basionym for the homotypical group");
192
						name.addBasionym(basionymName);
193
						//basionymName.getHomotypicalGroup().addTypifiedName(name);
194
					} else if (taxonBase instanceof Synonym){
195
						Synonym synonym = (Synonym) taxonBase;
196
						((Taxon)basionym).addSynonym(synonym, SynonymType.HOMOTYPIC_SYNONYM_OF());
197
						basionym.getHomotypicGroup().setGroupBasionym(basionymName);
198
						taxonStore.add(basionym);
199
					}
200
				}else{
201
					if (taxonBase instanceof Taxon){
202
						Synonym synonym = (Synonym) basionym;
203
						((Taxon)taxonBase).addSynonym(synonym, SynonymType.HOMOTYPIC_SYNONYM_OF());
204
						taxonBase.getHomotypicGroup().setGroupBasionym(basionymName);
205
						taxonStore.add(taxonBase);
206
					} else{
207
					    Taxon acc = ((Synonym)taxonBase).getAcceptedTaxon();
208
						if (acc != null){
209
							acc.addHomotypicSynonym((Synonym)basionym);
210
							basionymName.getHomotypicalGroup().setGroupBasionym(basionymName);
211
						}
212
					}
213
				}
214

  
215

  
216
			} else{
217
				basionymName = TaxonNameFactory.NewNonViralInstance(name.getRank());
218
				childName = "RelatedName";
219
				obligatory = true;
220
				Element elName = XmlHelp.getSingleChildElement(success, elBasionym, childName, tcsNamespace, obligatory);
221
				String strName = (elName == null)? "" : elName.getTextNormalize();
222
				basionymName.setTitleCache(strName, false);
223
				Synonym basionymSyn = Synonym.NewInstance(basionymName, unknownSec());
224
				if (taxonBase instanceof Taxon){
225
					Taxon taxon = (Taxon)taxonBase;
226
					taxon.addSynonym(basionymSyn, SynonymType.HOMOTYPIC_SYNONYM_OF());
227
					taxon.getHomotypicGroup().setGroupBasionym(basionymName);
228
					taxonStore.add(taxon);
229
				} else{
230
					Synonym syn = (Synonym) taxonBase;
231
					if (syn.getAcceptedTaxon() != null){
232
						Taxon accTaxon = syn.getAcceptedTaxon();
233
						accTaxon.addSynonym(basionymSyn, SynonymType.HOMOTYPIC_SYNONYM_OF());
234
						accTaxon.getHomotypicGroup().setGroupBasionym(basionymName);
235
						taxonStore.add(accTaxon);
236
					}
237
				}
238
			}
239
		}
240
		return 1;
241
	}
242

  
243
	private int makeTaxonConcept(TcsXmlImportState state, MapWrapper<TaxonBase> taxonMap, Set<TaxonBase> taxonStore, Element elTaxonConcept, Namespace tcsNamespace, ResultWrapper<Boolean> success){
244
		int taxonRelCount = 0;
245

  
246
		String childName = "TaxonRelationships";
247
		boolean obligatory = false;
248
		Element elTaxonRelationships = XmlHelp.getSingleChildElement(success, elTaxonConcept, childName, tcsNamespace, obligatory);
249

  
250
		if (elTaxonRelationships != null){
251
			//Relationships
252
			String tcsElementName = "TaxonRelationship";
253
			List<Element> elTaxonRelationshipList = elTaxonRelationships.getChildren(tcsElementName, tcsNamespace);
254
			logger.info("Number of taxonrelationships: " + elTaxonRelationshipList.size());
255
			for (Element elTaxonRelationship: elTaxonRelationshipList){
256

  
257
				taxonRelCount++;
258
				logger.debug("TaxonRelationship "+  taxonRelCount);
259

  
260
				String strId = elTaxonConcept.getAttributeValue("id");
261
				//TODO
262
//				String strConceptType = elTaxonConcept.getAttributeValue("type"); //original, revision, incomplete, aggregate, nominal
263
//				String strPrimary = elTaxonConcept.getAttributeValue("primary"); //If primary='true' the concept is the first level response to a query. If 'false' the concept may be a secondary concept linked directly or indirectly to the definition of a primary concept.
264
//				String strForm = elTaxonConcept.getAttributeValue("form");  //anamorph, teleomorph, hybrid
265

  
266
				TaxonBase fromTaxon = taxonMap.get(removeVersionOfRef(strId));
267
				makeRelationshipType(state, elTaxonRelationship, taxonMap, taxonStore, fromTaxon, success);
268

  
269
				if (fromTaxon instanceof Taxon){
270
					makeHomotypicSynonymRelations((Taxon)fromTaxon);
271
				}
272
			}// end Relationship
273
		}
274
		return taxonRelCount;
275
	}
276

  
277
	private int makeTaxonRelationshipAssertion(
278
			TcsXmlImportState state,
279
			MapWrapper<TaxonBase> taxonMap,
280
			MapWrapper<Reference> referenceMap,
281
			Set<TaxonBase> taxonStore,
282
			Element elDataSet,
283
			Namespace tcsNamespace,
284
			ResultWrapper<Boolean> success){
285

  
286
		int i = 0;
287
		String childName = "TaxonRelationshipAssertions";
288
		boolean obligatory = false;
289
		Element elTaxonRelationshipAssertions = XmlHelp.getSingleChildElement(success, elDataSet, childName, tcsNamespace, obligatory);
290
		if(elTaxonRelationshipAssertions == null){
291
			return 0;
292
		}
293

  
294
		childName = "TaxonRelationshipAssertion";
295
		List<Element> elTaxonRelationshipAssertionList = elTaxonRelationshipAssertions.getChildren(childName, tcsNamespace);
296
		//for each taxon relationship assertion
297
		for (Element elTaxonRelationshipAssertion : elTaxonRelationshipAssertionList){
298
			if ((i++ % modCount) == 0){ logger.info("TaxonRelationshipAssertions handled: " + (i-1));}
299
			String strId = elTaxonRelationshipAssertion.getAttributeValue("id");
300
			//TODO id
301

  
302
			childName = "AccordingTo";
303
			obligatory = true;
304
			Element elAccordingTo = XmlHelp.getSingleChildElement(success, elTaxonRelationshipAssertion, childName, tcsNamespace, obligatory);
305
			Reference ref = makeAccordingTo(elAccordingTo, referenceMap, success);
306

  
307
			childName = "FromTaxonConcept";
308
			obligatory = true;
309
			Element elFromTaxonConcept = XmlHelp.getSingleChildElement(success, elTaxonRelationshipAssertion, childName, tcsNamespace, obligatory);
310

  
311
			Class<? extends TaxonBase> clazz = Taxon.class;
312
			//TODO if synonym
313
			TaxonBase fromTaxon = makeReferenceType(elFromTaxonConcept, clazz, taxonMap, success);
314

  
315
			makeRelationshipType(state, elTaxonRelationshipAssertion, taxonMap, taxonStore, fromTaxon, success);
316
		}//elTaxonRelationshipAssertion
317

  
318
		return i;
319
	}
320

  
321

  
322
	/**
323
	 * Handles the TCS RelationshipType element.
324
	 * @param tcsConfig
325
	 * @param elRelationship
326
	 * @param taxonMap
327
	 * @param taxonStore
328
	 * @param fromTaxon
329
	 * @param success
330
	 */
331
	private void makeRelationshipType(
332
			TcsXmlImportState state
333
			, Element elRelationship
334
			, MapWrapper<TaxonBase> taxonMap
335
			, Set<TaxonBase> taxonStore
336
			, TaxonBase fromTaxon
337
			, ResultWrapper<Boolean> success
338
			){
339

  
340
		if (elRelationship == null){
341
			success.setValue(false);
342
		}
343
		String strRelType = elRelationship.getAttributeValue("type");
344

  
345

  
346
		try {
347
			ResultWrapper<Boolean> isInverse = new ResultWrapper<Boolean>();
348
			isInverse.setValue(false);
349
			if ("has vernacular".equalsIgnoreCase(strRelType)){
350
				handleVernacular(success, state, elRelationship, fromTaxon);
351
			}else{
352
				RelationshipTermBase<?> relType = TcsXmlTransformer.tcsRelationshipType2Relationship(strRelType, isInverse);
353

  
354
				//toTaxon (should be part of relationshipType)
355
				boolean isSynonym = (relType instanceof SynonymType);
356
				TaxonBase toTaxon = getToTaxon(elRelationship, taxonMap, state.getMissingConceptLSIDs(), isSynonym, success, state);
357

  
358
				if (toTaxon != null && fromTaxon != null){
359
					//exchange taxa if relationship is inverse
360
					if (isInverse.getValue() == true ){
361
						TaxonBase tmp = toTaxon;
362
						toTaxon = fromTaxon;
363
						fromTaxon = tmp;
364
					}
365

  
366
					//Create relationship
367
					if (! (toTaxon instanceof Taxon)){
368
						logger.warn("TaxonBase toTaxon is not of Type 'Taxon'. Relationship is not added.");
369
						success.setValue(false);
370
					}else{
371
						Taxon taxonTo = (Taxon)toTaxon;
372
						if (relType instanceof SynonymType){
373
							SynonymType synRelType = (SynonymType)relType;
374
							if (! (fromTaxon instanceof Synonym )){
375
								logger.warn("TaxonBase fromTaxon is not of Type 'Synonym'. Relationship is not added.");
376
								success.setValue(false);
377
							}else{
378
								Synonym synonym = (Synonym)fromTaxon;
379
								TaxonName synName = synonym.getName();
380
								TaxonName accName = taxonTo.getName();
381
								if (synName != null && accName != null && synName.isHomotypic(accName)
382
											&& ( synRelType.equals(SynonymType.SYNONYM_OF()))){
383
									synRelType = SynonymType.HOMOTYPIC_SYNONYM_OF();
384
								}
385
								if (! relationExists(taxonTo, synonym, synRelType)){
386
									taxonTo.addSynonym(synonym, synRelType);
387
								}else{
388
									//TODO citation, microReference
389
									//TODO different synRelTypes -> warning
390
									success.setValue(false);
391
								}
392
							}
393
						}else if (relType instanceof TaxonRelationshipType){
394
							Reference citation = null;
395
							String microReference = null;
396
						    makeTaxonRelationship(state, (TaxonRelationshipType)relType, fromTaxon, taxonTo, citation, microReference, success);
397
						}else{
398
							logger.warn("Unknown Relationshiptype");
399
							success.setValue(false);
400
						}
401
						taxonStore.add(toTaxon);
402
					}
403
				}else{
404
					if (toTaxon == null){
405
					//	logger.warn("toTaxon (" + /*strToTaxon + */ ") could  not be found in taxonMap. Relationship of type " + strRelType + " was not added to CDM");
406
					}
407
					if (fromTaxon == null){
408
					//	logger.warn("fromTaxon (" + /*strTaxonAbout + */") could not be found in taxonMap. Relationship was not added to CDM");
409
					}
410
					success.setValue(false);
411
				}
412
			}
413
		} catch (UnknownCdmTypeException e) {
414
			//TODO
415
			logger.warn("relationshipType " + strRelType + " not yet implemented");
416
			success.setValue(false);
417
		}
418
		return;
419
	}
420

  
421
	private void handleVernacular(ResultWrapper<Boolean> success, TcsXmlImportState state, Element elRelationship, TaxonBase taxonBase) {
422
		if (! taxonBase.isInstanceOf(Taxon.class)){
423
			logger.warn("From Taxon is not of type Taxon but of type " +  taxonBase.getClass().getSimpleName());
424
			success.setValue(false);
425
			return;
426
		}else{
427
			Taxon taxon = CdmBase.deproxy(taxonBase, Taxon.class);
428
			Map<String, CommonTaxonName> commonNameMap = state.getCommonNameMap();
429
			CommonTaxonName commonTaxonName = getCommonName(elRelationship, commonNameMap, success);
430
			TaxonDescription description = getDescription(taxon);
431
			description.addElement(commonTaxonName);
432
		}
433
	}
434

  
435
	private TaxonDescription getDescription(Taxon taxon) {
436
		if (taxon.getDescriptions().isEmpty()){
437
			return TaxonDescription.NewInstance(taxon);
438
		}else{
439
			//TODO only if the description represents this TCS file
440
			return taxon.getDescriptions().iterator().next();
441
		}
442
	}
443

  
444
	private CommonTaxonName getCommonName(Element elTaxonRelationship, Map<String, CommonTaxonName> commonNameMap, ResultWrapper<Boolean> success){
445
		CommonTaxonName result = null;
446
		if (elTaxonRelationship == null || commonNameMap == null){
447
			success.setValue(false);
448
		}else{
449
			String childName = "ToTaxonConcept";
450
			boolean obligatory = true;
451
			Element elToTaxonConcept = XmlHelp.getSingleChildElement(success, elTaxonRelationship, childName, elTaxonRelationship.getNamespace(), obligatory);
452

  
453
			String linkType = elToTaxonConcept.getAttributeValue("linkType");
454
			if (linkType == null || linkType.equals("local")){
455
				String ref = elToTaxonConcept.getAttributeValue("ref");
456
				if (ref != null){
457
					result = commonNameMap.get(ref);
458
				}else{
459
					logger.warn("Non ref not yet implemented for vernacular name relationship");
460
				}
461
			}else{
462
				logger.warn("External link types for vernacular name not yet implemented");
463
			}
464
		}
465
		return result;
466
	}
467

  
468
	private void makeTaxonRelationship(TcsXmlImportState state, TaxonRelationshipType relType, TaxonBase fromTaxon, Taxon taxonTo, Reference citation, String microReference, ResultWrapper<Boolean> success){
469
		TaxonRelationshipType taxRelType = relType;
470
		if (! (fromTaxon instanceof Taxon )){
471
			logger.warn("TaxonBase fromTaxon " + /*strTaxonAbout +*/ "is not of Type 'Taxon'. Relationship is not added.");
472
			success.setValue(false);
473
		}else{
474
			Taxon taxonFrom = (Taxon)fromTaxon;
475
			if (relType.equals(TaxonRelationshipType.TAXONOMICALLY_INCLUDED_IN())){
476
				makeTaxonomicallyIncluded(state, taxonTo, taxonFrom, citation, microReference);
477
			}else{
478
				taxonFrom.addTaxonRelation(taxonTo, taxRelType, citation, microReference);
479
			}
480
		}
481
	}
482

  
483
	private boolean makeTaxonomicallyIncluded(TcsXmlImportState state, Taxon toTaxon, Taxon fromTaxon, Reference citation, String microCitation){
484
		Reference sec = toTaxon.getSec();
485
		Classification tree = state.getTree(sec);
486
		if (tree == null){
487
			tree = makeTree(state, sec);
488
		}
489
		TaxonNode childNode = tree.addParentChild(toTaxon, fromTaxon, citation, microCitation);
490
		return (childNode != null);
491
	}
492

  
493

  
494
	@SuppressWarnings("rawtypes")
495
	private TaxonBase getToTaxon(Element elTaxonRelationship, MapWrapper<TaxonBase> map, List<String> missingNameID,boolean isSynonym, ResultWrapper<Boolean> success, TcsXmlImportState state){
496
		TaxonBase result = null;
497
		if (elTaxonRelationship == null || map == null){
498
			success.setValue(false);
499
		}else{
500
			String childName = "ToTaxonConcept";
501
			boolean obligatory = true;
502
			Element elToTaxonConcept = XmlHelp.getSingleChildElement(success, elTaxonRelationship, childName, elTaxonRelationship.getNamespace(), obligatory);
503

  
504

  
505
			String linkType = elToTaxonConcept.getAttributeValue("linkType");
506
			if (linkType == null || linkType.equals("local")){
507
				String ref = elToTaxonConcept.getAttributeValue("ref");
508
				if (ref != null){
509
					result = map.get(ref);
510
					if (result == null && state.getConfig().isDoGetMissingNames()){
511

  
512

  
513
						String[] split= ref.split(":");
514
						String id = split[split.length-1];
515
						logger.info("get name for id " + id);
516
						if (missingNameID.contains(id)){
517
						    return null;
518
						}
519
						InputStream nameStream = service.getNamesById(id);
520

  
521

  
522
						try{
523
							String nameUri = "urn:lsid:ipni.org:names:"+ id;
524
							TaxonName name = rdfNameImport.handleRdfElementFromStream(nameStream, rdfConfig, (MapWrapper<TaxonName>)state.getStore(ICdmIO.TAXONNAME_STORE), nameUri);
525
							if (name != null){
526
								if (name.getTaxa().isEmpty()){
527

  
528
									result = Taxon.NewInstance(name, null);
529
								}else{
530
									result = (TaxonBase)name.getTaxa().iterator().next();
531
								}
532
								name.addSource(OriginalSourceType.Import, ref, "TaxonConcept", null, null);
533
								result.addSource(OriginalSourceType.Import, ref, "TaxonConcept", null, null);
534

  
535
								map.put(removeVersionOfRef(ref), result);
536
							} else{
537
							    missingNameID.add(id);
538
							}
539
						}catch(Exception e){
540
							logger.debug(e.getMessage());
541
							e.printStackTrace();
542
						}
543
					}
544
				}else{
545
					String title = elToTaxonConcept.getTextNormalize();
546
					//TODO synonym?
547
					TaxonName taxonName = TaxonNameFactory.NewNonViralInstance(null);
548
					taxonName.setTitleCache(title, true);
549
					logger.warn("Free text related taxon seems to be bug in TCS");
550
					if (isSynonym){
551
						result = Synonym.NewInstance(taxonName, TcsXmlTaxonImport.unknownSec());
552
					}else{
553
						result = Taxon.NewInstance(taxonName, TcsXmlTaxonImport.unknownSec());
554
					}
555
					result.setTitleCache(title, true);
556
				}
557
			}else{
558
				logger.warn("External link types for synonym not yet implemented");
559
			}
560
		}
561
		return result;
562
	}
563

  
564
	private boolean relationExists(Taxon taxonTo, Synonym synonym, SynonymType synRelType){
565
		if (synonym == null || taxonTo == null
566
		        || !taxonTo.equals(synonym.getAcceptedTaxon())){
567
			return false;
568
		}else{
569
		    return CdmUtils.nullSafeEqual(synonym.getType(),synRelType);
570
		}
571
	}
572

  
573
	private boolean makeHomotypicSynonymRelations(Taxon aboutTaxon){
574
		TaxonName aboutName = aboutTaxon.getName();
575
		if (aboutName != null){
576
			Set<TaxonName> typifiedNames = aboutName.getHomotypicalGroup().getTypifiedNames();
577
			for (TaxonName typifiedName : typifiedNames){
578
				//TODO check if name is part of this tcs file
579
				if (typifiedName.equals(aboutName)){
580
					continue;
581
				}
582
				Set<Synonym> syns = typifiedName.getSynonyms();
583
				for(Synonym syn:syns){
584
					aboutTaxon.addSynonym(syn, SynonymType.HOMOTYPIC_SYNONYM_OF());
585
				}
586
			}
587
		}
588
		return true;
589
	}
590

  
591
	@Override
592
    protected boolean isIgnore(TcsXmlImportState state){
593
		return ! state.getConfig().isDoRelTaxa();
594
	}
595
}

Also available in: Unified diff