3d92d889a5965d2d8bd6bf599c5163b42e174471
[cdmlib-apps.git] / app-import / src / main / java / eu / etaxonomy / cdm / io / redlist / bfnXml / out / BfnXmlTaxonNameExport.java
1 /**
2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
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.
8 */
9 package eu.etaxonomy.cdm.io.redlist.bfnXml.out;
10
11 import java.util.Comparator;
12 import java.util.List;
13 import java.util.Set;
14 import java.util.UUID;
15
16 import org.jdom2.Attribute;
17 import org.jdom2.Document;
18 import org.jdom2.Element;
19 import org.springframework.stereotype.Component;
20
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;
45
46
47
48 /**
49 *
50 * @author pplitzner
51 * @since May 3, 2016
52 *
53 */
54 @Component
55 public class BfnXmlTaxonNameExport extends BfnXmlExportBase {
56
57 private static final long serialVersionUID = -931703660108981011L;
58
59 public BfnXmlTaxonNameExport(){
60 super();
61 }
62
63 @Override
64 protected void doInvoke(BfnXmlExportState state){
65 startTransaction(true);
66
67 Document document = state.getConfig().getDocument();
68
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);
75
76 exportFeatures(roteListeDaten);
77
78 exportTaxonomy(classification, roteListeDaten, state);
79
80 }
81
82 }
83
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);
91 }
92 }
93
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);
100
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);
119
120
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());
128 // continue;
129 // }
130 // addIwert(bezugsraum, feature.getLabel(), stateData.iterator().next().getState().getLabel());
131 // }
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());
135 // }
136 // }
137 }
138 }
139
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());
145 }
146 }
147 }
148
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());
157 continue;
158 }
159 addIwert(parent, feature.getLabel(), stateData.iterator().next().getState().getLabel());
160 }
161 }
162 }
163
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);
187
188 // reihenfolge++;
189 }
190 }
191 }
192 }
193 }
194
195 private void exportTaxon(Taxon taxon, Element parent, BfnXmlExportState state) {
196 Element taxonym = new Element(BfnXmlConstants.EL_TAXONYM);
197 parent.addContent(taxonym);
198
199 //reihenfolge attribute
200 taxonym.setAttribute(BfnXmlConstants.ATT_REIHENFOLGE, getExtension(taxon, ExtensionType.ORDER()));
201 //getIdentifier(taxon, BfnXmlConstants.UUID_REIHENFOLGE_IDENTIFIER_TYPE));
202
203 //taxNr attribute
204 taxonym.setAttribute(BfnXmlConstants.ATT_TAXNR, getIdentifier(taxon, BfnXmlTransformer.UUID_TAX_NR_IDENTIFIER_TYPE));
205
206
207 exportWissName(taxon, taxonym);
208
209 //synonyms
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);
218 }
219 }
220
221 //common name
222 exportCommonName(taxon, taxonym);
223
224 //factual data
225 exportFactualData(taxon, taxonym);
226
227
228 }
229
230 /**
231 * @param taxon
232 * @param order
233 * @return
234 */
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());
239 if (set.size() > 1){
240 return set.iterator().next();
241 }
242 return null;
243 }else{
244 return set.iterator().next();
245 }
246 }
247
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();
253 }
254 else{
255 logger.error("Taxon "+taxon.getTitleCache()+" has none or multiple identifiers of type '"+identifierType.getLabel()+"'");
256 return null;
257 }
258 }
259
260 private void exportWissName(TaxonBase<?> taxon, Element parent) {
261 Element wissName = new Element(BfnXmlConstants.EL_WISSNAME);
262 parent.addContent(wissName);
263
264 INonViralName name = taxon.getName();
265 Rank rank = name.getRank();
266 //epithet 1,2,3
267 exportEpithet(taxon, wissName, name, rank);
268
269 //rank
270 addNanteil(wissName, BfnXmlConstants.BEREICH_RANG, BfnXmlTransformer.getRankCodeForRank(rank));
271
272
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
277
278 //authors
279 addNanteil(wissName, BfnXmlConstants.BEREICH_AUTOREN, name.getAuthorshipCache());
280
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
285
286 //wissName
287 addNanteil(wissName, BfnXmlConstants.BEREICH_WISSNAME, name.getTitleCache());
288 }
289
290 private void exportEpithet(TaxonBase<?> taxon, Element wissName, INonViralName name, Rank rank) {
291 //eindeutiger Code
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());
298 }
299 }
300
301 //epitheton1-2
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();
307 }
308 addNanteil(wissName, BfnXmlConstants.BEREICH_EPITHETON2, epitheton2);
309 }
310 //epitheton3
311 String epitheton3 = null;
312 if(rank.isLower(Rank.SPECIES())){
313 epitheton3 = name.getInfraSpecificEpithet();
314 }
315 if(epitheton3==null){
316 epitheton3 = name.getSpecificEpithet();
317 }
318 addNanteil(wissName, BfnXmlConstants.BEREICH_EPITHETON3, epitheton3);
319
320 //epitheton4-5
321 addNanteil(wissName, BfnXmlConstants.BEREICH_EPITHETON4, null);
322 addNanteil(wissName, BfnXmlConstants.BEREICH_EPITHETON5, null);
323 }
324
325 private void exportCommonName(Taxon taxon, Element taxonym) {
326 Element deutscheNamen = new Element(BfnXmlConstants.EL_DEUTSCHENAMEN);
327 taxonym.addContent(deutscheNamen);
328
329 int sequenz = 1;
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);
341
342 dName.setAttribute(new Attribute(BfnXmlConstants.ATT_SEQUENZ, String.valueOf(sequenz)));
343 trivialName.addContent(commonName.getName());
344 }
345 }
346 }
347 sequenz++;
348 }
349 }
350
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);
356 }
357 element.addContent(nanteil);
358 }
359
360 @Override
361 protected boolean doCheck(BfnXmlExportState state) {
362 return false;
363 }
364
365 @Override
366 protected boolean isIgnore(BfnXmlExportState state) {
367 return false;
368 }
369
370 private final class TaxonComparator implements Comparator<TaxonNode> {
371 @Override
372 public int compare(TaxonNode o1, TaxonNode o2) {
373 Taxon taxon1 = o1.getTaxon();
374 Taxon taxon2 = o2.getTaxon();
375
376 int reihenfolge1 = Integer.parseInt(getExtension(taxon1, ExtensionType.ORDER()));
377 int reihenfolge2 = Integer.parseInt(getExtension(taxon2, ExtensionType.ORDER()));
378
379 return reihenfolge1-reihenfolge2;
380 }
381 }
382
383 }