1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.module.observation.util;
35
36 import info.magnolia.cms.core.HierarchyManager;
37 import info.magnolia.cms.util.DelayedExecutor;
38 import info.magnolia.context.LifeTimeJCRSessionUtil;
39
40 import java.util.ArrayList;
41 import java.util.Iterator;
42 import java.util.List;
43
44 import javax.jcr.RepositoryException;
45 import javax.jcr.observation.Event;
46 import javax.jcr.observation.EventIterator;
47 import javax.jcr.observation.EventListener;
48 import javax.jcr.observation.ObservationManager;
49
50 import org.apache.jackrabbit.core.observation.SynchronousEventListener;
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
53
54
55
56
57
58
59
60 @Deprecated
61 public class ObservationUtil {
62 private final static Logger log = LoggerFactory
63 .getLogger(ObservationUtil.class);
64
65
66
67
68
69
70 public static void registerChangeListener(String repository,
71 String observationPath, EventListener listener) {
72 registerChangeListener(repository, observationPath, true, listener);
73 }
74
75
76
77
78
79
80 public static void registerChangeListener(String repository,
81 String observationPath, boolean includeSubnodes,
82 EventListener listener) {
83 registerChangeListener(repository, observationPath, includeSubnodes,
84 (String[]) null, listener);
85 }
86
87
88
89
90
91
92 public static void registerChangeListener(String repository,
93 String observationPath, boolean includeSubnodes, String nodeType,
94 EventListener listener) {
95 registerChangeListener(repository, observationPath, includeSubnodes,
96 new String[] { nodeType }, listener);
97 }
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115 public static void registerChangeListener(String repository,
116 String observationPath, boolean includeSubnodes,
117 String[] nodeTypes, EventListener listener) {
118 log.debug("Registering event listener for path [{}]", observationPath);
119
120 try {
121 ObservationManager observationManager = getObservationManager(repository);
122
123 observationManager.addEventListener(listener, Event.NODE_ADDED
124 | Event.NODE_REMOVED | Event.PROPERTY_ADDED
125 | Event.PROPERTY_CHANGED | Event.PROPERTY_REMOVED,
126 observationPath, includeSubnodes, null, nodeTypes, false);
127 } catch (RepositoryException e) {
128 log
129 .error(
130 "Unable to add event listeners for " + observationPath, e);
131 }
132 }
133
134
135
136
137 @Deprecated
138 public static void registerDefferedChangeListener(String repository,
139 String observationPath, EventListener listener, long delay,
140 long maxDelay) {
141 registerDeferredChangeListener(repository, observationPath, listener,
142 delay, maxDelay);
143 }
144
145 public static void registerDeferredChangeListener(String repository,
146 String observationPath, EventListener listener, long delay,
147 long maxDelay) {
148 registerDeferredChangeListener(repository, observationPath, true,
149 (String[]) null, listener, delay, maxDelay);
150 }
151
152
153
154
155 @Deprecated
156 public static void registerDefferedChangeListener(String repository,
157 String observationPath, boolean includeSubnodes,
158 EventListener listener, long delay, long maxDelay) {
159 registerDeferredChangeListener(repository, observationPath,
160 includeSubnodes, listener, delay, maxDelay);
161 }
162
163 public static void registerDeferredChangeListener(String repository,
164 String observationPath, boolean includeSubnodes,
165 EventListener listener, long delay, long maxDelay) {
166 registerDeferredChangeListener(repository, observationPath,
167 includeSubnodes, (String[]) null, listener, delay, maxDelay);
168 }
169
170
171
172
173 @Deprecated
174 public static void registerDefferedChangeListener(String repository,
175 String observationPath, boolean includeSubnodes, String nodeType,
176 EventListener listener, long delay, long maxDelay) {
177 registerDeferredChangeListener(repository, observationPath,
178 includeSubnodes, nodeType, listener, delay, maxDelay);
179 }
180
181 public static void registerDeferredChangeListener(String repository,
182 String observationPath, boolean includeSubnodes, String nodeType,
183 EventListener listener, long delay, long maxDelay) {
184 registerDeferredChangeListener(repository, observationPath,
185 includeSubnodes, new String[] { nodeType }, listener, delay,
186 maxDelay);
187 }
188
189
190
191
192 @Deprecated
193 public static void registerDefferedChangeListener(String repository,
194 String observationPath, boolean includeSubnodes,
195 String[] nodeTypes, EventListener listener, long delay,
196 long maxDelay) {
197 registerDeferredChangeListener(repository, observationPath,
198 includeSubnodes, nodeTypes, listener, delay, maxDelay);
199 }
200
201
202
203
204
205
206 public static void registerDeferredChangeListener(String repository,
207 String observationPath, boolean includeSubnodes,
208 String[] nodeTypes, EventListener listener, long delay,
209 long maxDelay) {
210 final EventListener deferedListener = instanciateDeferredEventListener(
211 listener, delay, maxDelay);
212 registerChangeListener(repository, observationPath, includeSubnodes,
213 nodeTypes, deferedListener);
214 }
215
216
217
218
219
220
221
222
223
224
225 public static void registerChangeListener(String repository,
226 String observationPath, boolean includeSubnodes, String nodeType,
227 int eventTypes, EventListener listener) {
228 if (nodeType == null) {
229 registerChangeListener(repository, observationPath,
230 includeSubnodes, (String[]) null, eventTypes, listener);
231 } else {
232 registerChangeListener(repository, observationPath,
233 includeSubnodes, new String[] { nodeType }, eventTypes,
234 listener);
235 }
236 }
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254 public static void registerChangeListener(String repository,
255 String observationPath, boolean includeSubnodes,
256 String[] nodeTypes, int eventTypes, EventListener listener) {
257 log.debug("Registering event listener for path [{}:{}]", repository, observationPath);
258
259 try {
260 ObservationManager observationManager = getObservationManager(repository);
261
262 observationManager.addEventListener(listener, eventTypes,
263 observationPath, includeSubnodes, null, nodeTypes, false);
264 } catch (RepositoryException e) {
265 log
266 .error(
267 "Unable to add event listeners for " + observationPath, e);
268 }
269 }
270
271
272
273
274
275
276
277
278
279
280 public static EventListener instanciateDeferredEventListener(
281 EventListener listener, long delay, long maxDelay) {
282 return new DeferringEventListener(listener, delay, maxDelay);
283 }
284
285 public static SynchEventListener instanciateSynchEventListener(
286 EventListener listener) {
287 return new SynchEventListener(listener);
288 }
289
290 public static void unregisterChangeListener(String repository,
291 EventListener listener) {
292 try {
293
294 getObservationManager(repository).removeEventListener(listener);
295
296 } catch (RepositoryException e) {
297 log.error("Unable to remove event listener [" + listener
298 + "] from repository " + repository, e);
299 }
300 }
301
302 private static ObservationManager getObservationManager(String repository)
303 throws RepositoryException {
304 return getHierarchyManager(repository).getWorkspace()
305 .getObservationManager();
306 }
307
308 private static HierarchyManager getHierarchyManager(String repository) {
309 return LifeTimeJCRSessionUtil.getHierarchyManager(repository);
310 }
311
312
313
314
315 public static class SynchEventListener implements SynchronousEventListener {
316
317 private final EventListener listener;
318
319 public SynchEventListener(EventListener listener) {
320 this.listener = listener;
321
322 }
323
324 public void onEvent(EventIterator events) {
325 this.listener.onEvent(events);
326 }
327
328 @Override
329 public String toString() {
330 return super.toString() + ":" + this.listener;
331 }
332 }
333
334
335
336
337 public static class DeferringEventListener implements EventListener {
338
339 private final ObservationBasedDelayedExecutor executor;
340
341 private final EventListener listener;
342
343 public DeferringEventListener(EventListener listener, long delay,
344 long maxDelay) {
345 this.listener = listener;
346 executor = new ObservationBasedDelayedExecutor(listener, delay,
347 maxDelay);
348 }
349
350 public void onEvent(EventIterator events) {
351 this.executor.consume(events);
352 }
353
354 @Override
355 public String toString() {
356 return super.toString() + ":" + this.listener;
357 }
358 }
359
360
361
362
363 public static class ObservationBasedDelayedExecutor {
364 private final DelayedExecutor delayedExecutor;
365 private final List eventsBuffer = new ArrayList();
366
367 public ObservationBasedDelayedExecutor(final EventListener listener,
368 long delay, long maxDelay) {
369 delayedExecutor = new DelayedExecutor(new Runnable() {
370 public void run() {
371
372 synchronized (eventsBuffer) {
373 listener.onEvent(new ListBasedEventIterator(
374 eventsBuffer));
375 eventsBuffer.clear();
376 }
377 }
378 }, delay, maxDelay);
379 }
380
381 protected void consume(EventIterator events) {
382 synchronized (this.eventsBuffer) {
383 while (events.hasNext()) {
384 this.eventsBuffer.add(events.next());
385 }
386 delayedExecutor.trigger();
387 }
388 }
389 }
390
391
392
393
394
395 public static class ListBasedEventIterator implements EventIterator {
396 private final Iterator iterator;
397 private final List events;
398 private int pos = 0;
399
400 public ListBasedEventIterator(List events) {
401 this.events = events;
402 this.iterator = events.iterator();
403 }
404
405 public boolean hasNext() {
406 return this.iterator.hasNext();
407 }
408
409 public Object next() {
410 pos++;
411 return this.iterator.next();
412 }
413
414 public void remove() {
415 this.iterator.remove();
416 }
417
418 public Event nextEvent() {
419 return (Event) next();
420 }
421
422 public long getPosition() {
423 return pos;
424 }
425
426 public long getSize() {
427 return events.size();
428 }
429
430 public void skip(long skipNum) {
431 for (int i = 0; i < skipNum; i++) {
432 next();
433 }
434 }
435 }
436
437 }