Added Hierarchy to imported vocabularies and abbrevated labels as well as id in source.
[cdmlib-apps.git] / app-import / src / main / java / eu / etaxonomy / cdm / io / redlist / bfnXml / BfnXmlImportFeature.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
10 package eu.etaxonomy.cdm.io.redlist.bfnXml;
11
12 import java.util.ArrayList;
13 import java.util.Arrays;
14 import java.util.List;
15 import java.util.UUID;
16
17 import javax.management.ObjectInstance;
18
19 import org.apache.commons.lang.StringUtils;
20 import org.apache.log4j.Logger;
21 import org.hibernate.id.UUIDGenerator;
22 import org.jdom.Element;
23 import org.jdom.Namespace;
24 import org.springframework.stereotype.Component;
25 import org.springframework.transaction.TransactionStatus;
26
27 import eu.etaxonomy.cdm.api.service.IClassificationService;
28 import eu.etaxonomy.cdm.api.service.IDescriptionService;
29 import eu.etaxonomy.cdm.api.service.IFeatureNodeService;
30 import eu.etaxonomy.cdm.api.service.ITaxonService;
31 import eu.etaxonomy.cdm.api.service.ITermService;
32 import eu.etaxonomy.cdm.api.service.IVocabularyService;
33 import eu.etaxonomy.cdm.common.ResultWrapper;
34 import eu.etaxonomy.cdm.common.XmlHelp;
35 import eu.etaxonomy.cdm.io.common.ICdmIO;
36 import eu.etaxonomy.cdm.io.common.ImportHelper;
37 import eu.etaxonomy.cdm.io.common.MapWrapper;
38 import eu.etaxonomy.cdm.model.common.DefinedTermBase;
39 import eu.etaxonomy.cdm.model.common.Language;
40 import eu.etaxonomy.cdm.model.common.OrderedTermVocabulary;
41 import eu.etaxonomy.cdm.model.common.TermType;
42 import eu.etaxonomy.cdm.model.common.TermVocabulary;
43 import eu.etaxonomy.cdm.model.common.VocabularyEnum;
44 import eu.etaxonomy.cdm.model.description.CategoricalData;
45 import eu.etaxonomy.cdm.model.description.DescriptionBase;
46 import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
47 import eu.etaxonomy.cdm.model.description.Feature;
48 import eu.etaxonomy.cdm.model.description.FeatureNode;
49 import eu.etaxonomy.cdm.model.description.FeatureTree;
50 import eu.etaxonomy.cdm.model.description.State;
51 import eu.etaxonomy.cdm.model.description.StateData;
52 import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
53 import eu.etaxonomy.cdm.model.name.NonViralName;
54 import eu.etaxonomy.cdm.model.name.Rank;
55 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
56 import eu.etaxonomy.cdm.model.taxon.Classification;
57 import eu.etaxonomy.cdm.model.taxon.Synonym;
58 import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;
59 import eu.etaxonomy.cdm.model.taxon.Taxon;
60 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
61 import eu.etaxonomy.cdm.persistence.dao.description.IFeatureDao;
62 import eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException;
63 import eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl;
64 import eu.etaxonomy.cdm.strategy.parser.ParserProblem;
65 /**
66 *
67 * @author a.oppermann
68 * @date 04.07.2013
69 *
70 */
71 @Component
72 public class BfnXmlImportFeature extends BfnXmlImportBase implements ICdmIO<BfnXmlImportState> {
73 private static final Logger logger = Logger.getLogger(BfnXmlImportFeature.class);
74
75 public BfnXmlImportFeature(){
76 super();
77 }
78
79 @Override
80 public boolean doCheck(BfnXmlImportState state){
81 boolean result = true;
82 //TODO needs to be implemented
83 return result;
84 }
85
86 @Override
87 @SuppressWarnings({ "unchecked", "rawtypes" })
88 public void doInvoke(BfnXmlImportState state){
89
90 IVocabularyService vocabularyService = getVocabularyService();
91
92
93 logger.warn("start create Features in CDM...");
94 ResultWrapper<Boolean> success = ResultWrapper.NewInstance(true);
95 String childName;
96 boolean obligatory;
97 BfnXmlImportConfigurator config = state.getConfig();
98 Element elDataSet = getDataSetElement(config);
99 Namespace bfnNamespace = config.getBfnXmlNamespace();
100
101 List contentXML = elDataSet.getContent();
102 Element currentElement = null;
103 for(Object object:contentXML){
104
105 if(object instanceof Element){
106 currentElement = (Element)object;
107
108 if(currentElement.getName().equalsIgnoreCase("ROTELISTEDATEN")){
109
110 TransactionStatus tx = startTransaction();
111
112 childName = "EIGENSCHAFTEN";
113 obligatory = false;
114 Element elFeatureNames = XmlHelp.getSingleChildElement(success, currentElement, childName, bfnNamespace, obligatory);
115
116 String bfnElementName = "EIGENSCHAFT";
117 List<Element> elFeatureList = (List<Element>)elFeatureNames.getChildren(bfnElementName, bfnNamespace);
118 List<Feature> featureList = new ArrayList<Feature>();
119 //for each taxonName
120 for (Element elFeature : elFeatureList){
121
122 if(elFeature.getAttributeValue("standardname", bfnNamespace).equalsIgnoreCase("RL Kat.")){
123 makeFeature(vocabularyService, featureList,success, obligatory, bfnNamespace,elFeature, state);
124 }
125 String featureLabel = "Kat. +/-";
126 if(elFeature.getAttributeValue("standardname").equalsIgnoreCase(featureLabel)){
127 makeFeature(vocabularyService, featureList,success, obligatory, bfnNamespace,elFeature, state);
128 }
129 if(elFeature.getAttributeValue("standardname").equalsIgnoreCase("aktuelle Bestandsstituation")){
130 makeFeature(vocabularyService, featureList,success, obligatory, bfnNamespace,elFeature, state);
131 }
132 if(elFeature.getAttributeValue("standardname").equalsIgnoreCase("langfristiger Bestandstrend")){
133 makeFeature(vocabularyService, featureList,success, obligatory, bfnNamespace,elFeature, state);
134 }
135 if(elFeature.getAttributeValue("standardname").equalsIgnoreCase("kurzfristiger Bestandstrend")){
136 makeFeature(vocabularyService, featureList,success, obligatory, bfnNamespace,elFeature, state);
137 }
138 if(elFeature.getAttributeValue("standardname").equalsIgnoreCase("Risikofaktoren")){
139 makeFeature(vocabularyService, featureList,success, obligatory, bfnNamespace,elFeature, state);
140 }
141 if(elFeature.getAttributeValue("standardname").equalsIgnoreCase("Verantwortlichkeit")){
142 makeFeature(vocabularyService, featureList,success, obligatory, bfnNamespace,elFeature, state);
143 }
144 if(elFeature.getAttributeValue("standardname").equalsIgnoreCase("alte RL- Kat.")){
145 makeFeature(vocabularyService, featureList,success, obligatory, bfnNamespace,elFeature, state);
146 }
147 if(elFeature.getAttributeValue("standardname").equalsIgnoreCase("Neobiota")){
148 makeFeature(vocabularyService, featureList,success, obligatory, bfnNamespace,elFeature, state);
149 }
150 if(elFeature.getAttributeValue("standardname").equalsIgnoreCase("Eindeutiger Code")){
151 makeFeature(vocabularyService, featureList,success, obligatory, bfnNamespace,elFeature, state);
152 }
153 if(elFeature.getAttributeValue("standardname").equalsIgnoreCase("Kommentar zur Taxonomie")){
154 makeFeature(vocabularyService, featureList,success, obligatory, bfnNamespace,elFeature, state);
155 }
156 if(elFeature.getAttributeValue("standardname").equalsIgnoreCase("Kommentar zur Gefährdung")){
157 makeFeature(vocabularyService, featureList,success, obligatory, bfnNamespace,elFeature, state);
158 }
159 if(elFeature.getAttributeValue("standardname").equalsIgnoreCase("Sonderfälle")){
160 makeFeature(vocabularyService, featureList,success, obligatory, bfnNamespace,elFeature, state);
161 }
162 if(elFeature.getAttributeValue("standardname").equalsIgnoreCase("Letzter Nachweis")){
163 makeFeature(vocabularyService, featureList,success, obligatory, bfnNamespace,elFeature, state);
164 }
165 if(elFeature.getAttributeValue("standardname").equalsIgnoreCase("Weitere Kommentare")){
166 makeFeature(vocabularyService, featureList,success, obligatory, bfnNamespace,elFeature, state);
167 }
168 }
169 createFeatureTree(featureList);
170 commitTransaction(tx);
171
172 logger.info("end create features ...");
173
174 if (!success.getValue()){
175 state.setUnsuccessfull();
176 }
177 return;
178 }
179 }
180 }
181 return;
182
183 }
184
185 /**
186 * @param featureList
187 */
188 private void createFeatureTree(List<Feature> featureList) {
189 FeatureTree featureTree = FeatureTree.NewInstance(featureList);
190 String featureTreeName = "RedListFeatureTree";
191 featureTree.setTitleCache(featureTreeName, true);
192 getFeatureTreeService().save(featureTree);
193 }
194
195 /**
196 *
197 * @param vocabularyService
198 * @param featureList
199 * @param success
200 * @param obligatory
201 * @param bfnNamespace
202 * @param elFeature
203 * @param state
204 */
205 private void makeFeature(IVocabularyService vocabularyService,
206 List<Feature> featureList,
207 ResultWrapper<Boolean> success, boolean obligatory,
208 Namespace bfnNamespace, Element elFeature, BfnXmlImportState state) {
209 String childName;
210 String strRlKat = elFeature.getAttributeValue("standardname");
211 UUID featureUUID = null;
212 try {
213 featureUUID = BfnXmlTransformer.getRedlistFeatureUUID(strRlKat);
214 } catch (UnknownCdmTypeException e) {
215 e.printStackTrace();
216 }
217 Feature redListCat = getFeature(state, featureUUID, strRlKat, strRlKat, strRlKat, null);
218 featureList.add(redListCat);
219 childName = "LISTENWERTE";
220 Element elListValues = XmlHelp.getSingleChildElement(success, elFeature, childName, bfnNamespace, obligatory);
221 if(elListValues != null && !elListValues.getContent().isEmpty()){
222 String childElementName = "LWERT";
223 createOrUpdateStates(bfnNamespace, elListValues, childElementName, redListCat, state);
224 }
225 createOrUpdateTermVocabulary(TermType.Feature, vocabularyService, redListCat, "RedList Feature");
226 }
227
228 /**
229 * @param vocabularyService
230 * @param term
231 */
232 @SuppressWarnings({ "unchecked", "rawtypes" })
233 private TermVocabulary createOrUpdateTermVocabulary(TermType termType, IVocabularyService vocabularyService, DefinedTermBase term, String strTermVocabulary) {
234 TermVocabulary termVocabulary = null;
235 List<TermVocabulary> vocList = vocabularyService.list(TermVocabulary.class, null, null, null, VOC_CLASSIFICATION_INIT_STRATEGY);
236 for(TermVocabulary tv : vocList){
237 if(tv.getTitleCache().equalsIgnoreCase(strTermVocabulary)){
238 termVocabulary = tv;
239 }
240 }
241 if(termVocabulary == null){
242 termVocabulary = TermVocabulary.NewInstance(termType, strTermVocabulary, strTermVocabulary, strTermVocabulary, null);
243 }
244 termVocabulary.addTerm(term);
245 vocabularyService.saveOrUpdate(termVocabulary);
246
247 return termVocabulary;
248 }
249
250
251 /**
252 * @param success
253 * @param bfnNamespace
254 * @param elListValues
255 * @param childElementName
256 * @param redListCat
257 */
258
259 @SuppressWarnings({ "unchecked", "rawtypes"})
260 private void createOrUpdateStates(Namespace bfnNamespace, Element elListValues, String childElementName,
261 Feature redListCat, BfnXmlImportState state) {
262
263 List<Element> elListValueList = (List<Element>)elListValues.getChildren(childElementName, bfnNamespace);
264 // List<StateData> stateList = new ArrayList<StateData>();
265
266 OrderedTermVocabulary termVocabulary = null;
267 for(Element elListValue:elListValueList){
268 String listValue = elListValue.getTextNormalize();
269 String matchedListValue;
270 UUID stateTermUuid = null;
271 UUID vocabularyStateUuid = null;
272 try {
273 vocabularyStateUuid = BfnXmlTransformer.getRedlistVocabularyUUID(redListCat.toString());
274 } catch (UnknownCdmTypeException e1) {
275 vocabularyStateUuid = UUID.randomUUID();
276 logger.warn("Element: " + listValue + "\n"+ e1);
277 }
278 try {
279 matchedListValue = BfnXmlTransformer.redListString2RedListCode(listValue);
280 } catch (UnknownCdmTypeException e) {
281 matchedListValue = listValue;
282 logger.warn("no matched red list code nor UUID found. \n" + e);
283
284 }
285 try {
286 stateTermUuid = BfnXmlTransformer.getRedlistStateTermUUID(matchedListValue, redListCat.getTitleCache());
287 } catch (UnknownCdmTypeException e) {
288 // stateTermUuid = UUID.randomUUID();
289 //TODO: needs to be fixed for "eindeutiger Code"
290 logger.warn("could not finde state term uuid for " + matchedListValue + " and redlist category"+ redListCat.getTitleCache()+"\n"+e);
291 }
292 String vocName = redListCat.toString()+" States";
293 termVocabulary = (OrderedTermVocabulary) getVocabulary(TermType.State, vocabularyStateUuid, vocName, vocName, vocName, null, true, null);
294 State stateTerm = getStateTerm(state, stateTermUuid, matchedListValue, matchedListValue, matchedListValue, termVocabulary);
295 }
296 if(termVocabulary != null){
297 redListCat.addSupportedCategoricalEnumeration(termVocabulary);
298 getTermService().saveOrUpdate(redListCat);
299 }
300
301 }
302
303
304
305
306
307
308
309
310
311 /* (non-Javadoc)
312 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IImportConfigurator)
313 */
314 protected boolean isIgnore(BfnXmlImportState state){
315 return ! state.getConfig().isDoTaxonNames();
316 }
317
318
319
320 /** Hibernate classification vocabulary initialisation strategy */
321 private static final List<String> VOC_CLASSIFICATION_INIT_STRATEGY = Arrays.asList(new String[] {
322 "classification.$",
323 "classification.rootNodes",
324 "childNodes",
325 "childNodes.taxon",
326 "childNodes.taxon.name",
327 "taxonNodes",
328 "taxonNodes.taxon",
329 "synonymRelations",
330 "taxon.*",
331 "taxon.sec",
332 "taxon.name.*",
333 "taxon.synonymRelations",
334 "termVocabulary.*",
335 "terms"
336
337 });
338
339
340 }