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
.redlist
.bfnXml
.out
;
11 import java
.util
.Comparator
;
12 import java
.util
.List
;
14 import java
.util
.UUID
;
16 import org
.apache
.logging
.log4j
.LogManager
;
17 import org
.apache
.logging
.log4j
.Logger
;
18 import org
.jdom2
.Attribute
;
19 import org
.jdom2
.Document
;
20 import org
.jdom2
.Element
;
21 import org
.springframework
.stereotype
.Component
;
23 import eu
.etaxonomy
.cdm
.hibernate
.HibernateProxyHelper
;
24 import eu
.etaxonomy
.cdm
.io
.redlist
.bfnXml
.BfnXmlConstants
;
25 import eu
.etaxonomy
.cdm
.io
.redlist
.bfnXml
.in
.BfnXmlTransformer
;
26 import eu
.etaxonomy
.cdm
.model
.common
.ExtensionType
;
27 import eu
.etaxonomy
.cdm
.model
.common
.IdentifiableSource
;
28 import eu
.etaxonomy
.cdm
.model
.common
.Language
;
29 import eu
.etaxonomy
.cdm
.model
.description
.CategoricalData
;
30 import eu
.etaxonomy
.cdm
.model
.description
.CommonTaxonName
;
31 import eu
.etaxonomy
.cdm
.model
.description
.DescriptionElementBase
;
32 import eu
.etaxonomy
.cdm
.model
.description
.Feature
;
33 import eu
.etaxonomy
.cdm
.model
.description
.State
;
34 import eu
.etaxonomy
.cdm
.model
.description
.StateData
;
35 import eu
.etaxonomy
.cdm
.model
.description
.TaxonDescription
;
36 import eu
.etaxonomy
.cdm
.model
.description
.TextData
;
37 import eu
.etaxonomy
.cdm
.model
.name
.INonViralName
;
38 import eu
.etaxonomy
.cdm
.model
.name
.Rank
;
39 import eu
.etaxonomy
.cdm
.model
.name
.RankClass
;
40 import eu
.etaxonomy
.cdm
.model
.reference
.OriginalSourceType
;
41 import eu
.etaxonomy
.cdm
.model
.taxon
.Classification
;
42 import eu
.etaxonomy
.cdm
.model
.taxon
.Synonym
;
43 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
44 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
45 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonNode
;
46 import eu
.etaxonomy
.cdm
.model
.term
.DefinedTerm
;
47 import eu
.etaxonomy
.cdm
.model
.term
.TermVocabulary
;
54 public class BfnXmlTaxonNameExport
extends BfnXmlExportBase
{
56 private static final long serialVersionUID
= -931703660108981011L;
57 private static final Logger logger
= LogManager
.getLogger();
59 public BfnXmlTaxonNameExport(){
64 protected void doInvoke(BfnXmlExportState state
){
65 startTransaction(true);
67 Document document
= state
.getConfig().getDocument();
69 //get all classifications
70 List
<Classification
> classifications
= getClassificationService().list(Classification
.class, null, null, null, null);
71 for (Classification classification
: classifications
) {
72 Element roteListeDaten
= new Element(BfnXmlConstants
.EL_ROTELISTEDATEN
);
73 roteListeDaten
.setAttribute(new Attribute(BfnXmlConstants
.ATT_INHALT
, classification
.getTitleCache()));
74 document
.getRootElement().addContent(roteListeDaten
);
76 exportFeatures(roteListeDaten
);
78 exportTaxonomy(classification
, roteListeDaten
, state
);
83 private void exportTaxonomy(Classification classification
, Element roteListeDaten
, BfnXmlExportState state
) {
84 Element taxonyme
= new Element(BfnXmlConstants
.EL_TAXONYME
);
85 roteListeDaten
.addContent(taxonyme
);
86 List
<TaxonNode
> childNodes
= classification
.getChildNodes();
87 java
.util
.Collections
.sort(childNodes
, new TaxonComparator());
88 for (TaxonNode taxonNode
: childNodes
) {
89 exportTaxon(taxonNode
.getTaxon(), taxonyme
, state
);
93 private void exportFactualData(Taxon taxon
, Element parent
) {
94 Element informationen
= new Element(BfnXmlConstants
.EL_INFORMATIONEN
);
95 parent
.addContent(informationen
);
96 Element bezugsraum
= new Element(BfnXmlConstants
.EL_BEZUGSRAUM
);
97 bezugsraum
.setAttribute(new Attribute(BfnXmlConstants
.ATT_NAME
, BfnXmlConstants
.BEZUGRAUM_BUND
));
98 informationen
.addContent(bezugsraum
);
100 Set
<TaxonDescription
> descriptions
= taxon
.getDescriptions();
101 for (TaxonDescription taxonDescription
: descriptions
) {
102 //TODO: export only red list features ??
103 Set
<DescriptionElementBase
> descriptionElements
= taxonDescription
.getElements();
104 exportCategoricalData(BfnXmlConstants
.VOC_RL_KAT
, descriptionElements
, taxon
, parent
);
105 exportCategoricalData(BfnXmlConstants
.VOC_KAT
, descriptionElements
, taxon
, parent
);
106 exportCategoricalData(BfnXmlConstants
.VOC_NEOBIOTA
, descriptionElements
, taxon
, parent
);
107 exportCategoricalData(BfnXmlConstants
.VOC_AKTUELLE_BESTANDSSTITUATION
, descriptionElements
, taxon
, parent
);
108 exportCategoricalData(BfnXmlConstants
.VOC_LANGFRISTIGER_BESTANDSTREND
, descriptionElements
, taxon
, parent
);
109 exportCategoricalData(BfnXmlConstants
.VOC_KURZFRISTIGER_BESTANDSTREND
, descriptionElements
, taxon
, parent
);
110 exportCategoricalData(BfnXmlConstants
.VOC_RISIKOFAKTOREN
, descriptionElements
, taxon
, parent
);
111 exportCategoricalData(BfnXmlConstants
.VOC_SONDERFAELLE
, descriptionElements
, taxon
, parent
);
112 exportTextData(BfnXmlConstants
.FEAT_LETZTER_NACHWEIS
, descriptionElements
, taxon
, parent
);
113 exportCategoricalData(BfnXmlConstants
.VOC_VERANTWORTLICHKEIT
, descriptionElements
, taxon
, parent
);
114 exportTextData(BfnXmlConstants
.FEAT_KOMMENTAR_TAXONOMIE
, descriptionElements
, taxon
, parent
);
115 exportTextData(BfnXmlConstants
.FEAT_KOMMENTAR_GEFAEHRDUNG
, descriptionElements
, taxon
, parent
);
116 exportTextData(BfnXmlConstants
.FEAT_WEITERE_KOMMENTARE
, descriptionElements
, taxon
, parent
);
117 exportCategoricalData(BfnXmlConstants
.VOC_ALTE_RL_KAT
, descriptionElements
, taxon
, parent
);
120 // for (DescriptionElementBase descriptionElementBase : descriptionElements) {
121 // if(descriptionElementBase.isInstanceOf(CategoricalData.class)){
122 // CategoricalData categoricalData = HibernateProxyHelper.deproxy(descriptionElementBase, CategoricalData.class);
123 // Feature feature = categoricalData.getFeature();
124 // List<StateData> stateData = categoricalData.getStateData();
125 // if(stateData.size()!=1){
126 // logger.error("StateData does not have a size of 1 for feature "+feature.getLabel()+" in taxon "+taxon.getTitleCache());
129 // addIwert(bezugsraum, feature.getLabel(), stateData.iterator().next().getState().getLabel());
131 // else if(descriptionElementBase.isInstanceOf(TextData.class)){
132 // TextData textData = HibernateProxyHelper.deproxy(descriptionElementBase, TextData.class);
133 // addIwert(bezugsraum, textData.getFeature().getLabel(), textData.getLanguageText(Language.GERMAN()).getText());
139 private void exportTextData(String featureLabel
, Set
<DescriptionElementBase
> descriptionElements
, Taxon taxon
, Element parent
){
140 for (DescriptionElementBase descriptionElementBase
: descriptionElements
) {
141 if(descriptionElementBase
.getFeature().getLabel().equals(featureLabel
)){
142 TextData textData
= HibernateProxyHelper
.deproxy(descriptionElementBase
, TextData
.class);
143 addIwert(parent
, textData
.getFeature().getLabel(), textData
.getLanguageText(Language
.GERMAN()).getText());
148 private void exportCategoricalData(String featureLabel
, Set
<DescriptionElementBase
> descriptionElements
, Taxon taxon
, Element parent
){
149 for (DescriptionElementBase descriptionElementBase
: descriptionElements
) {
150 if(descriptionElementBase
.getFeature().getLabel().equals(featureLabel
)){
151 CategoricalData categoricalData
= HibernateProxyHelper
.deproxy(descriptionElementBase
, CategoricalData
.class);
152 Feature feature
= categoricalData
.getFeature();
153 List
<StateData
> stateData
= categoricalData
.getStateData();
154 if(stateData
.size()!=1){
155 logger
.error("StateData does not have a size of 1 for feature "+feature
.getLabel()+" in taxon "+taxon
.getTitleCache());
158 addIwert(parent
, feature
.getLabel(), stateData
.iterator().next().getState().getLabel());
163 private void exportFeatures(Element roteListeDaten
) {
164 Element eigenschaften
= new Element(BfnXmlConstants
.EL_EIGENSCHAFTEN
);
165 roteListeDaten
.addContent(eigenschaften
);
166 TermVocabulary
<Feature
> redListFeaturesVoc
= getVocabularyService().load(BfnXmlTransformer
.vocRLFeatures
);
167 Set
<Feature
> terms
= redListFeaturesVoc
.getTerms();
168 for (Feature feature
: terms
) {
169 //export red list features
170 Element eigenschaft
= new Element(BfnXmlConstants
.EL_EIGENSCHAFT
);
171 eigenschaft
.setAttribute(new Attribute(BfnXmlConstants
.ATT_STANDARDNAME
, feature
.getLabel()));
172 eigenschaften
.addContent(eigenschaft
);
173 if(feature
.isSupportsCategoricalData()){
174 //export feature states
175 Element listenwerte
= new Element(BfnXmlConstants
.EL_LISTENWERTE
);
176 eigenschaft
.addContent(listenwerte
);
177 Set
<TermVocabulary
<State
>> supportedCategoricalEnumerations
= feature
.getSupportedCategoricalEnumerations();
178 for (TermVocabulary
<State
> termVocabulary
: supportedCategoricalEnumerations
) {
179 Set
<State
> featureStates
= termVocabulary
.getTerms();
180 // int reihenfolge = 1;
181 for (State featureState
: featureStates
) {
182 Element lwert
= new Element(BfnXmlConstants
.EL_LWERT
);
183 // lwert.setAttribute(new Attribute(BfnXmlConstants.ATT_REIHENFOLGE, String.valueOf(reihenfolge)));
184 lwert
.addContent(featureState
.getLabel());
185 listenwerte
.addContent(lwert
);
194 private void exportTaxon(Taxon taxon
, Element parent
, BfnXmlExportState state
) {
195 Element taxonym
= new Element(BfnXmlConstants
.EL_TAXONYM
);
196 parent
.addContent(taxonym
);
198 //reihenfolge attribute
199 taxonym
.setAttribute(BfnXmlConstants
.ATT_REIHENFOLGE
, getExtension(taxon
, ExtensionType
.ORDER()));
200 //getIdentifier(taxon, BfnXmlConstants.UUID_REIHENFOLGE_IDENTIFIER_TYPE));
203 taxonym
.setAttribute(BfnXmlConstants
.ATT_TAXNR
, getIdentifier(taxon
, BfnXmlTransformer
.UUID_TAX_NR_IDENTIFIER_TYPE
));
206 exportWissName(taxon
, taxonym
);
209 Set
<Synonym
> synonyms
= taxon
.getSynonyms();
210 if(synonyms
.size()>0){
211 Element synonymeElement
= new Element(BfnXmlConstants
.EL_SYNONYME
);
212 taxonym
.addContent(synonymeElement
);
213 for (Synonym synonym
: synonyms
) {
214 Element synonymElement
= new Element(BfnXmlConstants
.EL_SYNONYM
);
215 synonymeElement
.addContent(synonymElement
);
216 exportWissName(synonym
, synonymElement
);
221 exportCommonName(taxon
, taxonym
);
224 exportFactualData(taxon
, taxonym
);
234 private String
getExtension(Taxon taxon
, ExtensionType order
) {
235 Set
<String
> set
= taxon
.getExtensions(order
);
236 if (set
.size() != 1){
237 logger
.warn("Exactly 1 order extension should exist, but has " + set
.size());
239 return set
.iterator().next();
243 return set
.iterator().next();
247 private String
getIdentifier(Taxon taxon
, UUID identifierUuid
) {
248 DefinedTerm identifierType
= HibernateProxyHelper
.deproxy(getTermService().load(identifierUuid
), DefinedTerm
.class);
249 Set
<String
> identfiers
= taxon
.getIdentifierStrings(identifierType
);
250 if(identfiers
.size()==1){
251 return identfiers
.iterator().next();
254 logger
.error("Taxon "+taxon
.getTitleCache()+" has none or multiple identifiers of type '"+identifierType
.getLabel()+"'");
259 private void exportWissName(TaxonBase
<?
> taxon
, Element parent
) {
260 Element wissName
= new Element(BfnXmlConstants
.EL_WISSNAME
);
261 parent
.addContent(wissName
);
263 INonViralName name
= taxon
.getName();
264 Rank rank
= name
.getRank();
266 exportEpithet(taxon
, wissName
, name
, rank
);
269 addNanteil(wissName
, BfnXmlConstants
.BEREICH_RANG
, BfnXmlTransformer
.getRankCodeForRank(rank
));
272 addNanteil(wissName
, BfnXmlConstants
.BEREICH_ORDNUNGSZAHL
, null);//TODO
273 addNanteil(wissName
, BfnXmlConstants
.BEREICH_AUTONYM
, null);//TODO
274 addNanteil(wissName
, BfnXmlConstants
.BEREICH_REICH
, null);//TODO
275 addNanteil(wissName
, BfnXmlConstants
.BEREICH_BASTARD
, null);//TODO
278 addNanteil(wissName
, BfnXmlConstants
.BEREICH_AUTOREN
, name
.getAuthorshipCache());
280 addNanteil(wissName
, BfnXmlConstants
.BEREICH_ZUSAETZE
, null);//TODO
281 addNanteil(wissName
, "SortWissName", null);//TODO
282 addNanteil(wissName
, "SortArtEpi", null);//TODO
283 addNanteil(wissName
, "SortDeutName", null);//TODO
286 addNanteil(wissName
, BfnXmlConstants
.BEREICH_WISSNAME
, name
.getTitleCache());
289 private void exportEpithet(TaxonBase
<?
> taxon
, Element wissName
, INonViralName name
, Rank rank
) {
291 Set
<IdentifiableSource
> sources
= taxon
.getSources();
292 for (IdentifiableSource identifiableSource
: sources
) {
293 if(identifiableSource
.getType().equals(OriginalSourceType
.Import
)
294 && identifiableSource
.getIdNamespace().equals(BfnXmlConstants
.EL_TAXONYM
+":"
295 +BfnXmlConstants
.EL_WISSNAME
+":"+BfnXmlConstants
.EL_NANTEIL
+":"+BfnXmlConstants
.BEREICH_EINDEUTIGER_CODE
)){
296 addNanteil(wissName
, BfnXmlConstants
.BEREICH_EINDEUTIGER_CODE
, identifiableSource
.getIdInSource());
301 addNanteil(wissName
, BfnXmlConstants
.BEREICH_EPITHETON1
, name
.getGenusOrUninomial());
302 if(rank
.isLowerThan(RankClass
.Genus
)){
303 String epitheton2
= name
.getInfraGenericEpithet();
304 if(epitheton2
==null){
305 epitheton2
= name
.getSpecificEpithet();
307 addNanteil(wissName
, BfnXmlConstants
.BEREICH_EPITHETON2
, epitheton2
);
310 String epitheton3
= null;
311 if(rank
.isLowerThan(RankClass
.Species
)){
312 epitheton3
= name
.getInfraSpecificEpithet();
314 if(epitheton3
==null){
315 epitheton3
= name
.getSpecificEpithet();
317 addNanteil(wissName
, BfnXmlConstants
.BEREICH_EPITHETON3
, epitheton3
);
320 addNanteil(wissName
, BfnXmlConstants
.BEREICH_EPITHETON4
, null);
321 addNanteil(wissName
, BfnXmlConstants
.BEREICH_EPITHETON5
, null);
324 private void exportCommonName(Taxon taxon
, Element taxonym
) {
325 Element deutscheNamen
= new Element(BfnXmlConstants
.EL_DEUTSCHENAMEN
);
326 taxonym
.addContent(deutscheNamen
);
329 Set
<TaxonDescription
> descriptions
= taxon
.getDescriptions();
330 for (TaxonDescription taxonDescription
: descriptions
) {
331 Set
<DescriptionElementBase
> elements
= taxonDescription
.getElements();
332 for (DescriptionElementBase descriptionElementBase
: elements
) {
333 if(descriptionElementBase
.isInstanceOf(CommonTaxonName
.class)){
334 CommonTaxonName commonName
= HibernateProxyHelper
.deproxy(descriptionElementBase
, CommonTaxonName
.class);
335 if(commonName
.getLanguage().equals(Language
.GERMAN())){
336 Element dName
= new Element(BfnXmlConstants
.EL_DNAME
);
337 Element trivialName
= new Element(BfnXmlConstants
.EL_TRIVIALNAME
);
338 deutscheNamen
.addContent(dName
);
339 dName
.addContent(trivialName
);
341 dName
.setAttribute(new Attribute(BfnXmlConstants
.ATT_SEQUENZ
, String
.valueOf(sequenz
)));
342 trivialName
.addContent(commonName
.getName());
350 private void addNanteil(Element element
, String bereich
, String textContent
) {
351 Element nanteil
= new Element(BfnXmlConstants
.EL_NANTEIL
);
352 nanteil
.setAttribute(new Attribute(BfnXmlConstants
.ATT_BEREICH
, bereich
));
353 if(textContent
!=null){
354 nanteil
.addContent(textContent
);
356 element
.addContent(nanteil
);
360 protected boolean doCheck(BfnXmlExportState state
) {
365 protected boolean isIgnore(BfnXmlExportState state
) {
369 private final class TaxonComparator
implements Comparator
<TaxonNode
> {
371 public int compare(TaxonNode o1
, TaxonNode o2
) {
372 Taxon taxon1
= o1
.getTaxon();
373 Taxon taxon2
= o2
.getTaxon();
375 int reihenfolge1
= Integer
.parseInt(getExtension(taxon1
, ExtensionType
.ORDER()));
376 int reihenfolge2
= Integer
.parseInt(getExtension(taxon2
, ExtensionType
.ORDER()));
378 return reihenfolge1
-reihenfolge2
;