ref #7648 initial implementation of TaxonGraphService with tests and TaxonGraphObserver
[cdmlib.git] / cdmlib-services / src / main / java / eu / etaxonomy / cdm / api / service / taxonGraph / TaxonGraphObserver.java
1 /**
2 * Copyright (C) 2018 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.api.service.taxonGraph;
10
11 import org.apache.commons.lang.ArrayUtils;
12 import org.apache.log4j.Logger;
13 import org.springframework.beans.factory.annotation.Autowired;
14 import org.springframework.stereotype.Component;
15
16 import eu.etaxonomy.cdm.model.name.TaxonName;
17 import eu.etaxonomy.cdm.model.reference.Reference;
18 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeEvent;
19 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeEvent.EventType;
20 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
21 import eu.etaxonomy.cdm.persistence.hibernate.ICdmPostDataChangeObserver;
22
23 /**
24 * @author a.kohlbecker
25 * @since Sep 27, 2018
26 *
27 */
28 @Component
29 public class TaxonGraphObserver implements ICdmPostDataChangeObserver {
30
31 @Autowired
32 private ITaxonGraphService taxonGraphService;
33
34 private String[] NAMEPARTS_OR_RANK_PROPS = new String[]{"genusOrUninomial", "specificEpithet", "rank"};
35 private String[] NOMREF_PROP = new String[]{"nomenclaturalReference"};
36
37 /**
38 * {@inheritDoc}
39 */
40 @Override
41 public void update(CdmDataChangeMap changeEvents) {
42
43 try {
44 for(CdmDataChangeEvent event : changeEvents.getEvents(EventType.UPDATE)){
45 if(event.getEntity() instanceof TaxonName){
46 if(checkStateChange(event, NAMEPARTS_OR_RANK_PROPS) > -1){
47 taxonGraphService.onNameOrRankChange((TaxonName) event.getEntity());
48 }
49 int changedNomRefIndex = checkStateChange(event, NOMREF_PROP);
50 if(changedNomRefIndex > -1){
51 taxonGraphService.onNomReferenceChange((TaxonName) event.getEntity(), (Reference)event.getOldState()[changedNomRefIndex]);
52 }
53 }
54 }
55 for(CdmDataChangeEvent event : changeEvents.getEvents(EventType.INSERT)){
56 if(event.getEntity() instanceof TaxonName){
57 taxonGraphService.onNewTaxonName((TaxonName) event.getEntity());
58 }
59 }
60 } catch (TaxonGraphException e) {
61 Logger.getLogger(this.getClass()).error(e);
62 }
63
64 }
65
66
67 private int checkStateChange(CdmDataChangeEvent event, String[] propertyNamesToCheck){
68
69 String[] propertyNames = event.getPersister().getPropertyNames();
70 Object[] oldState = event.getOldState();
71 Object[] state = event.getState();
72
73 int propsCheckedCnt = 0;
74 for(int i = 0; i < propertyNames.length; i++){
75 if(ArrayUtils.contains(propertyNamesToCheck, propertyNames[i])){
76 propsCheckedCnt++;
77 if(!oldState[i].equals(state[i])){
78 return i;
79 }
80 if(propsCheckedCnt == propertyNamesToCheck.length){
81 return -1;
82 }
83 }
84 }
85 // this execption should be raised during the unit tests already and thus will never occur in production
86 throw new RuntimeException("TaxonName class misses at least one property of: " + ArrayUtils.toString(propertyNamesToCheck));
87 }
88
89 }