Project

General

Profile

Download (6.05 KB) Statistics
| Branch: | Tag: | Revision:
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 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
	private 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
	@Override
143
	public void onPostInsert(PostInsertEvent event) {
144
		if(propagateInserts && event.getEntity() instanceof CdmBase){
145
			getDefault().notifyObservers(CdmDataChangeEvent.NewInstance(event));
146
		}
147
	}
148
	
149
	@Override
150
	public void onPostLoad(PostLoadEvent event) {
151
		if(propagateLoads && event.getEntity() instanceof CdmBase){
152
			getDefault().notifyObservers(CdmDataChangeEvent.NewInstance(event));
153
		}
154
	}
155

    
156
	@Override
157
	public void onPostUpdate(PostUpdateEvent event) {
158
		if(propagateUpdates && event.getEntity() instanceof CdmBase){
159
			getDefault().notifyObservers(CdmDataChangeEvent.NewInstance(event));
160
		}
161
	}
162

    
163
	@Override
164
	public void onPostDelete(PostDeleteEvent event) {
165
		if(propagateDeletes && event.getEntity() instanceof CdmBase){
166
			getDefault().notifyObservers(CdmDataChangeEvent.NewInstance(event));
167
		}
168
	}
169

    
170
	/**
171
	 * @return the delayed
172
	 */
173
	public boolean isDelayed() {
174
		return delayed;
175
	}
176

    
177
	/**
178
	 * @param delayed the delayed to set
179
	 */
180
	public void setDelayed(boolean delayed) {
181
		if(delayed && changeEvents == null){
182
			changeEvents = new CdmDataChangeMap();
183
		}
184
		this.delayed = delayed;
185
	}
186

    
187
	/**
188
	 * @return the propagateLoads
189
	 */
190
	public boolean isPropagateLoads() {
191
		return propagateLoads;
192
	}
193

    
194
	/**
195
	 * @param propagateLoads the propagateLoads to set
196
	 */
197
	public void setPropagateLoads(boolean propagateLoads) {
198
		this.propagateLoads = propagateLoads;
199
	}
200

    
201
	/**
202
	 * @return the propagateInserts
203
	 */
204
	public boolean isPropagateInserts() {
205
		return propagateInserts;
206
	}
207

    
208
	/**
209
	 * @param propagateInserts the propagateInserts to set
210
	 */
211
	public void setPropagateInserts(boolean propagateInserts) {
212
		this.propagateInserts = propagateInserts;
213
	}
214

    
215
	/**
216
	 * @return the propagateUpdates
217
	 */
218
	public boolean isPropagateUpdates() {
219
		return propagateUpdates;
220
	}
221

    
222
	/**
223
	 * @param propagateUpdates the propagateUpdates to set
224
	 */
225
	public void setPropagateUpdates(boolean propagateUpdates) {
226
		this.propagateUpdates = propagateUpdates;
227
	}
228

    
229
	/**
230
	 * @return the propagateDeletes
231
	 */
232
	public boolean isPropagateDeletes() {
233
		return propagateDeletes;
234
	}
235

    
236
	/**
237
	 * @param propagateDeletes the propagateDeletes to set
238
	 */
239
	public void setPropagateDeletes(boolean propagateDeletes) {
240
		this.propagateDeletes = propagateDeletes;
241
	}
242
	
243
}
(8-8/17)