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
.Agent
;
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 logger
.warn("<nomenclature><type> is of unsupported format: " + elType
.getTextNormalize() + getBracketSourceName(config
));
212 simpleSpecimen
.setTitleCache(elType
.getTextNormalize());
214 String strLocality
= type
[0].trim();
215 if (! "".equals(strLocality
)){
216 // simpleSpecimen.setLocality(strLocality);
219 String strCollector
= type
[1].trim();
220 if (! "".equals(strCollector
)){
221 Agent collector
= Person
.NewTitledInstance(strCollector
);
222 // simpleSpecimen.setCollector(collector);
225 String strCollectorNumber
= type
[2].trim();
226 if (! "".equals(strCollectorNumber
)){
227 // simpleSpecimen.setCollectorsNumber(strCollectorNumber);
230 String title
= CdmUtils
.concat(" ", new String
[]{strLocality
, strCollector
, strCollectorNumber
});
231 simpleSpecimen
.setTitleCache(title
);
237 * Reads the typeLoc element split in parts for eacht type (holo, iso,...)
239 * @param simpleSpecimen
244 private HashMap
<Specimen
, TypeDesignationStatus
> doElTypeLoc(Element elTypeLoc
,
245 SimpleSpecimen simpleSpecimen
,
246 TaxonNameBase
<?
,?
> taxonName
,
247 TaxonXImportConfigurator config
){
249 HashMap
<Specimen
, TypeDesignationStatus
> result
= new HashMap
<Specimen
, TypeDesignationStatus
>();
251 String typeLocFullString
= elTypeLoc
.getTextTrim();
252 typeLocFullString
= typeLocFullString
.replace("(", "").replace(")", "");
253 String
[] typeLocStatusList
= typeLocFullString
.split(";");
255 Specimen originalSpecimen
= simpleSpecimen
.getSpecimen();
258 for (String typeLocStatus
: typeLocStatusList
){
259 typeLocStatus
= typeLocStatus
.trim();
260 int pos
= typeLocStatus
.indexOf(" ");
262 logger
.warn("Unknown format for type_loc : " + typeLocStatus
+ getBracketSourceName(config
));
263 result
.put(originalSpecimen
, null);
265 String statusString
= typeLocStatus
.substring(0,pos
);
266 TypeDesignationStatus status
= getStatusByStatusString(statusString
.trim());
268 //String[] collectionStrings = typeLocStatus.substring(pos).split(",");
269 String tmpCollString
= typeLocStatus
.substring(pos
).trim();
270 //for(String collectionString : collectionStrings){
271 if (tmpCollString
.contains("typ")){
272 logger
.warn("Is this really only a collection string? : " + tmpCollString
+ getBracketSourceName(config
));
275 specimen
= (Specimen
)originalSpecimen
.clone();
276 String title
= originalSpecimen
.getTitleCache();
277 title
= title
+ "(" + tmpCollString
+ ")";
278 specimen
.setTitleCache(title
);
279 result
.put(specimen
, status
);
289 * Reads the collection_event tag, creates the according data and stores it.
291 * @param elNomenclature
296 private boolean doCollectionEvent(TaxonXImportConfigurator config
, Element elNomenclature
, Namespace nsTaxonx
, TaxonBase taxonBase
){
297 boolean result
= false;
298 if (elNomenclature
== null){
301 Element elCollectionEvent
= elNomenclature
.getChild("collection_event", nsTaxonx
);
302 if (elCollectionEvent
== null){
305 Element elLocality
= elCollectionEvent
.getChild("locality", nsTaxonx
);
306 Element elType
= elCollectionEvent
.getChild("type", nsTaxonx
);
307 Element elTypeLoc
= elCollectionEvent
.getChild("type_loc", nsTaxonx
);
310 SimpleSpecimen simpleSpecimen
= SimpleSpecimen
.NewInstance();
311 String locality
= elLocality
.getTextNormalize();
312 if (! "".equals(locality
)){
313 simpleSpecimen
.setLocality(locality
);
317 String
[] type
= elType
.getTextNormalize().split(" ");
318 if (type
.length
!= 2 ){
319 logger
.warn("<collecion_even><type> is of unsupported format: " + elType
.getTextNormalize());
321 Agent collector
= Person
.NewTitledInstance(type
[0]);
322 simpleSpecimen
.setCollector(collector
);
324 String collectorNumber
= type
[1];
325 simpleSpecimen
.setCollectorsNumber(collectorNumber
);
329 String typeLocFullString
= elTypeLoc
.getTextTrim();
330 typeLocFullString
= typeLocFullString
.replace("(", "").replace(")", "");
331 String
[] typeLocStatusList
= typeLocFullString
.split(";");
333 Specimen originalSpecimen
= simpleSpecimen
.getSpecimen();
335 //TODO special character ?, \86, !
337 for (String typeLocStatus
: typeLocStatusList
){
338 typeLocStatus
= typeLocStatus
.trim();
339 int pos
= typeLocStatus
.indexOf(" ");
341 logger
.warn("Unknown format: " + typeLocStatus
);
343 String statusString
= typeLocStatus
.substring(0,pos
);
344 TypeDesignationStatus status
= getStatusByStatusString(statusString
.trim());
345 String
[] collectionStrings
= typeLocStatus
.substring(pos
).split(",");
346 for(String collectionString
: collectionStrings
){
347 if (taxonBase
!= null){
348 TaxonNameBase
<?
, ?
> taxonName
= taxonBase
.getName();
349 if (taxonName
!= null){
350 ReferenceBase citation
= null;
351 String citationMicroReference
= null;
352 String originalNameString
= null;
353 boolean isNotDesignated
= true;
354 boolean addToAllHomotypicNames
= true;
355 Specimen specimen
= (Specimen
)originalSpecimen
.clone();
356 unlazyTypeDesignation(config
, taxonName
);
357 taxonName
.addSpecimenTypeDesignation(specimen
, status
, citation
, citationMicroReference
, originalNameString
, isNotDesignated
, addToAllHomotypicNames
);
368 private static Map
<String
, TypeDesignationStatus
> statusMap
;
369 private static void fillTypeStatusMap(){
370 statusMap
= new HashMap
<String
, TypeDesignationStatus
>();
371 statusMap
.put("holotype", TypeDesignationStatus
.HOLOTYPE());
372 statusMap
.put("isotype", TypeDesignationStatus
.ISOTYPE());
373 statusMap
.put("lectotype", TypeDesignationStatus
.LECTOTYPE());
374 statusMap
.put("syntype", TypeDesignationStatus
.SYNTYPE());
375 statusMap
.put("isolectotype", TypeDesignationStatus
.ISOLECTOTYPE());
376 statusMap
.put("type", null);
377 //TODO to be continued
381 //TODO move to TypeDesignation class
383 * Returns the typeDesignationStatus according to a type designation status string
384 * @param statusString
385 * @return TypeDesignationStatus
387 private static TypeDesignationStatus
getStatusByStatusString(String statusString
){
388 TypeDesignationStatus result
= null;
389 if (statusString
== null || "".equals(statusString
.trim())){
392 statusString
= statusString
.trim().toLowerCase();
393 statusString
= statusString
.replace("typi", "typus");
394 statusString
= statusString
.replace("typus", "type");
395 statusString
= statusString
.replace("types", "type");
396 statusString
= statusString
.toLowerCase();
398 if (statusMap
== null){
401 result
= statusMap
.get(statusString
);
402 if (statusString
.equals("type")){
403 logger
.info("No type designation type");
404 }else if (result
== null){
405 logger
.warn("Unknown type status string: " + statusString
);
412 * TODO Preliminary to avoid laizy loading errors
414 private void unlazyTypeDesignation(TaxonXImportConfigurator config
, TaxonNameBase taxonNameBase
){
415 TransactionStatus txStatus
= startTransaction();
416 //INameService taxonNameService = config.getCdmAppController().getNameService();
417 INameService taxonNameService
= getNameService();
419 taxonNameService
.saveTaxonName(taxonNameBase
);
420 Set
<TaxonNameBase
> typifiedNames
= taxonNameBase
.getHomotypicalGroup().getTypifiedNames();
421 for(TaxonNameBase typifiedName
: typifiedNames
){
422 typifiedName
.getTypeDesignations().size();
424 //taxonNameService.saveTaxonName(taxonNameBase);
425 commitTransaction(txStatus
);
429 * TODO Preliminary to avoid laizy loading errors
431 private void unlazySynonym(IImportConfigurator config
, Taxon taxon
){
432 TransactionStatus txStatus
= startTransaction();
433 ITaxonService taxonService
= getTaxonService();
434 taxonService
.saveTaxon(taxon
);
435 Set
<Synonym
> synonyms
= taxon
.getSynonyms();
436 logger
.debug(synonyms
.size());
437 //taxonService.saveTaxon(taxon);
438 commitTransaction(txStatus
);
441 private String
getBracketSourceName(TaxonXImportConfigurator config
){
442 return "(" + config
.getSourceNameString() + ")";