adapt app-import to v5.45
[cdmlib-apps.git] / app-import / src / main / java / eu / etaxonomy / cdm / io / redlist / gefaesspflanzen / RedListGefaesspflanzenImportClassification.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.gefaesspflanzen;
10
11 import java.sql.ResultSet;
12 import java.sql.SQLException;
13 import java.util.Arrays;
14 import java.util.HashMap;
15 import java.util.HashSet;
16 import java.util.Map;
17 import java.util.Map.Entry;
18 import java.util.Set;
19 import java.util.UUID;
20
21 import org.apache.logging.log4j.LogManager;
22 import org.apache.logging.log4j.Logger;
23 import org.springframework.stereotype.Component;
24
25 import eu.etaxonomy.cdm.common.CdmUtils;
26 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
27 import eu.etaxonomy.cdm.io.common.DbImportBase;
28 import eu.etaxonomy.cdm.io.common.IPartitionedIO;
29 import eu.etaxonomy.cdm.io.common.ResultSetPartitioner;
30 import eu.etaxonomy.cdm.model.common.CdmBase;
31 import eu.etaxonomy.cdm.model.common.Language;
32 import eu.etaxonomy.cdm.model.common.VerbatimTimePeriod;
33 import eu.etaxonomy.cdm.model.reference.Reference;
34 import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
35 import eu.etaxonomy.cdm.model.taxon.Classification;
36 import eu.etaxonomy.cdm.model.taxon.Synonym;
37 import eu.etaxonomy.cdm.model.taxon.SynonymType;
38 import eu.etaxonomy.cdm.model.taxon.Taxon;
39 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
40 import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
41
42 /**
43 * @author pplitzner
44 * @since Mar 1, 2016
45 */
46 @Component
47 @SuppressWarnings("serial")
48 public class RedListGefaesspflanzenImportClassification extends DbImportBase<RedListGefaesspflanzenImportState, RedListGefaesspflanzenImportConfigurator> {
49
50 private static final Logger logger = LogManager.getLogger();
51
52 private static final String tableName = "Rote Liste Gefäßpflanzen";
53
54 private static final String pluralString = "classifications";
55
56 public RedListGefaesspflanzenImportClassification() {
57 super(tableName, pluralString);
58 }
59
60 @Override
61 protected String getIdQuery(RedListGefaesspflanzenImportState state) {
62 return "SELECT SEQNUM "
63 + "FROM V_TAXATLAS_D20_EXPORT t "
64 + " ORDER BY SEQNUM";
65 }
66
67 @Override
68 protected String getRecordQuery(RedListGefaesspflanzenImportConfigurator config) {
69 String result = "select distinct e.*, f.FAMILIE "
70 + "from V_TAXATLAS_D20_EXPORT e, GATTUNG_FAMILIE f "
71 + "where e.EPI1 = f.GATTUNG and e.SEQNUM IN (@IDSET)";
72 result = result.replace("@IDSET", IPartitionedIO.ID_LIST_TOKEN);
73 return result;
74 }
75
76 @Override
77 protected void doInvoke(RedListGefaesspflanzenImportState state) {
78 Classification gesamtListe = makeClassification("Gesamtliste", state.getConfig().getClassificationUuid(), "Gesamtliste", null, RedListUtil.gesamtListeReferenceUuid, state);
79 Classification checkliste = makeClassification("Checkliste", RedListUtil.checkListClassificationUuid, "Checkliste", null, RedListUtil.checkListReferenceUuid, state);
80 makeClassification("Ehrendorfer", RedListUtil.uuidClassificationE, "Ehrendorfer", null, RedListUtil.uuidClassificationReferenceE, state);
81 makeClassification("Wisskirchen (Standardliste)", RedListUtil.uuidClassificationW, "Wisskirchen (Standardliste)", 1998, RedListUtil.uuidClassificationReferenceW, state);
82 makeClassification("Korneck (Rote Liste)", RedListUtil.uuidClassificationK, "Korneck (Rote Liste)", 1996, RedListUtil.uuidClassificationReferenceK, state);
83 makeClassification("Atlas (Westdeutschland)", RedListUtil.uuidClassificationAW, "Atlas (Westdeutschland)", 1988, RedListUtil.uuidClassificationReferenceAW, state);
84 makeClassification("Atlas (Ostdeutschland)", RedListUtil.uuidClassificationAO, "Atlas (Ostdeutschland)", 1996, RedListUtil.uuidClassificationReferenceAO, state);
85 makeClassification("Rothmaler", RedListUtil.uuidClassificationR, "Rothmaler", 2011, RedListUtil.uuidClassificationReferenceR, state);
86 makeClassification("Oberdorfer", RedListUtil.uuidClassificationO, "Oberdorfer", 2001, RedListUtil.uuidClassificationReferenceO, state);
87 makeClassification("Schmeil-Fitschen", RedListUtil.uuidClassificationS, "Schmeil-Fitschen", 2011, RedListUtil.uuidClassificationReferenceS, state);
88 importFamilies(gesamtListe, checkliste, state);
89 super.doInvoke(state);
90 }
91
92 private void importFamilies(Classification gesamtListe, Classification checkliste, RedListGefaesspflanzenImportState state) {
93 for(UUID uuid:state.getFamilyMap().values()){
94 Taxon family = HibernateProxyHelper.deproxy(getTaxonService().load(uuid, true, Arrays.asList(new String[]{"*"})), Taxon.class);
95
96 gesamtListe.addParentChild(null, family, null, null);
97 checkliste.addParentChild(null, family, null, null);
98 family.setSec(gesamtListe.getReference());
99 family.setTitleCache(null);
100
101 getClassificationService().saveOrUpdate(gesamtListe);
102 getClassificationService().saveOrUpdate(checkliste);
103 }
104 }
105
106 @Override
107 public boolean doPartition(ResultSetPartitioner partitioner, RedListGefaesspflanzenImportState state) {
108 ResultSet rs = partitioner.getResultSet();
109 Classification gesamtListeClassification = getClassificationService().load(state.getConfig().getClassificationUuid());
110 Classification checklistClassification = getClassificationService().load(RedListUtil.checkListClassificationUuid);
111 Classification classificationE = getClassificationService().load(RedListUtil.uuidClassificationE);
112 Classification classificationW = getClassificationService().load(RedListUtil.uuidClassificationW);
113 Classification classificationK = getClassificationService().load(RedListUtil.uuidClassificationK);
114 Classification classificationAW = getClassificationService().load(RedListUtil.uuidClassificationAW);
115 Classification classificationAO = getClassificationService().load(RedListUtil.uuidClassificationAO);
116 Classification classificationR = getClassificationService().load(RedListUtil.uuidClassificationR);
117 Classification classificationO = getClassificationService().load(RedListUtil.uuidClassificationO);
118 Classification classificationS = getClassificationService().load(RedListUtil.uuidClassificationS);
119 try {
120 while (rs.next()){
121 makeSingleTaxonNode(state, rs, gesamtListeClassification, checklistClassification,
122 classificationE, classificationW, classificationK, classificationAW
123 , classificationAO, classificationR, classificationO, classificationS);
124
125 }
126 } catch (SQLException e) {
127 e.printStackTrace();
128 }
129
130 logger.info("Update classification (1000 nodes)");
131 getClassificationService().saveOrUpdate(gesamtListeClassification);
132 getClassificationService().saveOrUpdate(checklistClassification);
133 getClassificationService().saveOrUpdate(classificationE);
134 getClassificationService().saveOrUpdate(classificationW);
135 getClassificationService().saveOrUpdate(classificationK);
136 getClassificationService().saveOrUpdate(classificationAW);
137 getClassificationService().saveOrUpdate(classificationAO);
138 getClassificationService().saveOrUpdate(classificationR);
139 getClassificationService().saveOrUpdate(classificationO);
140 getClassificationService().saveOrUpdate(classificationS);
141 return true;
142 }
143
144 private void makeSingleTaxonNode(RedListGefaesspflanzenImportState state, ResultSet rs,
145 Classification gesamtListeClassification, Classification checklistClassification,
146 Classification classificationE, Classification classificationW, Classification classificationK,
147 Classification classificationAW, Classification classificationAO, Classification classificationR,
148 Classification classificationO, Classification classificationS)
149 throws SQLException {
150 long id = rs.getLong(RedListUtil.NAMNR);
151 String parentId = String.valueOf(rs.getLong(RedListUtil.LOWER));
152 String gueltString = rs.getString(RedListUtil.GUELT);
153 String taxZusatzString = rs.getString(RedListUtil.TAX_ZUSATZ);
154 String familieString = rs.getString(RedListUtil.FAMILIE);
155 String clTaxonString = rs.getString(RedListUtil.CL_TAXON);
156
157 String relationE = rs.getString(RedListUtil.E);
158 String relationW = rs.getString(RedListUtil.W);
159 String relationK = rs.getString(RedListUtil.K);
160 String relationAW = rs.getString(RedListUtil.AW);
161 String relationAO = rs.getString(RedListUtil.AO);
162 String relationR = rs.getString(RedListUtil.R);
163 String relationO = rs.getString(RedListUtil.O);
164 String relationS = rs.getString(RedListUtil.S);
165
166 //Gesamtliste
167 TaxonBase<?> taxonBase = state.getRelatedObject(RedListUtil.TAXON_GESAMTLISTE_NAMESPACE, String.valueOf(id), TaxonBase.class);
168 taxonBase.setSec(gesamtListeClassification.getReference());
169 Taxon parent = state.getRelatedObject(RedListUtil.TAXON_GESAMTLISTE_NAMESPACE, parentId, Taxon.class);
170 if(parent!=null && !parent.isInstanceOf(Taxon.class)){
171 RedListUtil.logMessage(id, parent+" is no taxon but is a parent of "+taxonBase+" (Gesamtliste)", logger);
172 }
173 //add to family if no parent found
174 if(parent==null){
175 if(!taxonBase.isInstanceOf(Taxon.class)){
176 RedListUtil.logMessage(id, taxonBase+" has no parent but is not a taxon.", logger);
177 }
178 else{
179 Taxon family = (Taxon) state.getRelatedObject(RedListUtil.FAMILY_NAMESPACE_GESAMTLISTE, familieString);
180 gesamtListeClassification.addParentChild(family, HibernateProxyHelper.deproxy(taxonBase, Taxon.class), null, null);
181 //Buttler/Checklist taxon
182 if(CdmUtils.isNotBlank(clTaxonString) && clTaxonString.equals(RedListUtil.CL_TAXON_B)){
183 checklistClassification.addParentChild(family, HibernateProxyHelper.deproxy(taxonBase, Taxon.class), null, null);
184 taxonBase.setSec(checklistClassification.getReference());
185 }
186 if(family.getTaxonNodes().isEmpty()){
187 gesamtListeClassification.addChildTaxon(family, null, null);
188 //do not add empty families to checklist classification
189 if(!getClassificationService().listChildNodesOfTaxon(family.getUuid(), RedListUtil.checkListClassificationUuid,
190 true, null, null, null).isEmpty()){
191 checklistClassification.addChildTaxon(family, null, null);
192 }
193 }
194 }
195 }
196 //add to higher taxon
197 else{
198 createParentChildNodes(gesamtListeClassification, id, gueltString, taxZusatzString, taxonBase, parent);
199 //Buttler/Checklist taxon
200 if(CdmUtils.isNotBlank(clTaxonString) && clTaxonString.equals(RedListUtil.CL_TAXON_B)){
201 if(!checklistClassification.isTaxonInTree(parent)){
202 RedListUtil.logInfoMessage(id, parent+" is parent taxon but is not in checklist. Skipping child "+taxonBase, logger);
203 }
204 else{
205 if(taxonBase.isInstanceOf(Taxon.class)){
206 createParentChildNodes(checklistClassification, id, gueltString, taxZusatzString, taxonBase, parent);
207 }
208 else if(taxonBase.isInstanceOf(Synonym.class)){
209 //if it is a synonym it is already added to the accepted taxon
210 //so we just change the sec reference
211 taxonBase.setSec(checklistClassification.getReference());
212 taxonBase.setTitleCache(null);
213 }
214 }
215
216 }
217 }
218 taxonBase.setTitleCache(null, false);//refresh title cache
219
220 //add taxa for concept relationships to E, W, K, AW, AO, R, O, S
221 addTaxonToClassification(classificationE, RedListUtil.CLASSIFICATION_NAMESPACE_E, relationE, taxonBase, id, state);
222 addTaxonToClassification(classificationW, RedListUtil.CLASSIFICATION_NAMESPACE_W, relationW, taxonBase, id, state);
223 addTaxonToClassification(classificationK, RedListUtil.CLASSIFICATION_NAMESPACE_K, relationK, taxonBase, id, state);
224 addTaxonToClassification(classificationAW, RedListUtil.CLASSIFICATION_NAMESPACE_AW, relationAW, taxonBase, id, state);
225 addTaxonToClassification(classificationAO, RedListUtil.CLASSIFICATION_NAMESPACE_AO, relationAO, taxonBase, id, state);
226 addTaxonToClassification(classificationR, RedListUtil.CLASSIFICATION_NAMESPACE_R, relationR, taxonBase, id, state);
227 addTaxonToClassification(classificationO, RedListUtil.CLASSIFICATION_NAMESPACE_O, relationO, taxonBase, id, state);
228 addTaxonToClassification(classificationS, RedListUtil.CLASSIFICATION_NAMESPACE_S, relationS, taxonBase, id, state);
229 }
230
231 private void addTaxonToClassification(Classification classification, String classificationNamespace, String relationString, final TaxonBase<?> gesamtListeTaxon, long id, RedListGefaesspflanzenImportState state){
232 Taxon taxon = HibernateProxyHelper.deproxy(state.getRelatedObject(classificationNamespace, String.valueOf(id), TaxonBase.class), Taxon.class);
233 //add concept relation to gesamtliste/checkliste
234 if(taxon!=null && isNotBlank(relationString) && !relationString.equals(".")){
235 //if the related concept in gesamtliste/checkliste is a synonym then we
236 //create a relation to the accepted taxon
237 Taxon acceptedGesamtListeTaxon = getAcceptedTaxon(gesamtListeTaxon);
238 String relationSubstring = relationString.substring(relationString.length()-1, relationString.length());
239 TaxonRelationshipType taxonRelationshipTypeByKey = new RedListGefaesspflanzenTransformer().getTaxonRelationshipTypeByKey(relationSubstring);
240 if(taxonRelationshipTypeByKey==null){
241 RedListUtil.logMessage(id, "Could not interpret relationship "+relationString+" for taxon "+gesamtListeTaxon.generateTitle(), logger);
242 }
243 //there is no type "included in" so we have to reverse the direction
244 if(relationSubstring.equals("<")){
245 if(acceptedGesamtListeTaxon!=null){
246 acceptedGesamtListeTaxon.addTaxonRelation(taxon, taxonRelationshipTypeByKey, null, null);
247 }
248 }
249 else{
250 if(acceptedGesamtListeTaxon!=null){
251 taxon.addTaxonRelation(acceptedGesamtListeTaxon, taxonRelationshipTypeByKey, null, null);
252 }
253 }
254
255 taxon.setSec(classification.getReference());
256 classification.addChildTaxon(taxon, null, null);
257 taxon.setTitleCache(null);//Reset title cache to see sec ref in title
258 }
259 }
260
261 private void createParentChildNodes(Classification classification, long id, String gueltString,
262 String taxZusatzString, TaxonBase<?> taxonBase, Taxon parent) {
263 if(taxonBase==null){
264 RedListUtil.logMessage(id, "child taxon/synonym of "+parent+" is null. ("+classification.generateTitle()+")" , logger);
265 return;
266 }
267 //taxon
268 if(taxonBase.isInstanceOf(Taxon.class)){
269 //misapplied name
270 String appendedPhrase = taxonBase.getAppendedPhrase();
271 if(appendedPhrase!=null && appendedPhrase.equals(RedListUtil.AUCT)){
272 if(parent==null){
273 RedListUtil.logMessage(id, "parent taxon of misapplied name "+taxonBase+" is null. ("+classification.getTitleCache()+")" , logger);
274 return;
275 }
276 parent.addMisappliedName((Taxon) taxonBase, null, null);
277 //return because misapplied names do not have sec references
278 return;
279 }
280 else{
281 classification.addParentChild(parent, (Taxon)taxonBase, null, null);
282 }
283
284 if(isNotBlank(taxZusatzString)){
285 if(taxZusatzString.trim().equals("p. p.")){
286 RedListUtil.logMessage(id, "pro parte for accepted taxon "+taxonBase, logger);
287 }
288 }
289 }
290 //synonym
291 else if(taxonBase.isInstanceOf(Synonym.class)){
292 if(parent==null){
293 RedListUtil.logMessage(id, "parent taxon of synonym "+taxonBase+" is null. ("+classification.getTitleCache()+")" , logger);
294 return;
295 }
296 //basionym
297 if(gueltString.equals(RedListUtil.GUELT_BASIONYM)){
298 parent.addHomotypicSynonym((Synonym) taxonBase);
299 parent.getName().addBasionym(taxonBase.getName());
300 }
301 //regular synonym
302 else{
303 Synonym synonym = (Synonym) taxonBase;
304 parent.addSynonym(synonym, SynonymType.HETEROTYPIC_SYNONYM_OF);
305
306 //TAX_ZUSATZ
307 if(isNotBlank(taxZusatzString)){
308 if(taxZusatzString.trim().equals("p. p.")){
309 logger.warn(id + ": p. p. not implemented anymore");
310 }
311 else if(taxZusatzString.trim().equals("s. l. p. p.")){
312 logger.warn(id + ": p. p. not implemented anymore");
313 taxonBase.setAppendedPhrase("s. l.");
314 }
315 else if(taxZusatzString.trim().equals("s. str. p. p.")){
316 logger.warn(id + ": p. p. not implemented anymore");
317 taxonBase.setAppendedPhrase("s. str.");
318 }
319 else if(taxZusatzString.trim().equals("s. l.")
320 || taxZusatzString.trim().equals("s. str.")){
321 taxonBase.setAppendedPhrase(taxZusatzString);
322 }
323 else{
324 RedListUtil.logMessage(id, "unknown value "+taxZusatzString+" for column "+RedListUtil.TAX_ZUSATZ, logger);
325 }
326 }
327 }
328 }
329 //set sec reference
330 taxonBase.setSec(classification.getReference());
331 }
332
333 @Override
334 public Map<Object, Map<String, ? extends CdmBase>> getRelatedObjectsForPartition(ResultSet rs,
335 RedListGefaesspflanzenImportState state) {
336 Map<Object, Map<String, ? extends CdmBase>> result = new HashMap<>();
337
338 Set<String> idSet = new HashSet<>();
339 try {
340 while (rs.next()){
341 idSet.add(String.valueOf(rs.getLong(RedListUtil.NAMNR)));
342 idSet.add(String.valueOf(rs.getLong(RedListUtil.LOWER)));
343 }
344 } catch (SQLException e) {
345 e.printStackTrace();
346 }
347 //add taxa and their parent taxa
348 result.put(RedListUtil.TAXON_GESAMTLISTE_NAMESPACE, getCommonService().getSourcedObjectsByIdInSourceC(TaxonBase.class, idSet, RedListUtil.TAXON_GESAMTLISTE_NAMESPACE));
349 result.put(RedListUtil.CLASSIFICATION_NAMESPACE_E, getCommonService().getSourcedObjectsByIdInSourceC(TaxonBase.class, idSet, RedListUtil.CLASSIFICATION_NAMESPACE_E));
350 result.put(RedListUtil.CLASSIFICATION_NAMESPACE_W, getCommonService().getSourcedObjectsByIdInSourceC(TaxonBase.class, idSet, RedListUtil.CLASSIFICATION_NAMESPACE_W));
351 result.put(RedListUtil.CLASSIFICATION_NAMESPACE_K, getCommonService().getSourcedObjectsByIdInSourceC(TaxonBase.class, idSet, RedListUtil.CLASSIFICATION_NAMESPACE_K));
352 result.put(RedListUtil.CLASSIFICATION_NAMESPACE_AW, getCommonService().getSourcedObjectsByIdInSourceC(TaxonBase.class, idSet, RedListUtil.CLASSIFICATION_NAMESPACE_AW));
353 result.put(RedListUtil.CLASSIFICATION_NAMESPACE_AO, getCommonService().getSourcedObjectsByIdInSourceC(TaxonBase.class, idSet, RedListUtil.CLASSIFICATION_NAMESPACE_AO));
354 result.put(RedListUtil.CLASSIFICATION_NAMESPACE_R, getCommonService().getSourcedObjectsByIdInSourceC(TaxonBase.class, idSet, RedListUtil.CLASSIFICATION_NAMESPACE_R));
355 result.put(RedListUtil.CLASSIFICATION_NAMESPACE_O, getCommonService().getSourcedObjectsByIdInSourceC(TaxonBase.class, idSet, RedListUtil.CLASSIFICATION_NAMESPACE_O));
356 result.put(RedListUtil.CLASSIFICATION_NAMESPACE_S, getCommonService().getSourcedObjectsByIdInSourceC(TaxonBase.class, idSet, RedListUtil.CLASSIFICATION_NAMESPACE_S));
357
358 //add families
359 //gesamtliste
360 Map<String, Taxon> familyMapGL = new HashMap<String, Taxon>();
361 for (Entry<String, UUID> entry: state.getFamilyMap().entrySet()) {
362 familyMapGL.put(entry.getKey(), HibernateProxyHelper.deproxy(getTaxonService().load(entry.getValue()), Taxon.class));
363 }
364 result.put(RedListUtil.FAMILY_NAMESPACE_GESAMTLISTE, familyMapGL);
365 return result;
366 }
367
368 private Classification makeClassification(String classificationName, UUID classificationUuid, String referenceName, Integer yearPublished, UUID referenceUuid, RedListGefaesspflanzenImportState state) {
369 Classification classification = Classification.NewInstance(classificationName, Language.DEFAULT());
370 classification.setUuid(classificationUuid);
371 Reference reference = ReferenceFactory.newGeneric();
372 reference.setTitle(referenceName);
373 reference.setUuid(referenceUuid);
374 classification.setReference(reference);
375 if(yearPublished!=null){
376 reference.setDatePublished(VerbatimTimePeriod.NewVerbatimInstance(yearPublished));
377 }
378 return getClassificationService().save(classification);
379 }
380
381 @Override
382 protected boolean doCheck(RedListGefaesspflanzenImportState state) {
383 return false;
384 }
385
386 @Override
387 protected boolean isIgnore(RedListGefaesspflanzenImportState state) {
388 return false;
389 }
390
391 }