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
.jdom2
.Attribute
;
17 import org
.jdom2
.Document
;
18 import org
.jdom2
.Element
;
19 import org
.springframework
.stereotype
.Component
;
21 import eu
.etaxonomy
.cdm
.hibernate
.HibernateProxyHelper
;
22 import eu
.etaxonomy
.cdm
.io
.redlist
.bfnXml
.BfnXmlConstants
;
23 import eu
.etaxonomy
.cdm
.io
.redlist
.bfnXml
.in
.BfnXmlTransformer
;
24 import eu
.etaxonomy
.cdm
.model
.common
.ExtensionType
;
25 import eu
.etaxonomy
.cdm
.model
.common
.IdentifiableSource
;
26 import eu
.etaxonomy
.cdm
.model
.common
.Language
;
27 import eu
.etaxonomy
.cdm
.model
.description
.CategoricalData
;
28 import eu
.etaxonomy
.cdm
.model
.description
.CommonTaxonName
;
29 import eu
.etaxonomy
.cdm
.model
.description
.DescriptionElementBase
;
30 import eu
.etaxonomy
.cdm
.model
.description
.Feature
;
31 import eu
.etaxonomy
.cdm
.model
.description
.State
;
32 import eu
.etaxonomy
.cdm
.model
.description
.StateData
;
33 import eu
.etaxonomy
.cdm
.model
.description
.TaxonDescription
;
34 import eu
.etaxonomy
.cdm
.model
.description
.TextData
;
35 import eu
.etaxonomy
.cdm
.model
.name
.INonViralName
;
36 import eu
.etaxonomy
.cdm
.model
.name
.Rank
;
37 import eu
.etaxonomy
.cdm
.model
.reference
.OriginalSourceType
;
38 import eu
.etaxonomy
.cdm
.model
.taxon
.Classification
;
39 import eu
.etaxonomy
.cdm
.model
.taxon
.Synonym
;
40 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
41 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
42 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonNode
;
43 import eu
.etaxonomy
.cdm
.model
.term
.DefinedTerm
;
44 import eu
.etaxonomy
.cdm
.model
.term
.TermVocabulary
;
55 public class BfnXmlTaxonNameExport
extends BfnXmlExportBase
{
57 private static final long serialVersionUID
= -931703660108981011L;
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
);
84 private void exportTaxonomy(Classification classification
, Element roteListeDaten
, BfnXmlExportState state
) {
85 Element taxonyme
= new Element(BfnXmlConstants
.EL_TAXONYME
);
86 roteListeDaten
.addContent(taxonyme
);
87 List
<TaxonNode
> childNodes
= classification
.getChildNodes();
88 java
.util
.Collections
.sort(childNodes
, new TaxonComparator());
89 for (TaxonNode taxonNode
: childNodes
) {
90 exportTaxon(taxonNode
.getTaxon(), taxonyme
, state
);
94 private void exportFactualData(Taxon taxon
, Element parent
) {
95 Element informationen
= new Element(BfnXmlConstants
.EL_INFORMATIONEN
);
96 parent
.addContent(informationen
);
97 Element bezugsraum
= new Element(BfnXmlConstants
.EL_BEZUGSRAUM
);
98 bezugsraum
.setAttribute(new Attribute(BfnXmlConstants
.ATT_NAME
, BfnXmlConstants
.BEZUGRAUM_BUND
));
99 informationen
.addContent(bezugsraum
);
101 Set
<TaxonDescription
> descriptions
= taxon
.getDescriptions();
102 for (TaxonDescription taxonDescription
: descriptions
) {
103 //TODO: export only red list features ??
104 Set
<DescriptionElementBase
> descriptionElements
= taxonDescription
.getElements();
105 exportCategoricalData(BfnXmlConstants
.VOC_RL_KAT
, descriptionElements
, taxon
, parent
);
106 exportCategoricalData(BfnXmlConstants
.VOC_KAT
, descriptionElements
, taxon
, parent
);
107 exportCategoricalData(BfnXmlConstants
.VOC_NEOBIOTA
, descriptionElements
, taxon
, parent
);
108 exportCategoricalData(BfnXmlConstants
.VOC_AKTUELLE_BESTANDSSTITUATION
, descriptionElements
, taxon
, parent
);
109 exportCategoricalData(BfnXmlConstants
.VOC_LANGFRISTIGER_BESTANDSTREND
, descriptionElements
, taxon
, parent
);
110 exportCategoricalData(BfnXmlConstants
.VOC_KURZFRISTIGER_BESTANDSTREND
, descriptionElements
, taxon
, parent
);
111 exportCategoricalData(BfnXmlConstants
.VOC_RISIKOFAKTOREN
, descriptionElements
, taxon
, parent
);
112 exportCategoricalData(BfnXmlConstants
.VOC_SONDERFAELLE
, descriptionElements
, taxon
, parent
);
113 exportTextData(BfnXmlConstants
.FEAT_LETZTER_NACHWEIS
, descriptionElements
, taxon
, parent
);
114 exportCategoricalData(BfnXmlConstants
.VOC_VERANTWORTLICHKEIT
, descriptionElements
, taxon
, parent
);
115 exportTextData(BfnXmlConstants
.FEAT_KOMMENTAR_TAXONOMIE
, descriptionElements
, taxon
, parent
);
116 exportTextData(BfnXmlConstants
.FEAT_KOMMENTAR_GEFAEHRDUNG
, descriptionElements
, taxon
, parent
);
117 exportTextData(BfnXmlConstants
.FEAT_WEITERE_KOMMENTARE
, descriptionElements
, taxon
, parent
);
118 exportCategoricalData(BfnXmlConstants
.VOC_ALTE_RL_KAT
, descriptionElements
, taxon
, parent
);
121 // for (DescriptionElementBase descriptionElementBase : descriptionElements) {
122 // if(descriptionElementBase.isInstanceOf(CategoricalData.class)){
123 // CategoricalData categoricalData = HibernateProxyHelper.deproxy(descriptionElementBase, CategoricalData.class);
124 // Feature feature = categoricalData.getFeature();
125 // List<StateData> stateData = categoricalData.getStateData();
126 // if(stateData.size()!=1){
127 // logger.error("StateData does not have a size of 1 for feature "+feature.getLabel()+" in taxon "+taxon.getTitleCache());
130 // addIwert(bezugsraum, feature.getLabel(), stateData.iterator().next().getState().getLabel());
132 // else if(descriptionElementBase.isInstanceOf(TextData.class)){
133 // TextData textData = HibernateProxyHelper.deproxy(descriptionElementBase, TextData.class);
134 // addIwert(bezugsraum, textData.getFeature().getLabel(), textData.getLanguageText(Language.GERMAN()).getText());
140 private void exportTextData(String featureLabel
, Set
<DescriptionElementBase
> descriptionElements
, Taxon taxon
, Element parent
){
141 for (DescriptionElementBase descriptionElementBase
: descriptionElements
) {
142 if(descriptionElementBase
.getFeature().getLabel().equals(featureLabel
)){
143 TextData textData
= HibernateProxyHelper
.deproxy(descriptionElementBase
, TextData
.class);
144 addIwert(parent
, textData
.getFeature().getLabel(), textData
.getLanguageText(Language
.GERMAN()).getText());
149 private void exportCategoricalData(String featureLabel
, Set
<DescriptionElementBase
> descriptionElements
, Taxon taxon
, Element parent
){
150 for (DescriptionElementBase descriptionElementBase
: descriptionElements
) {
151 if(descriptionElementBase
.getFeature().getLabel().equals(featureLabel
)){
152 CategoricalData categoricalData
= HibernateProxyHelper
.deproxy(descriptionElementBase
, CategoricalData
.class);
153 Feature feature
= categoricalData
.getFeature();
154 List
<StateData
> stateData
= categoricalData
.getStateData();
155 if(stateData
.size()!=1){
156 logger
.error("StateData does not have a size of 1 for feature "+feature
.getLabel()+" in taxon "+taxon
.getTitleCache());
159 addIwert(parent
, feature
.getLabel(), stateData
.iterator().next().getState().getLabel());
164 private void exportFeatures(Element roteListeDaten
) {
165 Element eigenschaften
= new Element(BfnXmlConstants
.EL_EIGENSCHAFTEN
);
166 roteListeDaten
.addContent(eigenschaften
);
167 TermVocabulary
<Feature
> redListFeaturesVoc
= getVocabularyService().load(BfnXmlTransformer
.vocRLFeatures
);
168 Set
<Feature
> terms
= redListFeaturesVoc
.getTerms();
169 for (Feature feature
: terms
) {
170 //export red list features
171 Element eigenschaft
= new Element(BfnXmlConstants
.EL_EIGENSCHAFT
);
172 eigenschaft
.setAttribute(new Attribute(BfnXmlConstants
.ATT_STANDARDNAME
, feature
.getLabel()));
173 eigenschaften
.addContent(eigenschaft
);
174 if(feature
.isSupportsCategoricalData()){
175 //export feature states
176 Element listenwerte
= new Element(BfnXmlConstants
.EL_LISTENWERTE
);
177 eigenschaft
.addContent(listenwerte
);
178 Set
<TermVocabulary
<State
>> supportedCategoricalEnumerations
= feature
.getSupportedCategoricalEnumerations();
179 for (TermVocabulary
<State
> termVocabulary
: supportedCategoricalEnumerations
) {
180 Set
<State
> featureStates
= termVocabulary
.getTerms();
181 // int reihenfolge = 1;
182 for (State featureState
: featureStates
) {
183 Element lwert
= new Element(BfnXmlConstants
.EL_LWERT
);
184 // lwert.setAttribute(new Attribute(BfnXmlConstants.ATT_REIHENFOLGE, String.valueOf(reihenfolge)));
185 lwert
.addContent(featureState
.getLabel());
186 listenwerte
.addContent(lwert
);
195 private void exportTaxon(Taxon taxon
, Element parent
, BfnXmlExportState state
) {
196 Element taxonym
= new Element(BfnXmlConstants
.EL_TAXONYM
);
197 parent
.addContent(taxonym
);
199 //reihenfolge attribute
200 taxonym
.setAttribute(BfnXmlConstants
.ATT_REIHENFOLGE
, getExtension(taxon
, ExtensionType
.ORDER()));
201 //getIdentifier(taxon, BfnXmlConstants.UUID_REIHENFOLGE_IDENTIFIER_TYPE));
204 taxonym
.setAttribute(BfnXmlConstants
.ATT_TAXNR
, getIdentifier(taxon
, BfnXmlTransformer
.UUID_TAX_NR_IDENTIFIER_TYPE
));
207 exportWissName(taxon
, taxonym
);
210 Set
<Synonym
> synonyms
= taxon
.getSynonyms();
211 if(synonyms
.size()>0){
212 Element synonymeElement
= new Element(BfnXmlConstants
.EL_SYNONYME
);
213 taxonym
.addContent(synonymeElement
);
214 for (Synonym synonym
: synonyms
) {
215 Element synonymElement
= new Element(BfnXmlConstants
.EL_SYNONYM
);
216 synonymeElement
.addContent(synonymElement
);
217 exportWissName(synonym
, synonymElement
);
222 exportCommonName(taxon
, taxonym
);
225 exportFactualData(taxon
, taxonym
);
235 private String
getExtension(Taxon taxon
, ExtensionType order
) {
236 Set
<String
> set
= taxon
.getExtensions(order
);
237 if (set
.size() != 1){
238 logger
.warn("Exactly 1 order extension should exist, but has " + set
.size());
240 return set
.iterator().next();
244 return set
.iterator().next();
248 private String
getIdentifier(Taxon taxon
, UUID identifierUuid
) {
249 DefinedTerm identifierType
= HibernateProxyHelper
.deproxy(getTermService().load(identifierUuid
), DefinedTerm
.class);
250 Set
<String
> identfiers
= taxon
.getIdentifiers(identifierType
);
251 if(identfiers
.size()==1){
252 return identfiers
.iterator().next();
255 logger
.error("Taxon "+taxon
.getTitleCache()+" has none or multiple identifiers of type '"+identifierType
.getLabel()+"'");
260 private void exportWissName(TaxonBase
<?
> taxon
, Element parent
) {
261 Element wissName
= new Element(BfnXmlConstants
.EL_WISSNAME
);
262 parent
.addContent(wissName
);
264 INonViralName name
= taxon
.getName();
265 Rank rank
= name
.getRank();
267 exportEpithet(taxon
, wissName
, name
, rank
);
270 addNanteil(wissName
, BfnXmlConstants
.BEREICH_RANG
, BfnXmlTransformer
.getRankCodeForRank(rank
));
273 addNanteil(wissName
, BfnXmlConstants
.BEREICH_ORDNUNGSZAHL
, null);//TODO
274 addNanteil(wissName
, BfnXmlConstants
.BEREICH_AUTONYM
, null);//TODO
275 addNanteil(wissName
, BfnXmlConstants
.BEREICH_REICH
, null);//TODO
276 addNanteil(wissName
, BfnXmlConstants
.BEREICH_BASTARD
, null);//TODO
279 addNanteil(wissName
, BfnXmlConstants
.BEREICH_AUTOREN
, name
.getAuthorshipCache());
281 addNanteil(wissName
, BfnXmlConstants
.BEREICH_ZUSAETZE
, null);//TODO
282 addNanteil(wissName
, "SortWissName", null);//TODO
283 addNanteil(wissName
, "SortArtEpi", null);//TODO
284 addNanteil(wissName
, "SortDeutName", null);//TODO
287 addNanteil(wissName
, BfnXmlConstants
.BEREICH_WISSNAME
, name
.getTitleCache());
290 private void exportEpithet(TaxonBase
<?
> taxon
, Element wissName
, INonViralName name
, Rank rank
) {
292 Set
<IdentifiableSource
> sources
= taxon
.getSources();
293 for (IdentifiableSource identifiableSource
: sources
) {
294 if(identifiableSource
.getType().equals(OriginalSourceType
.Import
)
295 && identifiableSource
.getIdNamespace().equals(BfnXmlConstants
.EL_TAXONYM
+":"
296 +BfnXmlConstants
.EL_WISSNAME
+":"+BfnXmlConstants
.EL_NANTEIL
+":"+BfnXmlConstants
.BEREICH_EINDEUTIGER_CODE
)){
297 addNanteil(wissName
, BfnXmlConstants
.BEREICH_EINDEUTIGER_CODE
, identifiableSource
.getIdInSource());
302 addNanteil(wissName
, BfnXmlConstants
.BEREICH_EPITHETON1
, name
.getGenusOrUninomial());
303 if(rank
.isLower(Rank
.GENUS())){
304 String epitheton2
= name
.getInfraGenericEpithet();
305 if(epitheton2
==null){
306 epitheton2
= name
.getSpecificEpithet();
308 addNanteil(wissName
, BfnXmlConstants
.BEREICH_EPITHETON2
, epitheton2
);
311 String epitheton3
= null;
312 if(rank
.isLower(Rank
.SPECIES())){
313 epitheton3
= name
.getInfraSpecificEpithet();
315 if(epitheton3
==null){
316 epitheton3
= name
.getSpecificEpithet();
318 addNanteil(wissName
, BfnXmlConstants
.BEREICH_EPITHETON3
, epitheton3
);
321 addNanteil(wissName
, BfnXmlConstants
.BEREICH_EPITHETON4
, null);
322 addNanteil(wissName
, BfnXmlConstants
.BEREICH_EPITHETON5
, null);
325 private void exportCommonName(Taxon taxon
, Element taxonym
) {
326 Element deutscheNamen
= new Element(BfnXmlConstants
.EL_DEUTSCHENAMEN
);
327 taxonym
.addContent(deutscheNamen
);
330 Set
<TaxonDescription
> descriptions
= taxon
.getDescriptions();
331 for (TaxonDescription taxonDescription
: descriptions
) {
332 Set
<DescriptionElementBase
> elements
= taxonDescription
.getElements();
333 for (DescriptionElementBase descriptionElementBase
: elements
) {
334 if(descriptionElementBase
.isInstanceOf(CommonTaxonName
.class)){
335 CommonTaxonName commonName
= HibernateProxyHelper
.deproxy(descriptionElementBase
, CommonTaxonName
.class);
336 if(commonName
.getLanguage().equals(Language
.GERMAN())){
337 Element dName
= new Element(BfnXmlConstants
.EL_DNAME
);
338 Element trivialName
= new Element(BfnXmlConstants
.EL_TRIVIALNAME
);
339 deutscheNamen
.addContent(dName
);
340 dName
.addContent(trivialName
);
342 dName
.setAttribute(new Attribute(BfnXmlConstants
.ATT_SEQUENZ
, String
.valueOf(sequenz
)));
343 trivialName
.addContent(commonName
.getName());
351 private void addNanteil(Element element
, String bereich
, String textContent
) {
352 Element nanteil
= new Element(BfnXmlConstants
.EL_NANTEIL
);
353 nanteil
.setAttribute(new Attribute(BfnXmlConstants
.ATT_BEREICH
, bereich
));
354 if(textContent
!=null){
355 nanteil
.addContent(textContent
);
357 element
.addContent(nanteil
);
361 protected boolean doCheck(BfnXmlExportState state
) {
366 protected boolean isIgnore(BfnXmlExportState state
) {
370 private final class TaxonComparator
implements Comparator
<TaxonNode
> {
372 public int compare(TaxonNode o1
, TaxonNode o2
) {
373 Taxon taxon1
= o1
.getTaxon();
374 Taxon taxon2
= o2
.getTaxon();
376 int reihenfolge1
= Integer
.parseInt(getExtension(taxon1
, ExtensionType
.ORDER()));
377 int reihenfolge2
= Integer
.parseInt(getExtension(taxon2
, ExtensionType
.ORDER()));
379 return reihenfolge1
-reihenfolge2
;