2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
9 package eu
.etaxonomy
.cdm
.io
.taxonx
;
11 import java
.util
.ArrayList
;
12 import java
.util
.HashMap
;
13 import java
.util
.List
;
17 import org
.apache
.log4j
.Logger
;
18 import org
.jdom
.Element
;
19 import org
.jdom
.Namespace
;
20 import org
.springframework
.stereotype
.Component
;
21 import org
.springframework
.transaction
.TransactionStatus
;
23 import eu
.etaxonomy
.cdm
.api
.service
.ICommonService
;
24 import eu
.etaxonomy
.cdm
.api
.service
.INameService
;
25 import eu
.etaxonomy
.cdm
.api
.service
.ITaxonService
;
26 import eu
.etaxonomy
.cdm
.common
.CdmUtils
;
27 import eu
.etaxonomy
.cdm
.io
.common
.CdmIoBase
;
28 import eu
.etaxonomy
.cdm
.io
.common
.ICdmIO
;
29 import eu
.etaxonomy
.cdm
.io
.common
.IImportConfigurator
;
30 import eu
.etaxonomy
.cdm
.io
.common
.MapWrapper
;
31 import eu
.etaxonomy
.cdm
.model
.agent
.AgentBase
;
32 import eu
.etaxonomy
.cdm
.model
.agent
.Person
;
33 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
34 import eu
.etaxonomy
.cdm
.model
.name
.NonViralName
;
35 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameBase
;
36 import eu
.etaxonomy
.cdm
.model
.name
.TypeDesignationStatus
;
37 import eu
.etaxonomy
.cdm
.model
.occurrence
.Specimen
;
38 import eu
.etaxonomy
.cdm
.model
.reference
.ReferenceBase
;
39 import eu
.etaxonomy
.cdm
.model
.taxon
.Synonym
;
40 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
41 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
50 public class TaxonXNomenclatureImport
extends CdmIoBase
<IImportConfigurator
> implements ICdmIO
<IImportConfigurator
> {
51 private static final Logger logger
= Logger
.getLogger(TaxonXNomenclatureImport
.class);
53 @SuppressWarnings("unused")
54 private static int modCount
= 10000;
56 public TaxonXNomenclatureImport(){
60 public boolean doCheck(IImportConfigurator config
){
62 boolean result
= true;
63 logger
.warn("Checking for Types not yet implemented");
64 //result &= checkArticlesWithoutJournal(bmiConfig);
65 //result &= checkPartOfJournal(bmiConfig);
70 public boolean doInvoke(IImportConfigurator config
, Map
<String
, MapWrapper
<?
extends CdmBase
>> stores
){
71 logger
.info("start make Nomenclature ...");
73 TransactionStatus tx
= startTransaction();
74 TaxonXImportConfigurator txConfig
= (TaxonXImportConfigurator
)config
;
75 Element root
= txConfig
.getSourceRoot();
76 Namespace nsTaxonx
= root
.getNamespace();
79 Taxon taxon
= getTaxon(txConfig
);
80 boolean isChanged
= false;
82 Element elTaxonBody
= root
.getChild("taxonxBody", nsTaxonx
);
83 Element elTreatment
= elTaxonBody
.getChild("treatment", nsTaxonx
);
84 Element elNomenclature
= elTreatment
.getChild("nomenclature", nsTaxonx
);
86 //isChanged |= doCollectionEvent(txConfig, elNomenclature, nsTaxonx, taxon);
88 if (taxon
!= null && taxon
.getName() != null && elNomenclature
!= null){
89 isChanged
|= doNomenclaturalType(txConfig
, elNomenclature
, nsTaxonx
, taxon
.getName());
90 List
<Element
> elSynonymyList
= new ArrayList
<Element
>();
91 elSynonymyList
.addAll(elNomenclature
.getChildren("synonomy", nsTaxonx
));
92 elSynonymyList
.addAll(elNomenclature
.getChildren("synonymy", nsTaxonx
)); //wrong spelling in TaxonX-Schema
93 for (Element elSynonymy
: elSynonymyList
){
94 String synonymName
= elSynonymy
.getChildTextTrim("name");
95 if (elSynonymy
.getChild("type", nsTaxonx
) != null || elSynonymy
.getChild("type_loc", nsTaxonx
) != null){
96 Synonym synonym
= getSynonym(txConfig
, taxon
, synonymName
);
98 isChanged
|= doNomenclaturalType(txConfig
, elSynonymy
, nsTaxonx
, synonym
.getName());
106 getTaxonService().saveTaxon(taxon
);
108 commitTransaction(tx
);
112 private Synonym
getSynonym(TaxonXImportConfigurator config
, Taxon taxon
, String synName
){
113 Synonym result
= null;
114 unlazySynonym(config
, taxon
);
115 Set
<Synonym
> synList
= taxon
.getSynonyms();
116 for (Synonym syn
: synList
){
117 if (syn
.getName() != null && ((NonViralName
<?
>)syn
.getName()).getNameCache().equals(synName
)){
118 return syn
; //only first synonym is returned
121 logger
.warn("Synonym ("+synName
+ ")not found for taxon " + taxon
.getTitleCache() + getBracketSourceName(config
));
125 private Taxon
getTaxon(TaxonXImportConfigurator config
){
127 // result = Taxon.NewInstance(BotanicalName.NewInstance(null), null);
128 //ICommonService commonService =config.getCdmAppController().getCommonService();
129 ICommonService commonService
= getCommonService();
130 String originalSourceId
= config
.getOriginalSourceId();
131 String namespace
= config
.getOriginalSourceTaxonNamespace();
132 result
= (Taxon
)commonService
.getSourcedObjectByIdInSource(Taxon
.class, originalSourceId
, namespace
);
134 logger
.warn("Taxon (id: " + originalSourceId
+ ", namespace: " + namespace
+ ") could not be found");
140 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IImportConfigurator)
142 protected boolean isIgnore(IImportConfigurator config
){
143 return ! config
.isDoFacts();
148 * Reads the collection_event tag, creates the according data and stores it.
150 * @param elNomenclature
155 private boolean doNomenclaturalType(TaxonXImportConfigurator config
, Element elNomenclature
, Namespace nsTaxonx
, TaxonNameBase taxonName
){
156 if (taxonName
== null){
157 logger
.warn("taxonName is null");
160 if (elNomenclature
== null){
161 logger
.warn("elNomenclature is null");
166 Element elType
= elNomenclature
.getChild("type", nsTaxonx
);
167 Element elTypeLoc
= elNomenclature
.getChild("type_loc", nsTaxonx
);
169 if (elType
!= null || elTypeLoc
!= null){
170 ReferenceBase citation
= null;
171 String citationMicroReference
= null;
172 String originalNameString
= null;
173 boolean isNotDesignated
= true;
174 boolean addToAllHomotypicNames
= true;
175 unlazyTypeDesignation(config
, taxonName
);
178 SimpleSpecimen simpleSpecimen
= SimpleSpecimen
.NewInstance();
181 doElType(elType
, simpleSpecimen
, config
);
185 HashMap
<Specimen
, TypeDesignationStatus
> typeLocMap
= null;
186 if (elTypeLoc
!= null){
187 typeLocMap
= doElTypeLoc(elTypeLoc
, simpleSpecimen
, taxonName
, config
);
189 if (typeLocMap
!= null && typeLocMap
.size() >0){
190 for (Specimen specimen
: typeLocMap
.keySet()){
191 TypeDesignationStatus status
= typeLocMap
.get(specimen
);
192 taxonName
.addSpecimenTypeDesignation(specimen
, status
, citation
, citationMicroReference
, originalNameString
, isNotDesignated
, addToAllHomotypicNames
);
194 }else{ // no type_loc
195 TypeDesignationStatus status
= null;
196 taxonName
.addSpecimenTypeDesignation(simpleSpecimen
.getSpecimen(), status
, citation
, citationMicroReference
, originalNameString
, isNotDesignated
, addToAllHomotypicNames
);
203 private boolean doElType(Element elType
, SimpleSpecimen simpleSpecimen
, TaxonXImportConfigurator config
){
205 String text
= elType
.getTextNormalize();
206 if (text
.endsWith(";")){
209 String
[] type
= text
.split(";");
210 if (type
.length
!= 3 ){
211 if (text
.equals("")){
212 logger
.info("<nomenclature><type> is empty: " + getBracketSourceName(config
));
214 logger
.warn("<nomenclature><type> is of unsupported format: " + elType
.getTextNormalize() + getBracketSourceName(config
));
216 simpleSpecimen
.setTitleCache(elType
.getTextNormalize());
218 String strLocality
= type
[0].trim();
219 if (! "".equals(strLocality
)){
220 // simpleSpecimen.setLocality(strLocality);
223 String strCollector
= type
[1].trim();
224 if (! "".equals(strCollector
)){
225 AgentBase collector
= Person
.NewTitledInstance(strCollector
);
226 // simpleSpecimen.setCollector(collector);
229 String strCollectorNumber
= type
[2].trim();
230 if (! "".equals(strCollectorNumber
)){
231 // simpleSpecimen.setCollectorsNumber(strCollectorNumber);
234 String title
= CdmUtils
.concat(" ", new String
[]{strLocality
, strCollector
, strCollectorNumber
});
235 simpleSpecimen
.setTitleCache(title
);
241 * Reads the typeLoc element split in parts for eacht type (holo, iso,...)
243 * @param simpleSpecimen
248 private HashMap
<Specimen
, TypeDesignationStatus
> doElTypeLoc(Element elTypeLoc
,
249 SimpleSpecimen simpleSpecimen
,
250 TaxonNameBase
<?
,?
> taxonName
,
251 TaxonXImportConfigurator config
){
253 HashMap
<Specimen
, TypeDesignationStatus
> result
= new HashMap
<Specimen
, TypeDesignationStatus
>();
255 String typeLocFullString
= elTypeLoc
.getTextTrim();
256 typeLocFullString
= typeLocFullString
.replace("(", "").replace(")", "");
257 String
[] typeLocStatusList
= typeLocFullString
.split(";");
259 Specimen originalSpecimen
= simpleSpecimen
.getSpecimen();
262 for (String typeLocStatus
: typeLocStatusList
){
263 typeLocStatus
= typeLocStatus
.trim();
264 int pos
= typeLocStatus
.indexOf(" ");
266 logger
.warn("Unknown format or empty type_loc : '" +typeLocStatus
+ "'" + getBracketSourceName(config
));
267 result
.put(originalSpecimen
, null);
269 String statusString
= typeLocStatus
.substring(0,pos
);
270 TypeDesignationStatus status
= getStatusByStatusString(statusString
.trim(), config
);
272 //String[] collectionStrings = typeLocStatus.substring(pos).split(",");
273 String tmpCollString
= typeLocStatus
.substring(pos
).trim();
274 //for(String collectionString : collectionStrings){
275 if (tmpCollString
.contains("typ")){
276 logger
.warn("Is this really only a collection string? : " + tmpCollString
+ getBracketSourceName(config
));
279 specimen
= (Specimen
)originalSpecimen
.clone();
280 String title
= originalSpecimen
.getTitleCache();
281 title
= title
+ "(" + tmpCollString
+ ")";
282 specimen
.setTitleCache(title
);
283 result
.put(specimen
, status
);
293 * Reads the collection_event tag, creates the according data and stores it.
295 * @param elNomenclature
300 private boolean doCollectionEvent(TaxonXImportConfigurator config
, Element elNomenclature
, Namespace nsTaxonx
, TaxonBase taxonBase
){
301 boolean result
= false;
302 if (elNomenclature
== null){
305 Element elCollectionEvent
= elNomenclature
.getChild("collection_event", nsTaxonx
);
306 if (elCollectionEvent
== null){
309 Element elLocality
= elCollectionEvent
.getChild("locality", nsTaxonx
);
310 Element elType
= elCollectionEvent
.getChild("type", nsTaxonx
);
311 Element elTypeLoc
= elCollectionEvent
.getChild("type_loc", nsTaxonx
);
314 SimpleSpecimen simpleSpecimen
= SimpleSpecimen
.NewInstance();
315 String locality
= elLocality
.getTextNormalize();
316 if (! "".equals(locality
)){
317 simpleSpecimen
.setLocality(locality
);
321 String
[] type
= elType
.getTextNormalize().split(" ");
322 if (type
.length
!= 2 ){
323 logger
.warn("<collecion_even><type> is of unsupported format: " + elType
.getTextNormalize());
325 AgentBase collector
= Person
.NewTitledInstance(type
[0]);
326 simpleSpecimen
.setCollector(collector
);
328 String collectorNumber
= type
[1];
329 simpleSpecimen
.setCollectorsNumber(collectorNumber
);
333 String typeLocFullString
= elTypeLoc
.getTextTrim();
334 typeLocFullString
= typeLocFullString
.replace("(", "").replace(")", "");
335 String
[] typeLocStatusList
= typeLocFullString
.split(";");
337 Specimen originalSpecimen
= simpleSpecimen
.getSpecimen();
339 //TODO special character ?, \86, !
341 for (String typeLocStatus
: typeLocStatusList
){
342 typeLocStatus
= typeLocStatus
.trim();
343 int pos
= typeLocStatus
.indexOf(" ");
345 logger
.warn("Unknown format: " + typeLocStatus
);
347 String statusString
= typeLocStatus
.substring(0,pos
);
348 TypeDesignationStatus status
= getStatusByStatusString(statusString
.trim(), config
);
349 String
[] collectionStrings
= typeLocStatus
.substring(pos
).split(",");
350 for(String collectionString
: collectionStrings
){
351 if (taxonBase
!= null){
352 TaxonNameBase
<?
, ?
> taxonName
= taxonBase
.getName();
353 if (taxonName
!= null){
354 ReferenceBase citation
= null;
355 String citationMicroReference
= null;
356 String originalNameString
= null;
357 boolean isNotDesignated
= true;
358 boolean addToAllHomotypicNames
= true;
359 Specimen specimen
= (Specimen
)originalSpecimen
.clone();
360 unlazyTypeDesignation(config
, taxonName
);
361 taxonName
.addSpecimenTypeDesignation(specimen
, status
, citation
, citationMicroReference
, originalNameString
, isNotDesignated
, addToAllHomotypicNames
);
372 private static Map
<String
, TypeDesignationStatus
> statusMap
;
373 private static void fillTypeStatusMap(){
374 statusMap
= new HashMap
<String
, TypeDesignationStatus
>();
375 statusMap
.put("holotype", TypeDesignationStatus
.HOLOTYPE());
376 statusMap
.put("isotype", TypeDesignationStatus
.ISOTYPE());
377 statusMap
.put("lectotype", TypeDesignationStatus
.LECTOTYPE());
378 statusMap
.put("syntype", TypeDesignationStatus
.SYNTYPE());
379 statusMap
.put("isolectotype", TypeDesignationStatus
.ISOLECTOTYPE());
380 statusMap
.put("type", null);
381 //TODO to be continued
385 //TODO move to TypeDesignation class
387 * Returns the typeDesignationStatus according to a type designation status string
388 * @param statusString
389 * @return TypeDesignationStatus
391 private static TypeDesignationStatus
getStatusByStatusString(String statusString
, TaxonXImportConfigurator config
){
392 TypeDesignationStatus result
= null;
393 if (statusString
== null || "".equals(statusString
.trim())){
396 statusString
= statusString
.trim().toLowerCase();
397 statusString
= statusString
.replace("typi", "typus");
398 statusString
= statusString
.replace("typus", "type");
399 statusString
= statusString
.replace("types", "type");
400 statusString
= statusString
.toLowerCase();
402 if (statusMap
== null){
405 result
= statusMap
.get(statusString
);
406 if (statusString
.equals("type")){
407 logger
.info("No type designation type" + getBracketSourceName(config
));
408 }else if (result
== null){
409 logger
.warn("Unknown type status string: " + statusString
+ getBracketSourceName(config
));
416 * TODO Preliminary to avoid laizy loading errors
418 private void unlazyTypeDesignation(TaxonXImportConfigurator config
, TaxonNameBase taxonNameBase
){
419 TransactionStatus txStatus
= startTransaction();
420 //INameService taxonNameService = config.getCdmAppController().getNameService();
421 INameService taxonNameService
= getNameService();
423 taxonNameService
.saveTaxonName(taxonNameBase
);
424 Set
<TaxonNameBase
> typifiedNames
= taxonNameBase
.getHomotypicalGroup().getTypifiedNames();
425 for(TaxonNameBase typifiedName
: typifiedNames
){
426 typifiedName
.getTypeDesignations().size();
428 //taxonNameService.saveTaxonName(taxonNameBase);
429 commitTransaction(txStatus
);
433 * TODO Preliminary to avoid laizy loading errors
435 private void unlazySynonym(IImportConfigurator config
, Taxon taxon
){
436 TransactionStatus txStatus
= startTransaction();
437 ITaxonService taxonService
= getTaxonService();
438 taxonService
.saveTaxon(taxon
);
439 Set
<Synonym
> synonyms
= taxon
.getSynonyms();
440 logger
.debug(synonyms
.size());
441 //taxonService.saveTaxon(taxon);
442 commitTransaction(txStatus
);
445 private static String
getBracketSourceName(TaxonXImportConfigurator config
){
446 return "(" + config
.getSourceNameString() + ")";