ITaxonNodeService, TaxonNodeServiceImpl : added methods using uuids
[cdmlib.git] / cdmlib-persistence / src / main / java / eu / etaxonomy / cdm / persistence / hibernate / CdmPostDataChangeObservableListener.java
1 // $Id$
2 /**
3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10
11 package eu.etaxonomy.cdm.persistence.hibernate;
12
13 import java.util.HashSet;
14 import java.util.Set;
15
16 import org.apache.log4j.Logger;
17 import org.hibernate.event.spi.PostDeleteEvent;
18 import org.hibernate.event.spi.PostDeleteEventListener;
19 import org.hibernate.event.spi.PostInsertEvent;
20 import org.hibernate.event.spi.PostInsertEventListener;
21 import org.hibernate.event.spi.PostLoadEvent;
22 import org.hibernate.event.spi.PostLoadEventListener;
23 import org.hibernate.event.spi.PostUpdateEvent;
24 import org.hibernate.event.spi.PostUpdateEventListener;
25
26 import eu.etaxonomy.cdm.model.common.CdmBase;
27
28 /**
29 * ICdmPostDataChangeObserver implementors may register for this listener and their update() will
30 * be called after any CRUD (Create, Retrieve, Update, Delete).
31 *
32 * Only events whose entities are of type CdmBase will be propagated
33 *
34 * TODO Manage this class via Spring
35 *
36 * @author n.hoffmann
37 * @created 24.03.2009
38 * @version 1.0
39 */
40 public class CdmPostDataChangeObservableListener implements
41 PostDeleteEventListener
42 , PostInsertEventListener
43 , PostLoadEventListener
44 , PostUpdateEventListener
45 {
46 private static final long serialVersionUID = -8764348096490526927L;
47 @SuppressWarnings("unused")
48 private static final Logger logger = Logger.getLogger(CdmPostDataChangeObservableListener.class);
49
50 /**
51 * if this is set to true, observers have to be notified manually by calling
52 * {@link #delayedNotify()}. All events until then will be stored in {@link #changeEvents}
53 */
54 private boolean delayed;
55
56 /**
57 * Define what events will be propagated
58 */
59 private boolean propagateLoads = false,
60 propagateInserts = true,
61 propagateUpdates = true,
62 propagateDeletes = true;
63
64 /**
65 * DataChangeEvents get stored in this list for delayed propagation
66 */
67 private CdmDataChangeMap changeEvents;
68
69 /**
70 * Observing objects
71 */
72 private final Set<ICdmPostDataChangeObserver> observers = new HashSet<ICdmPostDataChangeObserver>();
73
74
75 /**
76 * Singleton instance
77 */
78 private static CdmPostDataChangeObservableListener instance;
79
80 /**
81 * @return the singleton CdmPostDataChangeObservableListener
82 */
83 public static CdmPostDataChangeObservableListener getDefault(){
84 if(instance == null){
85 instance = new CdmPostDataChangeObservableListener();
86 // TODO set these properties via Spring
87 // get the delayed version by default
88 instance.setDelayed(true);
89 // omit load events from propagation
90 instance.setPropagateLoads(false);
91 }
92 return instance;
93 }
94
95 /**
96 * Register for updates
97 *
98 * @param observer
99 */
100 public void register(ICdmPostDataChangeObserver observer){
101 getDefault().observers.add(observer);
102 }
103
104 /**
105 * Remove observer from notify queue
106 * @param observer
107 */
108 public void unregister(ICdmPostDataChangeObserver observer){
109 getDefault().observers.remove(observer);
110 }
111
112 public void delayedNotify(){
113 if(delayed && changeEvents.size() > 0){
114 Set<ICdmPostDataChangeObserver> modificationSaveObservers
115 = new HashSet<ICdmPostDataChangeObserver>(observers);
116 for( ICdmPostDataChangeObserver observer : modificationSaveObservers){
117 observer.update(changeEvents);
118 }
119 changeEvents.clear();
120 }
121 }
122
123 /**
124 * Propagates the event to all registered objects.
125 *
126 * @param event
127 */
128 public void notifyObservers(CdmDataChangeEvent event){
129 for( ICdmPostDataChangeObserver observer : observers){
130 if(delayed){
131 // store event for delayed propagation
132 changeEvents.add(event.getEventType(), event);
133 }else{
134 // propagate event directly
135 CdmDataChangeMap tmpMap = new CdmDataChangeMap();
136 tmpMap.add(event.getEventType(), event);
137 observer.update(tmpMap);
138 }
139 }
140 }
141
142 public void fireNotification(CdmDataChangeEvent event) {
143 for( ICdmPostDataChangeObserver observer : observers){
144 // propagate event directly
145 CdmDataChangeMap tmpMap = new CdmDataChangeMap();
146 tmpMap.add(event.getEventType(), event);
147 observer.update(tmpMap);
148
149 }
150 }
151
152 @Override
153 public void onPostInsert(PostInsertEvent event) {
154 if(propagateInserts && event.getEntity() instanceof CdmBase){
155 getDefault().notifyObservers(CdmDataChangeEvent.NewInstance(event));
156 }
157 }
158
159 @Override
160 public void onPostLoad(PostLoadEvent event) {
161 if(propagateLoads && event.getEntity() instanceof CdmBase){
162 getDefault().notifyObservers(CdmDataChangeEvent.NewInstance(event));
163 }
164 }
165
166 @Override
167 public void onPostUpdate(PostUpdateEvent event) {
168 if(propagateUpdates && event.getEntity() instanceof CdmBase){
169 getDefault().notifyObservers(CdmDataChangeEvent.NewInstance(event));
170 }
171 }
172
173 @Override
174 public void onPostDelete(PostDeleteEvent event) {
175 if(propagateDeletes && event.getEntity() instanceof CdmBase){
176 getDefault().notifyObservers(CdmDataChangeEvent.NewInstance(event));
177 }
178 }
179
180 /**
181 * @return the delayed
182 */
183 public boolean isDelayed() {
184 return delayed;
185 }
186
187 /**
188 * @param delayed the delayed to set
189 */
190 public void setDelayed(boolean delayed) {
191 if(delayed && changeEvents == null){
192 changeEvents = new CdmDataChangeMap();
193 }
194 this.delayed = delayed;
195 }
196
197 /**
198 * @return the propagateLoads
199 */
200 public boolean isPropagateLoads() {
201 return propagateLoads;
202 }
203
204 /**
205 * @param propagateLoads the propagateLoads to set
206 */
207 public void setPropagateLoads(boolean propagateLoads) {
208 this.propagateLoads = propagateLoads;
209 }
210
211 /**
212 * @return the propagateInserts
213 */
214 public boolean isPropagateInserts() {
215 return propagateInserts;
216 }
217
218 /**
219 * @param propagateInserts the propagateInserts to set
220 */
221 public void setPropagateInserts(boolean propagateInserts) {
222 this.propagateInserts = propagateInserts;
223 }
224
225 /**
226 * @return the propagateUpdates
227 */
228 public boolean isPropagateUpdates() {
229 return propagateUpdates;
230 }
231
232 /**
233 * @param propagateUpdates the propagateUpdates to set
234 */
235 public void setPropagateUpdates(boolean propagateUpdates) {
236 this.propagateUpdates = propagateUpdates;
237 }
238
239 /**
240 * @return the propagateDeletes
241 */
242 public boolean isPropagateDeletes() {
243 return propagateDeletes;
244 }
245
246 /**
247 * @param propagateDeletes the propagateDeletes to set
248 */
249 public void setPropagateDeletes(boolean propagateDeletes) {
250 this.propagateDeletes = propagateDeletes;
251 }
252
253 }