Project

General

Profile

Download (6.42 KB) Statistics
| Branch: | Tag: | Revision:
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.persistence.hibernate;
11

    
12
import java.util.HashSet;
13
import java.util.Set;
14

    
15
import org.apache.log4j.Logger;
16
import org.hibernate.event.spi.PostDeleteEvent;
17
import org.hibernate.event.spi.PostDeleteEventListener;
18
import org.hibernate.event.spi.PostInsertEvent;
19
import org.hibernate.event.spi.PostInsertEventListener;
20
import org.hibernate.event.spi.PostLoadEvent;
21
import org.hibernate.event.spi.PostLoadEventListener;
22
import org.hibernate.event.spi.PostUpdateEvent;
23
import org.hibernate.event.spi.PostUpdateEventListener;
24
import org.hibernate.persister.entity.EntityPersister;
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
 * @since 24.03.2009
38
 */
39
public class CdmPostDataChangeObservableListener implements
40
		  PostDeleteEventListener
41
		, PostInsertEventListener
42
		, PostLoadEventListener
43
		, PostUpdateEventListener
44
{
45
	private static final long serialVersionUID = -8764348096490526927L;
46
	@SuppressWarnings("unused")
47
	private static final Logger logger = Logger.getLogger(CdmPostDataChangeObservableListener.class);
48

    
49
	/**
50
	 * if this is set to true, observers have to be notified manually by calling
51
	 * {@link #delayedNotify()}. All events until then will be stored in {@link #changeEvents}
52
	 */
53
	private boolean delayed;
54

    
55
	/**
56
	 * Define what events will be propagated
57
	 */
58
	private boolean propagateLoads = false,
59
					propagateInserts = true,
60
					propagateUpdates = true,
61
					propagateDeletes = true;
62

    
63
	/**
64
	 * DataChangeEvents get stored in this list for delayed propagation
65
	 */
66
	private CdmDataChangeMap changeEvents;
67

    
68
	/**
69
	 * Observing objects
70
	 */
71
	private final Set<ICdmPostDataChangeObserver> observers = new HashSet<>();
72

    
73

    
74
	/**
75
	 * Singleton instance
76
	 */
77
	private static CdmPostDataChangeObservableListener instance;
78

    
79
	/**
80
	 * @return the singleton CdmPostDataChangeObservableListener
81
	 */
82
	public static CdmPostDataChangeObservableListener getDefault(){
83
		if(instance == null){
84
			instance = new CdmPostDataChangeObservableListener();
85
			// TODO set these properties via Spring
86
			// get the delayed version by default
87
			instance.setDelayed(true);
88
			// omit load events from propagation
89
			instance.setPropagateLoads(false);
90
		}
91
		return instance;
92
	}
93

    
94
	/**
95
	 * Register for updates
96
	 *
97
	 * @param observer
98
	 */
99
	public void register(ICdmPostDataChangeObserver observer){
100
		getDefault().observers.add(observer);
101
	}
102

    
103
	/**
104
	 * Remove observer from notify queue
105
	 * @param observer
106
	 */
107
	public void unregister(ICdmPostDataChangeObserver observer){
108
		getDefault().observers.remove(observer);
109
	}
110

    
111
	public void delayedNotify(){
112
		if(delayed && changeEvents.size() > 0){
113
			Set<ICdmPostDataChangeObserver> modificationSaveObservers
114
						= new HashSet<>(observers);
115
			for( ICdmPostDataChangeObserver observer : modificationSaveObservers){
116
				observer.update(changeEvents);
117
			}
118
			changeEvents.clear();
119
		}
120
	}
121

    
122
	/**
123
	 * Propagates the event to all registered objects.
124
	 *
125
	 * @param event
126
	 */
127
	public void notifyObservers(CdmDataChangeEvent event){
128
		for( ICdmPostDataChangeObserver observer : observers){
129
			if(delayed){
130
				// store event for delayed propagation
131
				changeEvents.add(event.getEventType(), event);
132
			}else{
133
				// propagate event directly
134
				CdmDataChangeMap tmpMap = new CdmDataChangeMap();
135
				tmpMap.add(event.getEventType(), event);
136
				observer.update(tmpMap);
137
			}
138
		}
139
	}
140

    
141
	public void fireNotification(CdmDataChangeEvent event) {
142
	    for( ICdmPostDataChangeObserver observer : observers){
143
	        // propagate event directly
144
	        CdmDataChangeMap tmpMap = new CdmDataChangeMap();
145
	        tmpMap.add(event.getEventType(), event);
146
	        observer.update(tmpMap);
147

    
148
	    }
149
	}
150

    
151
	@Override
152
	public void onPostInsert(PostInsertEvent event) {
153
		if(propagateInserts && event.getEntity() instanceof CdmBase){
154
			getDefault().notifyObservers(CdmDataChangeEvent.NewInstance(event));
155
		}
156
	}
157

    
158
	@Override
159
	public void onPostLoad(PostLoadEvent event) {
160
		if(propagateLoads && event.getEntity() instanceof CdmBase){
161
			getDefault().notifyObservers(CdmDataChangeEvent.NewInstance(event));
162
		}
163
	}
164

    
165
	@Override
166
	public void onPostUpdate(PostUpdateEvent event) {
167
		if(propagateUpdates && event.getEntity() instanceof CdmBase){
168
			getDefault().notifyObservers(CdmDataChangeEvent.NewInstance(event));
169
		}
170
	}
171

    
172
	@Override
173
	public void onPostDelete(PostDeleteEvent event) {
174
		if(propagateDeletes && event.getEntity() instanceof CdmBase){
175
			getDefault().notifyObservers(CdmDataChangeEvent.NewInstance(event));
176
		}
177
	}
178

    
179
	/**
180
	 * @return the delayed
181
	 */
182
	public boolean isDelayed() {
183
		return delayed;
184
	}
185

    
186
	/**
187
	 * @param delayed the delayed to set
188
	 */
189
	public void setDelayed(boolean delayed) {
190
		if(delayed && changeEvents == null){
191
			changeEvents = new CdmDataChangeMap();
192
		}
193
		this.delayed = delayed;
194
	}
195

    
196
	/**
197
	 * @return the propagateLoads
198
	 */
199
	public boolean isPropagateLoads() {
200
		return propagateLoads;
201
	}
202

    
203
	/**
204
	 * @param propagateLoads the propagateLoads to set
205
	 */
206
	public void setPropagateLoads(boolean propagateLoads) {
207
		this.propagateLoads = propagateLoads;
208
	}
209

    
210
	/**
211
	 * @return the propagateInserts
212
	 */
213
	public boolean isPropagateInserts() {
214
		return propagateInserts;
215
	}
216

    
217
	/**
218
	 * @param propagateInserts the propagateInserts to set
219
	 */
220
	public void setPropagateInserts(boolean propagateInserts) {
221
		this.propagateInserts = propagateInserts;
222
	}
223

    
224
	/**
225
	 * @return the propagateUpdates
226
	 */
227
	public boolean isPropagateUpdates() {
228
		return propagateUpdates;
229
	}
230

    
231
	/**
232
	 * @param propagateUpdates the propagateUpdates to set
233
	 */
234
	public void setPropagateUpdates(boolean propagateUpdates) {
235
		this.propagateUpdates = propagateUpdates;
236
	}
237

    
238
	/**
239
	 * @return the propagateDeletes
240
	 */
241
	public boolean isPropagateDeletes() {
242
		return propagateDeletes;
243
	}
244

    
245
	/**
246
	 * @param propagateDeletes the propagateDeletes to set
247
	 */
248
	public void setPropagateDeletes(boolean propagateDeletes) {
249
		this.propagateDeletes = propagateDeletes;
250
	}
251

    
252
    @Override
253
    public boolean requiresPostCommitHanding(EntityPersister persister) {
254
        return false;
255
    }
256

    
257
}
(8-8/23)