4 package eu
.etaxonomy
.cdm
.io
.tcsxml
.in
;
6 import java
.util
.HashSet
;
10 import org
.apache
.log4j
.Logger
;
11 import org
.jdom
.Element
;
12 import org
.jdom
.Namespace
;
13 import org
.springframework
.stereotype
.Component
;
15 import eu
.etaxonomy
.cdm
.common
.ResultWrapper
;
16 import eu
.etaxonomy
.cdm
.common
.XmlHelp
;
17 import eu
.etaxonomy
.cdm
.io
.common
.ICdmIO
;
18 import eu
.etaxonomy
.cdm
.io
.common
.MapWrapper
;
19 import eu
.etaxonomy
.cdm
.io
.tcsxml
.TcsXmlTransformer
;
20 import eu
.etaxonomy
.cdm
.model
.common
.RelationshipTermBase
;
21 import eu
.etaxonomy
.cdm
.model
.name
.NonViralName
;
22 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameBase
;
23 import eu
.etaxonomy
.cdm
.model
.reference
.ReferenceBase
;
24 import eu
.etaxonomy
.cdm
.model
.taxon
.Synonym
;
25 import eu
.etaxonomy
.cdm
.model
.taxon
.SynonymRelationshipType
;
26 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
27 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
28 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonRelationshipType
;
29 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonomicTree
;
30 import eu
.etaxonomy
.cdm
.strategy
.exceptions
.UnknownCdmTypeException
;
38 public class TcsXmlTaxonRelationsImport
extends TcsXmlImportBase
implements ICdmIO
<TcsXmlImportState
> {
39 private static final Logger logger
= Logger
.getLogger(TcsXmlTaxonRelationsImport
.class);
41 private static int modCount
= 30000;
43 public TcsXmlTaxonRelationsImport(){
48 public boolean doCheck(TcsXmlImportState state
){
49 boolean result
= true;
50 logger
.warn("Checking for TaxonRelations not yet implemented");
51 logger
.warn("Creation of homotypic relations is still problematic");
52 //result &= checkArticlesWithoutJournal(bmiConfig);
53 //result &= checkPartOfJournal(bmiConfig);
59 public boolean doInvoke(TcsXmlImportState state
){
62 logger
.info("start make taxon relations ...");
63 MapWrapper
<TaxonBase
> taxonMap
= (MapWrapper
<TaxonBase
>)state
.getStore(ICdmIO
.TAXON_STORE
);
64 MapWrapper
<TaxonNameBase
<?
,?
>> taxonNameMap
= (MapWrapper
<TaxonNameBase
<?
,?
>>)state
.getStore(ICdmIO
.TAXONNAME_STORE
);
65 MapWrapper
<ReferenceBase
> referenceMap
= (MapWrapper
<ReferenceBase
>)state
.getStore(ICdmIO
.REFERENCE_STORE
);
67 Set
<TaxonBase
> taxonStore
= new HashSet
<TaxonBase
>();
69 ResultWrapper
<Boolean
> success
= ResultWrapper
.NewInstance(true);
72 String idNamespace
= "TaxonRelation";
74 TcsXmlImportConfigurator config
= state
.getConfig();
75 Element elDataSet
= super.getDataSetElement(config
);
76 Namespace tcsNamespace
= config
.getTcsXmlNamespace();
78 childName
= "TaxonConcepts";
80 Element elTaxonConcepts
= XmlHelp
.getSingleChildElement(success
, elDataSet
, childName
, tcsNamespace
, obligatory
);
82 childName
= "TaxonConcept";
83 List
<Element
> elTaxonConceptList
= elTaxonConcepts
.getChildren(childName
, tcsNamespace
);
86 int taxonRelCount
= 0;
88 //for each taxonConcept
89 for (Element elTaxonConcept
: elTaxonConceptList
){
90 if ((i
++ % modCount
) == 0){ logger
.info("Taxa handled: " + (i
-1));}
91 taxonRelCount
+= makeTaxonConcept(state
, taxonMap
, taxonStore
, elTaxonConcept
, tcsNamespace
, success
);
94 //TaxonRelationshipAssertions
95 taxonRelCount
+= makeTaxonRelationshipAssertion(state
, taxonMap
, referenceMap
, taxonStore
, elDataSet
, tcsNamespace
, success
);
97 logger
.info("Taxa to save: " + taxonStore
.size());
98 getTaxonService().save(taxonStore
);
100 logger
.info("end make taxon relations ...");
101 return success
.getValue();
104 private int makeTaxonConcept(TcsXmlImportState state
, MapWrapper
<TaxonBase
> taxonMap
, Set
<TaxonBase
> taxonStore
, Element elTaxonConcept
, Namespace tcsNamespace
, ResultWrapper
<Boolean
> success
){
105 int taxonRelCount
= 0;
107 String childName
= "TaxonRelationships";
108 boolean obligatory
= false;
109 Element elTaxonRelationships
= XmlHelp
.getSingleChildElement(success
, elTaxonConcept
, childName
, tcsNamespace
, obligatory
);
111 if (elTaxonRelationships
!= null){
113 String tcsElementName
= "TaxonRelationship";
114 List
<Element
> elTaxonRelationshipList
= elTaxonRelationships
.getChildren(tcsElementName
, tcsNamespace
);
116 for (Element elTaxonRelationship
: elTaxonRelationshipList
){
118 logger
.debug("TaxonRelationship "+ taxonRelCount
);
120 String strId
= elTaxonConcept
.getAttributeValue("id");
122 // String strConceptType = elTaxonConcept.getAttributeValue("type"); //original, revision, incomplete, aggregate, nominal
123 // 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.
124 // String strForm = elTaxonConcept.getAttributeValue("form"); //anamorph, teleomorph, hybrid
126 TaxonBase fromTaxon
= taxonMap
.get(strId
);
127 makeRelationshipType(state
, elTaxonRelationship
, taxonMap
, taxonStore
, fromTaxon
, success
);
129 if (fromTaxon
instanceof Taxon
){
130 makeHomotypicSynonymRelations((Taxon
)fromTaxon
);
134 return taxonRelCount
;
137 private int makeTaxonRelationshipAssertion(
138 TcsXmlImportState state
,
139 MapWrapper
<TaxonBase
> taxonMap
,
140 MapWrapper
<ReferenceBase
> referenceMap
,
141 Set
<TaxonBase
> taxonStore
,
143 Namespace tcsNamespace
,
144 ResultWrapper
<Boolean
> success
){
147 String childName
= "TaxonRelationshipAssertions";
148 boolean obligatory
= false;
149 Element elTaxonRelationshipAssertions
= XmlHelp
.getSingleChildElement(success
, elDataSet
, childName
, tcsNamespace
, obligatory
);
150 if(elTaxonRelationshipAssertions
== null){
154 childName
= "TaxonRelationshipAssertion";
155 List
<Element
> elTaxonRelationshipAssertionList
= elTaxonRelationshipAssertions
.getChildren(childName
, tcsNamespace
);
156 //for each taxon relationship assertion
157 for (Element elTaxonRelationshipAssertion
: elTaxonRelationshipAssertionList
){
158 if ((i
++ % modCount
) == 0){ logger
.info("TaxonRelationshipAssertions handled: " + (i
-1));}
159 String strId
= elTaxonRelationshipAssertion
.getAttributeValue("id");
162 childName
= "AccordingTo";
164 Element elAccordingTo
= XmlHelp
.getSingleChildElement(success
, elTaxonRelationshipAssertion
, childName
, tcsNamespace
, obligatory
);
165 ReferenceBase ref
= makeAccordingTo(elAccordingTo
, referenceMap
, success
);
167 childName
= "FromTaxonConcept";
169 Element elFromTaxonConcept
= XmlHelp
.getSingleChildElement(success
, elTaxonRelationshipAssertion
, childName
, tcsNamespace
, obligatory
);
171 Class
<?
extends TaxonBase
> clazz
= Taxon
.class;
173 TaxonBase fromTaxon
= makeReferenceType(elFromTaxonConcept
, clazz
, taxonMap
, success
);
175 makeRelationshipType(state
, elTaxonRelationshipAssertion
, taxonMap
, taxonStore
, fromTaxon
, success
);
176 }//elTaxonRelationshipAssertion
183 * Handles the TCS RelationshipType element.
185 * @param elRelationship
191 private void makeRelationshipType(
192 TcsXmlImportState state
193 , Element elRelationship
194 , MapWrapper
<TaxonBase
> taxonMap
195 , Set
<TaxonBase
> taxonStore
196 , TaxonBase fromTaxon
197 , ResultWrapper
<Boolean
> success
200 if (elRelationship
== null){
201 success
.setValue(false);
203 String strRelType
= elRelationship
.getAttributeValue("type");
207 ResultWrapper
<Boolean
> isInverse
= new ResultWrapper
<Boolean
>();
208 isInverse
.setValue(false);
209 RelationshipTermBase
<?
> relType
= TcsXmlTransformer
.tcsRelationshipType2Relationship(strRelType
, isInverse
);
211 //toTaxon (should be part of relationshipType)
212 boolean isSynonym
= (relType
instanceof SynonymRelationshipType
);
213 TaxonBase toTaxon
= getToTaxon(elRelationship
, taxonMap
, isSynonym
, success
);
215 if (toTaxon
!= null && fromTaxon
!= null){
216 //exchange taxa if relationship is inverse
217 if (isInverse
.getValue() == true ){
218 TaxonBase tmp
= toTaxon
;
223 //Create relationship
224 if (! (toTaxon
instanceof Taxon
)){
225 logger
.warn("TaxonBase toTaxon is not of Type 'Taxon'. Relationship is not added.");
226 success
.setValue(false);
228 Taxon taxonTo
= (Taxon
)toTaxon
;
229 ReferenceBase citation
= null;
230 String microReference
= null;
231 if (relType
instanceof SynonymRelationshipType
){
232 SynonymRelationshipType synRelType
= (SynonymRelationshipType
)relType
;
233 if (! (fromTaxon
instanceof Synonym
)){
234 logger
.warn("TaxonBase fromTaxon is not of Type 'Synonym'. Relationship is not added.");
235 success
.setValue(false);
237 Synonym synonym
= (Synonym
)fromTaxon
;
238 TaxonNameBase
<?
,?
> synName
= synonym
.getName();
239 TaxonNameBase
<?
,?
> accName
= taxonTo
.getName();
240 if (synName
!= null && accName
!= null && synName
.isHomotypic(accName
)
241 && ( synRelType
.equals(SynonymRelationshipType
.SYNONYM_OF()))){
242 synRelType
= SynonymRelationshipType
.HOMOTYPIC_SYNONYM_OF();
244 if (! relationExists(taxonTo
, synonym
, synRelType
)){
245 taxonTo
.addSynonym(synonym
, synRelType
, citation
, microReference
);
247 //TODO citation, microReference
248 //TODO different synRelTypes -> warning
249 success
.setValue(false);
252 }else if (relType
instanceof TaxonRelationshipType
){
253 makeTaxonRelationship(state
, (TaxonRelationshipType
)relType
, fromTaxon
, taxonTo
, citation
, microReference
, success
);
255 logger
.warn("Unknown Relationshiptype");
256 success
.setValue(false);
258 taxonStore
.add(toTaxon
);
261 if (toTaxon
== null){
262 logger
.warn("toTaxon (" + /*strToTaxon + */ ") could not be found in taxonMap. Relationship of type " + strRelType
+ " was not added to CDM");
264 if (fromTaxon
== null){
265 logger
.warn("fromTaxon (" + /*strTaxonAbout + */") could not be found in taxonMap. Relationship was not added to CDM");
267 success
.setValue(false);
270 } catch (UnknownCdmTypeException e
) {
272 logger
.warn("relationshipType " + strRelType
+ " not yet implemented");
273 success
.setValue(false);
278 private void makeTaxonRelationship(TcsXmlImportState state
, TaxonRelationshipType relType
, TaxonBase fromTaxon
, Taxon taxonTo
, ReferenceBase citation
, String microReference
, ResultWrapper
<Boolean
> success
){
279 TaxonRelationshipType taxRelType
= (TaxonRelationshipType
)relType
;
280 if (! (fromTaxon
instanceof Taxon
)){
281 logger
.warn("TaxonBase fromTaxon " + /*strTaxonAbout +*/ "is not of Type 'Taxon'. Relationship is not added.");
282 success
.setValue(false);
284 Taxon taxonFrom
= (Taxon
)fromTaxon
;
285 if (relType
.equals(TaxonRelationshipType
.TAXONOMICALLY_INCLUDED_IN())){
286 makeTaxonomicallyIncluded(state
, taxonTo
, taxonFrom
, citation
, microReference
);
288 taxonFrom
.addTaxonRelation(taxonTo
, taxRelType
, citation
, microReference
);
292 private boolean makeTaxonomicallyIncluded(TcsXmlImportState state
, Taxon toTaxon
, Taxon fromTaxon
, ReferenceBase citation
, String microCitation
){
293 boolean success
= true;
294 ReferenceBase sec
= toTaxon
.getSec();
295 TaxonomicTree tree
= state
.getTree(sec
);
297 tree
= makeTree(state
, sec
);
299 success
= tree
.addParentChild(toTaxon
, fromTaxon
, citation
, microCitation
);
304 private TaxonBase
getToTaxon(Element elTaxonRelationship
, MapWrapper
<TaxonBase
> map
, boolean isSynonym
, ResultWrapper
<Boolean
> success
){
305 TaxonBase result
= null;
306 if (elTaxonRelationship
== null || map
== null){
307 success
.setValue(false);
309 String childName
= "ToTaxonConcept";
310 boolean obligatory
= true;
311 Element elToTaxonConcept
= XmlHelp
.getSingleChildElement(success
, elTaxonRelationship
, childName
, elTaxonRelationship
.getNamespace(), obligatory
);
313 String linkType
= elToTaxonConcept
.getAttributeValue("linkType");
314 if (linkType
== null || linkType
.equals("local")){
315 String ref
= elToTaxonConcept
.getAttributeValue("ref");
317 result
= map
.get(ref
);
319 String title
= elToTaxonConcept
.getTextNormalize();
321 TaxonNameBase
<?
,?
> taxonName
= NonViralName
.NewInstance(null);
322 taxonName
.setTitleCache(title
);
323 logger
.warn("Free text related taxon seems to be bug in TCS");
325 result
= Synonym
.NewInstance(taxonName
, TcsXmlTaxonImport
.unknownSec());
327 result
= Taxon
.NewInstance(taxonName
, TcsXmlTaxonImport
.unknownSec());
329 result
.setTitleCache(title
);
332 logger
.warn("External link types for synonym not yet implemented");
342 private boolean relationExists(Taxon taxonTo
, Synonym synonym
, SynonymRelationshipType synRelType
){
343 if (synonym
== null){
346 if (synonym
.getRelationType(taxonTo
).size() > 0){
347 Set
<SynonymRelationshipType
> relTypeList
= synonym
.getRelationType(taxonTo
);
348 if (relTypeList
.contains(synRelType
)){
351 logger
.warn("Taxon-Synonym pair has 2 different SynonymRelationships. This is against the rules");
359 private boolean makeHomotypicSynonymRelations(Taxon aboutTaxon
){
360 TaxonNameBase
<?
,?
> aboutName
= aboutTaxon
.getName();
361 if (aboutName
!= null){
362 Set
<TaxonNameBase
> typifiedNames
= aboutName
.getHomotypicalGroup().getTypifiedNames();
363 for (TaxonNameBase
<?
,?
> typifiedName
: typifiedNames
){
364 //TODO check if name is part of this tcs file
365 if (typifiedName
.equals(aboutName
)){
368 Set
<Synonym
> syns
= typifiedName
.getSynonyms();
369 for(Synonym syn
:syns
){
370 aboutTaxon
.addSynonym(syn
, SynonymRelationshipType
.HOMOTYPIC_SYNONYM_OF());
378 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IImportConfigurator)
380 protected boolean isIgnore(TcsXmlImportState state
){
381 return ! state
.getConfig().isDoRelTaxa();