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.
10 package eu
.etaxonomy
.cdm
.io
.redlist
.bfnXml
;
12 import java
.util
.ArrayList
;
13 import java
.util
.Collection
;
14 import java
.util
.LinkedHashMap
;
15 import java
.util
.List
;
17 import java
.util
.UUID
;
19 import org
.apache
.commons
.lang
.StringUtils
;
20 import org
.apache
.log4j
.Logger
;
21 import org
.jdom
.Element
;
22 import org
.jdom
.Namespace
;
23 import org
.springframework
.stereotype
.Component
;
24 import org
.springframework
.transaction
.TransactionStatus
;
26 import eu
.etaxonomy
.cdm
.api
.service
.IClassificationService
;
27 import eu
.etaxonomy
.cdm
.api
.service
.ITaxonService
;
28 import eu
.etaxonomy
.cdm
.common
.ResultWrapper
;
29 import eu
.etaxonomy
.cdm
.common
.XmlHelp
;
30 import eu
.etaxonomy
.cdm
.io
.common
.ICdmIO
;
31 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
32 import eu
.etaxonomy
.cdm
.model
.common
.Language
;
33 import eu
.etaxonomy
.cdm
.model
.description
.CategoricalData
;
34 import eu
.etaxonomy
.cdm
.model
.description
.CommonTaxonName
;
35 import eu
.etaxonomy
.cdm
.model
.description
.DescriptionElementBase
;
36 import eu
.etaxonomy
.cdm
.model
.description
.Feature
;
37 import eu
.etaxonomy
.cdm
.model
.description
.State
;
38 import eu
.etaxonomy
.cdm
.model
.description
.TaxonDescription
;
39 import eu
.etaxonomy
.cdm
.model
.description
.TextData
;
40 import eu
.etaxonomy
.cdm
.model
.location
.NamedArea
;
41 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalCode
;
42 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalStatus
;
43 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalStatusType
;
44 import eu
.etaxonomy
.cdm
.model
.name
.NonViralName
;
45 import eu
.etaxonomy
.cdm
.model
.name
.Rank
;
46 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameBase
;
47 import eu
.etaxonomy
.cdm
.model
.taxon
.Classification
;
48 import eu
.etaxonomy
.cdm
.model
.taxon
.Synonym
;
49 import eu
.etaxonomy
.cdm
.model
.taxon
.SynonymRelationshipType
;
50 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
51 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
52 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonRelationship
;
53 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonRelationshipType
;
54 import eu
.etaxonomy
.cdm
.strategy
.exceptions
.UnknownCdmTypeException
;
55 import eu
.etaxonomy
.cdm
.strategy
.parser
.NonViralNameParserImpl
;
56 import eu
.etaxonomy
.cdm
.strategy
.parser
.ParserProblem
;
63 //@Component("bfnXmlTaxonNameIO")
65 public class BfnXmlImportTaxonName
extends BfnXmlImportBase
implements ICdmIO
<BfnXmlImportState
> {
68 private static final Logger logger
= Logger
.getLogger(BfnXmlImportTaxonName
.class);
70 private static String strNomenclaturalCode
= null;// "Zoological";//"Botanical";
71 private static int parsingProblemCounter
= 0;
72 private Map
<Integer
, Taxon
> firstList
;
73 private Map
<Integer
, Taxon
> secondList
;
76 public BfnXmlImportTaxonName(){
81 public boolean doCheck(BfnXmlImportState state
){
82 boolean result
= true;
87 @SuppressWarnings({"rawtypes" })
88 public void doInvoke(BfnXmlImportState state
){
89 ITaxonService taxonService
= getTaxonService();
91 BfnXmlImportConfigurator config
= state
.getConfig();
92 strNomenclaturalCode
= config
.getNomenclaturalSig();
93 Element elDataSet
= getDataSetElement(config
);
95 Namespace bfnNamespace
= config
.getBfnXmlNamespace();
97 List
<?
> contentXML
= elDataSet
.getContent();
98 Element currentElement
= null;
99 for(Object object
:contentXML
){
101 if(object
instanceof Element
){
102 currentElement
= (Element
)object
;
104 if(currentElement
.getName().equalsIgnoreCase("ROTELISTEDATEN")){
105 TransactionStatus tx
= startTransaction();
106 Map
<UUID
, TaxonBase
> savedTaxonMap
= extractTaxonNames(state
, taxonService
, config
, currentElement
, bfnNamespace
);
107 createOrUdateClassification(config
, taxonService
, savedTaxonMap
, currentElement
, state
);
108 commitTransaction(tx
);
109 }//import concept relations of taxon lists
110 if(config
.isHasSecondList()){
111 if(currentElement
.getName().equalsIgnoreCase("KONZEPTBEZIEHUNGEN")){
112 TransactionStatus tx
= startTransaction();
113 extractTaxonConceptRelationShips(bfnNamespace
,currentElement
);
114 commitTransaction(tx
);
123 * This method will parse the XML concept relationships and tries to map them into cdm relationship types.
125 * @param bfnNamespace
126 * @param currentElement
128 private void extractTaxonConceptRelationShips(Namespace bfnNamespace
, Element currentElement
) {
130 String bfnElementName
= "KONZEPTBEZIEHUNG";
131 ResultWrapper
<Boolean
> success
= ResultWrapper
.NewInstance(true);
132 List
<Element
> elConceptList
= currentElement
.getChildren(bfnElementName
, bfnNamespace
);
133 List
<TaxonBase
> updatedTaxonList
= new ArrayList
<TaxonBase
>();
134 for(Element element
:elConceptList
){
136 childName
= "TAXONYM1";
137 Element elTaxon1
= XmlHelp
.getSingleChildElement(success
, element
, childName
, bfnNamespace
, false);
138 String taxNr1
= elTaxon1
.getAttributeValue("taxNr");
139 int int1
= Integer
.parseInt(taxNr1
);
140 Taxon taxon1
= firstList
.get(int1
);
141 TaxonBase
<?
> taxonBase1
= getTaxonService().load(taxon1
.getUuid());
142 taxon1
= (Taxon
)taxonBase1
;
144 childName
= "TAXONYM2";
145 Element elTaxon2
= XmlHelp
.getSingleChildElement(success
, element
, childName
, bfnNamespace
, false);
146 String taxNr2
= elTaxon2
.getAttributeValue("taxNr");
147 int int2
= Integer
.parseInt(taxNr2
);
148 Taxon taxon2
= secondList
.get(int2
);
149 TaxonBase
<?
> taxonBase2
= getTaxonService().load(taxon2
.getUuid());
150 taxon2
= (Taxon
) taxonBase2
;
152 childName
= "STATUS";
153 Element elConceptStatus
= XmlHelp
.getSingleChildElement(success
, element
, childName
, bfnNamespace
, false);
154 String conceptStatusValue
= elConceptStatus
.getValue();
155 conceptStatusValue
= conceptStatusValue
.replaceAll("\u00A0", "").trim();
156 TaxonRelationshipType taxonRelationType
= null;
158 * This if case only exists because it was decided not to have a included_in relationship type.
160 if(conceptStatusValue
.equalsIgnoreCase("<")){
161 taxon2
.addTaxonRelation(taxon1
, TaxonRelationshipType
.INCLUDES(), null, null);
164 taxonRelationType
= BfnXmlTransformer
.concept2TaxonRelation(conceptStatusValue
);
165 } catch (UnknownCdmTypeException e
) {
168 taxon1
.addTaxonRelation(taxon2
, taxonRelationType
, null, null);
170 if(taxonRelationType
!= null && taxonRelationType
.equals(TaxonRelationshipType
.ALL_RELATIONSHIPS())){
171 List
<TaxonRelationship
> relationsFromThisTaxon
= (List
<TaxonRelationship
>) taxon1
.getRelationsFromThisTaxon();
172 TaxonRelationship taxonRelationship
= relationsFromThisTaxon
.get(0);
173 taxonRelationship
.setDoubtful(true);
175 updatedTaxonList
.add(taxon2
);
176 updatedTaxonList
.add(taxon1
);
178 getTaxonService().saveOrUpdate(updatedTaxonList
);
179 logger
.info("taxon relationships imported...");
183 * This method stores the current imported maps in global variables to make
184 * them later available for matching the taxon relationships between these
190 private void prepareListforConceptImport(BfnXmlImportConfigurator config
,Map
<Integer
, Taxon
> taxonMap
) {
191 if(config
.isFillSecondList()){
192 secondList
= taxonMap
;
194 firstList
= taxonMap
;
201 * @param taxonService
204 * @param bfnNamespace
207 private Map
<UUID
, TaxonBase
> extractTaxonNames(BfnXmlImportState state
,
208 ITaxonService taxonService
, BfnXmlImportConfigurator config
,
209 Element elDataSet
, Namespace bfnNamespace
) {
210 logger
.info("start make TaxonNames...");
211 Map
<Integer
, Taxon
> taxonMap
= new LinkedHashMap
<Integer
, Taxon
>();
212 ResultWrapper
<Boolean
> success
= ResultWrapper
.NewInstance(true);
215 String idNamespace
= "TaxonName";
217 childName
= "TAXONYME";
219 Element elTaxonNames
= XmlHelp
.getSingleChildElement(success
, elDataSet
, childName
, bfnNamespace
, obligatory
);
221 String bfnElementName
= "TAXONYM";
222 List
<Element
> elTaxonList
= elTaxonNames
.getChildren(bfnElementName
, bfnNamespace
);
225 for (Element elTaxon
: elTaxonList
){
227 String taxonId
= elTaxon
.getAttributeValue("taxNr");
228 childName
= "WISSNAME";
229 Element elWissName
= XmlHelp
.getSingleChildElement(success
, elTaxon
, childName
, bfnNamespace
, obligatory
);
230 String childElementName
= "NANTEIL";
231 Taxon taxon
= createOrUpdateTaxon(success
, idNamespace
, config
, bfnNamespace
, elWissName
, childElementName
, state
);
234 childName
= "SYNONYME";
235 Element elSynonyms
= XmlHelp
.getSingleChildElement(success
, elTaxon
, childName
, bfnNamespace
, obligatory
);
236 if(elSynonyms
!= null){
237 childElementName
= "SYNONYM";
238 createOrUpdateSynonym(taxon
, success
, obligatory
, bfnNamespace
, childElementName
,elSynonyms
, taxonId
, state
);
240 //for vernacular name
241 childName
= "DEUTSCHENAMEN";
242 Element elVernacularName
= XmlHelp
.getSingleChildElement(success
, elTaxon
, childName
, bfnNamespace
, obligatory
);
243 if(elVernacularName
!= null){
244 childElementName
= "DNAME";
245 createOrUpdateVernacularName(taxon
, bfnNamespace
, childElementName
, elVernacularName
, state
);
247 //for each information concerning the taxon element
248 //TODO Information block
249 if(config
.isDoInformationImport()){
250 childName
= "INFORMATIONEN";
251 Element elInformations
= XmlHelp
.getSingleChildElement(success
, elTaxon
, childName
, bfnNamespace
, obligatory
);
252 if(elInformations
!= null){
253 childElementName
= "BEZUGSRAUM";
254 createOrUpdateInformation(taxon
, bfnNamespace
, childElementName
,elInformations
, state
);
257 taxonMap
.put(Integer
.parseInt(taxonId
), taxon
);
260 //Quick'n'dirty to set concept relationships between two imported list
261 prepareListforConceptImport(config
, taxonMap
);
263 Map
<UUID
, TaxonBase
> savedTaxonMap
= taxonService
.saveOrUpdate((Collection
)taxonMap
.values());
264 //FIXME: after first list don't import metadata yet
265 //TODO: import information for second taxon list.
266 config
.setDoInformationImport(false);
267 logger
.info("end makeTaxonNames ...");
268 if (!success
.getValue()){
269 state
.setUnsuccessfull();
271 return savedTaxonMap
;
278 * This will put the prior imported list into a classification
281 * @param taxonService
283 * @param savedTaxonMap
284 * @param currentElement
288 @SuppressWarnings("rawtypes")
289 private boolean createOrUdateClassification(BfnXmlImportConfigurator config
, ITaxonService taxonService
, Map
<UUID
, TaxonBase
> savedTaxonMap
, Element currentElement
, BfnXmlImportState state
) {
290 boolean isNewClassification
= true;
291 String classificationName
= state
.getFirstClassificationName();
292 if(config
.isFillSecondList()){
293 classificationName
= state
.getSecondClassificationName();
295 // if(classificationName == null){
296 // classificationName = config.getClassificationName();
298 //TODO make classification name dynamically depending on its value in the XML.
299 Classification classification
= Classification
.NewInstance(classificationName
+" "+currentElement
.getAttributeValue("inhalt"), state
.getCompleteSourceRef());
300 classification
.addImportSource(Integer
.toString(classification
.getId()), classification
.getTitleCache(), state
.getCompleteSourceRef(), state
.getCurrentMicroRef().toString());
301 // List<Classification> classificationList = getClassificationService().list(Classification.class, null, null, null, VOC_CLASSIFICATION_INIT_STRATEGY);
302 // for(Classification c : classificationList){
303 // if(c.getTitleCache().equalsIgnoreCase(classification.getTitleCache())){
304 // classification = c;
305 // isNewClassification = false;
309 // ArrayList<TaxonBase> taxonBaseList = (ArrayList<TaxonBase>) taxonService.list(TaxonBase.class, null, null, null, VOC_CLASSIFICATION_INIT_STRATEGY);
310 for(TaxonBase tb
:savedTaxonMap
.values()){
311 if(tb
instanceof Taxon
){
312 TaxonBase tbase
= CdmBase
.deproxy(tb
, TaxonBase
.class);
313 Taxon taxon
= (Taxon
)tbase
;
314 taxon
= CdmBase
.deproxy(taxon
, Taxon
.class);
315 classification
.addChildTaxon(taxon
, null, null);
318 IClassificationService classificationService
= getClassificationService();
319 classificationService
.saveOrUpdate(classification
);
320 //set boolean for reference and internal mapping of concept relations
321 if(config
.isHasSecondList()){
322 config
.setFillSecondList(true);
324 return isNewClassification
;
330 * Matches the XML attributes against CDM entities.<BR>
331 * Imports Scientific Name, Rank, etc. and creates a taxon.<br>
332 * <b>Existing taxon names won't be matched yet</b>
337 * @param bfnNamespace
339 * @param childElementName
344 @SuppressWarnings({ "unchecked", "rawtypes" })
345 private Taxon
createOrUpdateTaxon(
346 ResultWrapper
<Boolean
> success
, String idNamespace
,
347 BfnXmlImportConfigurator config
, Namespace bfnNamespace
,
348 Element elTaxonName
, String childElementName
, BfnXmlImportState state
) {
350 List
<Element
> elWissNameList
= elTaxonName
.getChildren(childElementName
, bfnNamespace
);
352 String strAuthor
= null;
353 String strSupplement
= null;
355 String uniqueID
= null;
356 String uriNameSpace
= null;
357 // Long uniqueID = null;
358 for(Element elWissName
:elWissNameList
){
360 if(elWissName
.getAttributeValue("bereich", bfnNamespace
).equalsIgnoreCase("Eindeutiger Code")){
361 uriNameSpace
= elWissName
.getAttributeValue("bereich");
362 String textNormalize
= elWissName
.getTextNormalize();
363 if(StringUtils
.isBlank(textNormalize
)){
366 uniqueID
= textNormalize
;
369 if(elWissName
.getAttributeValue("bereich", bfnNamespace
).equalsIgnoreCase("Autoren")){
370 strAuthor
= elWissName
.getTextNormalize();
372 if(elWissName
.getAttributeValue("bereich", bfnNamespace
).equalsIgnoreCase("Rang")){
373 String strRank
= elWissName
.getTextNormalize();
374 rank
= makeRank(strRank
);
376 if(elWissName
.getAttributeValue("bereich", bfnNamespace
).equalsIgnoreCase("Zusätze")){
377 strSupplement
= elWissName
.getTextNormalize();
379 if(elWissName
.getAttributeValue("bereich", bfnNamespace
).equalsIgnoreCase("wissName")){
381 TaxonNameBase
<?
, ?
> nameBase
= parseNonviralNames(rank
,strAuthor
,strSupplement
,elWissName
);
382 if(nameBase
.isProtectedTitleCache() == true){
383 logger
.warn("Taxon " + nameBase
.getTitleCache());
386 //TODO extract to method?
387 if(strSupplement
!= null){
388 nameBase
.setAppendedPhrase(strSupplement
);
390 if(strSupplement
!= null && strSupplement
.equalsIgnoreCase("nom. illeg.")){
391 nameBase
.addStatus(NomenclaturalStatus
.NewInstance(NomenclaturalStatusType
.ILLEGITIMATE()));
394 * BFN does not want any name matching yet
396 // TaxonBase<?> taxonBase = null;
397 // //TODO find best matching Taxa
398 // Pager<TaxonNameBase> names = getNameService().findByTitle(null, nameBase.getTitleCache(), null, null, null, null, null, null);
399 // //TODO correct handling for pager
400 // List<TaxonNameBase> nameList = names.getRecords();
401 // if (nameList.isEmpty()){
402 // taxonBase = Taxon.NewInstance(nameBase, config.getSourceReference());
404 // taxonBase = Taxon.NewInstance(nameList.get(0), config.getSourceReference());
405 // if (nameList.size()>1){
406 // logger.warn("More than 1 matching taxon name found for " + nameBase.getTitleCache());
409 state
.setCurrentMicroRef(state
.getFirstListSecRef());
410 if(config
.isFillSecondList()){
411 state
.setCurrentMicroRef(state
.getSecondListSecRef());
413 taxon
= Taxon
.NewInstance(nameBase
, state
.getCurrentMicroRef());
414 //set create and set path of nameSpace
415 Element parentElement
= elWissName
.getParentElement();
416 Element grandParentElement
= parentElement
.getParentElement();
417 taxon
.addImportSource(uniqueID
, grandParentElement
.getName()+":"+parentElement
.getName()+":"+elWissName
.getName()+":"+uriNameSpace
, state
.getCompleteSourceRef(), state
.getCurrentMicroRef().getTitle());
418 } catch (UnknownCdmTypeException e
) {
419 success
.setValue(false);
427 * Matches the XML attributes against CDM entities.<BR>
428 * Imports Scientific Name, Rank etc. and create a synonym.<br>
429 * <b>Existing synonym names won't be matched yet</b>
434 * @param bfnNamespace
435 * @param childElementName
442 @SuppressWarnings({ "unchecked" })
443 private void createOrUpdateSynonym(Taxon taxon
, ResultWrapper
<Boolean
> success
, boolean obligatory
, Namespace bfnNamespace
,
444 String childElementName
, Element elSynonyms
, String taxonId
, BfnXmlImportState state
) {
447 List
<Element
> elSynonymList
= elSynonyms
.getChildren(childElementName
, bfnNamespace
);
449 for(Element elSyn
:elSynonymList
){
451 String strAuthor
= null;
452 String strSupplement
= null;
453 childName
= "WISSNAME";
454 Element elSynScientificName
= XmlHelp
.getSingleChildElement(success
, elSyn
, childName
, bfnNamespace
, obligatory
);
456 childElementName
= "NANTEIL";
457 List
<Element
> elSynDetails
= elSynScientificName
.getChildren(childElementName
, bfnNamespace
);
459 for(Element elSynDetail
:elSynDetails
){
460 if(elSynDetail
.getAttributeValue("bereich").equalsIgnoreCase("Rang")){
461 String strRank
= elSynDetail
.getTextNormalize();
462 rank
= makeRank(strRank
);
464 if(elSynDetail
.getAttributeValue("bereich").equalsIgnoreCase("Autoren")){
465 strAuthor
= elSynDetail
.getTextNormalize();
467 if(elSynDetail
.getAttributeValue("bereich", bfnNamespace
).equalsIgnoreCase("Zusätze")){
468 strSupplement
= elSynDetail
.getTextNormalize();
470 if(elSynDetail
.getAttributeValue("bereich").equalsIgnoreCase("wissName")){
472 TaxonNameBase
<?
, ?
> nameBase
= parseNonviralNames(rank
,strAuthor
,strSupplement
,elSynDetail
);
474 //TODO find best matching Taxa
475 Synonym synonym
= Synonym
.NewInstance(nameBase
, state
.getCurrentMicroRef());
476 taxon
.addSynonym(synonym
, SynonymRelationshipType
.SYNONYM_OF());
478 } catch (UnknownCdmTypeException e
) {
479 logger
.warn("Name with id " + taxonId
+ " has unknown nomenclatural code.");
480 success
.setValue(false);
493 * @param bfnNamespace
494 * @param childElementName
495 * @param elVernacularName
498 private void createOrUpdateVernacularName(Taxon taxon
,
499 Namespace bfnNamespace
, String childElementName
,
500 Element elVernacularName
, BfnXmlImportState state
) {
502 List
<Element
> elVernacularNameList
= elVernacularName
.getChildren(childElementName
, bfnNamespace
);
504 TaxonDescription taxonDescription
= getTaxonDescription(taxon
, false, true);
506 for(Element elVernacular
: elVernacularNameList
){
507 Element child
= elVernacular
.getChild("TRIVIALNAME");
509 makeCommonName(taxonDescription
, child
, state
);
518 * @param bfnNamespace
519 * @param childElementName
520 * @param elInformations
522 * @throws UnknownCdmTypeException
525 @SuppressWarnings("unchecked")
526 private void createOrUpdateInformation(Taxon taxon
,
527 Namespace bfnNamespace
, String childElementName
,
528 Element elInformations
,
529 BfnXmlImportState state
){
531 List
<Element
> elInformationList
= elInformations
.getChildren(childElementName
, bfnNamespace
);
533 for(Element elInfo
:elInformationList
){
534 //check if geographical scope is Bund and import only these information for now
535 //TODO create several taxon descriptions for different geographical scope
536 if(elInfo
.getName().equalsIgnoreCase("BEZUGSRAUM") && elInfo
.getAttributeValue("name").equalsIgnoreCase("Bund")){
537 childElementName
= "IWERT";
538 TaxonDescription taxonDescription
= getTaxonDescription(taxon
, false, true);
539 UUID germanStateUUID
;
541 germanStateUUID
= BfnXmlTransformer
.getGermanStateUUID("Deutschland");
542 NamedArea area
= (NamedArea
)getTermService().load(germanStateUUID
);
543 //FIXME GEOSCOPE_ID CANNOT BE NULL Exception
544 // taxonDescription.addGeoScope(area);
545 } catch (UnknownCdmTypeException e
) {
546 // TODO Auto-generated catch block
549 List
<Element
> elInfoDetailList
= elInfo
.getChildren(childElementName
, bfnNamespace
);
551 for(Element elInfoDetail
: elInfoDetailList
){
552 if(elInfoDetail
.getAttributeValue("standardname").equalsIgnoreCase("RL Kat.")){
553 makeFeatures(taxonDescription
, elInfoDetail
, state
, false);
555 if(elInfoDetail
.getAttributeValue("standardname").equalsIgnoreCase("Kat. +/-")){
556 makeFeatures(taxonDescription
, elInfoDetail
, state
, false);
558 if(elInfoDetail
.getAttributeValue("standardname").equalsIgnoreCase("aktuelle Bestandsstituation")){
559 makeFeatures(taxonDescription
, elInfoDetail
, state
, false);
561 if(elInfoDetail
.getAttributeValue("standardname").equalsIgnoreCase("langfristiger Bestandstrend")){
562 makeFeatures(taxonDescription
, elInfoDetail
, state
, false);
564 if(elInfoDetail
.getAttributeValue("standardname").equalsIgnoreCase("kurzfristiger Bestandstrend")){
565 makeFeatures(taxonDescription
, elInfoDetail
, state
, false);
567 if(elInfoDetail
.getAttributeValue("standardname").equalsIgnoreCase("Risikofaktoren")){
568 makeFeatures(taxonDescription
, elInfoDetail
, state
, false);
570 if(elInfoDetail
.getAttributeValue("standardname").equalsIgnoreCase("Verantwortlichkeit")){
571 makeFeatures(taxonDescription
, elInfoDetail
, state
, false);
573 if(elInfoDetail
.getAttributeValue("standardname").equalsIgnoreCase("alte RL- Kat.")){
574 makeFeatures(taxonDescription
, elInfoDetail
, state
, false);
576 if(elInfoDetail
.getAttributeValue("standardname").equalsIgnoreCase("Neobiota")){
577 makeFeatures(taxonDescription
, elInfoDetail
, state
, false);
579 if(elInfoDetail
.getAttributeValue("standardname").equalsIgnoreCase("Eindeutiger Code")){
580 makeFeatures(taxonDescription
, elInfoDetail
, state
, false);
582 if(elInfoDetail
.getAttributeValue("standardname").equalsIgnoreCase("Kommentar zur Taxonomie")){
583 makeFeatures(taxonDescription
, elInfoDetail
, state
, true);
585 if(elInfoDetail
.getAttributeValue("standardname").equalsIgnoreCase("Kommentar zur Gefährdung")){
586 makeFeatures(taxonDescription
, elInfoDetail
, state
, true);
588 if(elInfoDetail
.getAttributeValue("standardname").equalsIgnoreCase("Sonderfälle")){
589 makeFeatures(taxonDescription
, elInfoDetail
, state
, false);
591 if(elInfoDetail
.getAttributeValue("standardname").equalsIgnoreCase("Letzter Nachweis")){
592 makeFeatures(taxonDescription
, elInfoDetail
, state
, true);
594 if(elInfoDetail
.getAttributeValue("standardname").equalsIgnoreCase("Weitere Kommentare")){
595 makeFeatures(taxonDescription
, elInfoDetail
, state
, true);
604 private void makeCommonName(TaxonDescription taxonDescription
,
605 Element child
, BfnXmlImportState state
) {
606 String commonNameValue
= child
.getValue();
607 NamedArea area
= getTermService().getAreaByTdwgAbbreviation("GER");
608 CommonTaxonName commonName
= CommonTaxonName
.NewInstance(commonNameValue
, Language
.GERMAN(), area
);
609 taxonDescription
.addElement(commonName
);
615 * @param taxonDescription
616 * @param elInfoDetail
620 private void makeFeatures(
621 TaxonDescription taxonDescription
,
622 Element elInfoDetail
,
623 BfnXmlImportState state
,
624 boolean isTextData
) {
626 String transformedRlKatValue
= null;
627 UUID featureUUID
= null;
628 UUID stateTermUUID
= null;
629 String strRlKatValue
= elInfoDetail
.getChild("WERT").getValue();
630 String strRlKat
= elInfoDetail
.getAttributeValue("standardname");
631 boolean randomStateUUID
= false;
633 featureUUID
= BfnXmlTransformer
.getRedlistFeatureUUID(strRlKat
);
634 transformedRlKatValue
= BfnXmlTransformer
.redListString2RedListCode(strRlKatValue
);
635 } catch (UnknownCdmTypeException e
) {
636 transformedRlKatValue
= strRlKatValue
;
638 Feature redListFeature
= getFeature(state
, featureUUID
);
639 State rlState
= null;
640 //if is text data a state is not needed
643 stateTermUUID
= BfnXmlTransformer
.getRedlistStateTermUUID(transformedRlKatValue
, strRlKat
);
644 } catch (UnknownCdmTypeException e
) {
645 stateTermUUID
= UUID
.randomUUID();
646 randomStateUUID
= true;
648 if(randomStateUUID
|| stateTermUUID
== BfnXmlTransformer
.stateTermEmpty
){
649 if(stateTermUUID
== BfnXmlTransformer
.stateTermEmpty
) {
650 transformedRlKatValue
= "keine Angabe";
652 rlState
= getStateTerm(state
, stateTermUUID
, transformedRlKatValue
, transformedRlKatValue
, transformedRlKatValue
, null);
654 rlState
= getStateTerm(state
, stateTermUUID
);
658 TextData textData
= TextData
.NewInstance(redListFeature
);
659 textData
.putText(Language
.GERMAN(), strRlKatValue
);
660 DescriptionElementBase descriptionElement
= textData
;
661 taxonDescription
.addElement(descriptionElement
);
663 CategoricalData catData
= CategoricalData
.NewInstance(rlState
, redListFeature
);
664 DescriptionElementBase descriptionElement
= catData
;
665 taxonDescription
.addElement(descriptionElement
);
670 * Returns the rank represented by the rank element.<br>
671 * Returns <code>null</code> if the element is null.<br>
672 * Returns <code>null</code> if the code and the text are both either empty or do not exists.<br>
673 * Returns the rank represented by the code attribute, if the code attribute is not empty and could be resolved.<br>
674 * If the code could not be resolved it returns the rank represented most likely by the elements text.<br>
675 * Returns UNKNOWN_RANK if code attribute and element text could not be resolved.
676 * @param strRank bfn rank element
679 protected static Rank
makeRank(String strRank
){
681 if (strRank
== null){
684 Rank codeRank
= null;
686 codeRank
= BfnXmlTransformer
.rankCode2Rank(strRank
);
687 } catch (UnknownCdmTypeException e1
) {
688 codeRank
= Rank
.UNKNOWN_RANK();
691 if ( (codeRank
!= null) && !codeRank
.equals(Rank
.UNKNOWN_RANK())){
694 //codeRank does not exist
697 logger
.warn("string rank used, because code rank does not exist or was not recognized: " + codeRank
.getTitleCache()+" "+strRank
);
705 * @param strSupplement
708 * @throws UnknownCdmTypeException
710 private TaxonNameBase
<?
, ?
> parseNonviralNames(Rank rank
, String strAuthor
, String strSupplement
, Element elWissName
)
711 throws UnknownCdmTypeException
{
712 TaxonNameBase
<?
,?
> taxonNameBase
= null;
714 NomenclaturalCode nomCode
= BfnXmlTransformer
.nomCodeString2NomCode(strNomenclaturalCode
);
715 String strScientificName
= elWissName
.getTextNormalize();
718 * trim strScienctificName because sometimes
719 * getTextNormalize() does not removes all the
723 strScientificName
= StringUtils
.trim(strScientificName
);
724 strScientificName
= StringUtils
.remove(strScientificName
, "\u00a0");
725 strScientificName
= StringUtils
.remove(strScientificName
, "\uc281");
727 if(strSupplement
!= null && !strSupplement
.isEmpty()){
728 strScientificName
= StringUtils
.remove(strScientificName
, strSupplement
);
730 NonViralName
<?
> nonViralName
= null;
731 NonViralNameParserImpl parser
= NonViralNameParserImpl
.NewInstance();
732 nonViralName
= parser
.parseFullName(strScientificName
, nomCode
, rank
);
733 if(nonViralName
.hasProblem()){
734 for(ParserProblem p
:nonViralName
.getParsingProblems()){
735 logger
.warn(++parsingProblemCounter
+ " " +nonViralName
.getTitleCache() +" "+p
.toString());
738 //check for parsed rank
739 Rank parsedRank
= nonViralName
.getRank();
740 if(parsedRank
!= rank
){
741 nonViralName
.setRank(rank
);
743 //check for parsed author
744 String parsedAuthor
= nonViralName
.getAuthorshipCache();
745 strAuthor
= StringUtils
.trim(strAuthor
);
746 parsedAuthor
= StringUtils
.trim(parsedAuthor
);
747 if(parsedAuthor
.equalsIgnoreCase(strAuthor
)){
748 logger
.info("Taxon " + nonViralName
.getTitleCache() +":"
749 +"\t Author field: " + strAuthor
+" and parsed AuthorshipCache: "+nonViralName
.getAuthorshipCache());
751 taxonNameBase
= nonViralName
;
752 return taxonNameBase
;
756 protected boolean isIgnore(BfnXmlImportState state
){
757 return ! state
.getConfig().isDoTaxonNames();