Project

General

Profile

Download (6.31 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.Vector;
14

    
15
import org.apache.log4j.Logger;
16
import org.hibernate.event.PostDeleteEvent;
17
import org.hibernate.event.PostDeleteEventListener;
18
import org.hibernate.event.PostInsertEvent;
19
import org.hibernate.event.PostInsertEventListener;
20
import org.hibernate.event.PostLoadEvent;
21
import org.hibernate.event.PostLoadEventListener;
22
import org.hibernate.event.PostUpdateEvent;
23
import org.hibernate.event.PostUpdateEventListener;
24

    
25
import eu.etaxonomy.cdm.model.common.CdmBase;
26

    
27
/**
28
 * ICdmPostDataChangeObserver implementors may register for this listener and their update() will 
29
 * be called after any CRUD (Create, Retrieve, Update, Delete).
30
 * 
31
 * Only events whose entities are of type CdmBase will be propagated
32
 * 
33
 * TODO Manage this class via Spring
34
 * 
35
 * @author n.hoffmann
36
 * @created 24.03.2009
37
 * @version 1.0
38
 */
39
public class CdmPostDataChangeObservableListener 
40
	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 Vector<ICdmPostDataChangeObserver> observers = new Vector<ICdmPostDataChangeObserver>();
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
			for( ICdmPostDataChangeObserver observer : observers){
114
				observer.update(changeEvents);
115
			}
116
			changeEvents.clear();
117
		}
118
	}
119
	
120
	/**
121
	 * Propagates the event to all registered objects.
122
	 * 
123
	 * @param event
124
	 */
125
	private void notifyObservers(CdmDataChangeEvent event){
126
		for( ICdmPostDataChangeObserver observer : observers){
127
			if(delayed){
128
				// store event for delayed propagation
129
				changeEvents.add(event.getEventType(), event);
130
			}else{
131
				// propagate event directly
132
				CdmDataChangeMap tmpMap = new CdmDataChangeMap();
133
				tmpMap.add(event.getEventType(), event);
134
				observer.update(tmpMap);
135
			}
136
		}
137
	}
138
	
139
	/* (non-Javadoc)
140
	 * @see org.hibernate.event.PostInsertEventListener#onPostInsert(org.hibernate.event.PostInsertEvent)
141
	 */
142
	public void onPostInsert(PostInsertEvent event) {
143
		if(propagateInserts && event.getEntity() instanceof CdmBase){
144
			getDefault().notifyObservers(CdmDataChangeEvent.NewInstance(event));
145
		}
146
	}
147
	
148
	/* (non-Javadoc)
149
	 * @see org.hibernate.event.PostLoadEventListener#onPostLoad(org.hibernate.event.PostLoadEvent)
150
	 */
151
	public void onPostLoad(PostLoadEvent event) {
152
		if(propagateLoads && event.getEntity() instanceof CdmBase){
153
			getDefault().notifyObservers(CdmDataChangeEvent.NewInstance(event));
154
		}
155
	}
156

    
157
	/* (non-Javadoc)
158
	 * @see org.hibernate.event.PostUpdateEventListener#onPostUpdate(org.hibernate.event.PostUpdateEvent)
159
	 */
160
	public void onPostUpdate(PostUpdateEvent event) {
161
		if(propagateUpdates && event.getEntity() instanceof CdmBase){
162
			getDefault().notifyObservers(CdmDataChangeEvent.NewInstance(event));
163
		}
164
	}
165

    
166
	/* (non-Javadoc)
167
	 * @see org.hibernate.event.PostDeleteEventListener#onPostDelete(org.hibernate.event.PostDeleteEvent)
168
	 */
169
	public void onPostDelete(PostDeleteEvent event) {
170
		if(propagateDeletes && event.getEntity() instanceof CdmBase){
171
			getDefault().notifyObservers(CdmDataChangeEvent.NewInstance(event));
172
		}
173
	}
174

    
175
	/**
176
	 * @return the delayed
177
	 */
178
	public boolean isDelayed() {
179
		return delayed;
180
	}
181

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

    
192
	/**
193
	 * @return the propagateLoads
194
	 */
195
	public boolean isPropagateLoads() {
196
		return propagateLoads;
197
	}
198

    
199
	/**
200
	 * @param propagateLoads the propagateLoads to set
201
	 */
202
	public void setPropagateLoads(boolean propagateLoads) {
203
		this.propagateLoads = propagateLoads;
204
	}
205

    
206
	/**
207
	 * @return the propagateInserts
208
	 */
209
	public boolean isPropagateInserts() {
210
		return propagateInserts;
211
	}
212

    
213
	/**
214
	 * @param propagateInserts the propagateInserts to set
215
	 */
216
	public void setPropagateInserts(boolean propagateInserts) {
217
		this.propagateInserts = propagateInserts;
218
	}
219

    
220
	/**
221
	 * @return the propagateUpdates
222
	 */
223
	public boolean isPropagateUpdates() {
224
		return propagateUpdates;
225
	}
226

    
227
	/**
228
	 * @param propagateUpdates the propagateUpdates to set
229
	 */
230
	public void setPropagateUpdates(boolean propagateUpdates) {
231
		this.propagateUpdates = propagateUpdates;
232
	}
233

    
234
	/**
235
	 * @return the propagateDeletes
236
	 */
237
	public boolean isPropagateDeletes() {
238
		return propagateDeletes;
239
	}
240

    
241
	/**
242
	 * @param propagateDeletes the propagateDeletes to set
243
	 */
244
	public void setPropagateDeletes(boolean propagateDeletes) {
245
		this.propagateDeletes = propagateDeletes;
246
	}
247
	
248
}
(6-6/10)