@@ -21,6 +21,7 @@ Licensed to the Apache Software Foundation (ASF) under one
21
21
22
22
import org .apache .logging .log4j .LogManager ;
23
23
import org .apache .logging .log4j .Logger ;
24
+ import org .apache .wiki .util .Synchronizer ;
24
25
25
26
import java .lang .ref .WeakReference ;
26
27
import java .util .ArrayList ;
@@ -33,6 +34,7 @@ Licensed to the Apache Software Foundation (ASF) under one
33
34
import java .util .Set ;
34
35
import java .util .TreeSet ;
35
36
import java .util .Vector ;
37
+ import java .util .concurrent .atomic .AtomicBoolean ;
36
38
import java .util .concurrent .locks .ReentrantLock ;
37
39
38
40
/**
@@ -150,7 +152,18 @@ public final class WikiEventManager {
150
152
*
151
153
* @see java.util.concurrent.locks.ReentrantLock
152
154
*/
153
- private static final ReentrantLock lock = new ReentrantLock ();
155
+ private static final ReentrantLock instanceLock = new ReentrantLock ();
156
+ private static final ReentrantLock removeWikiEventListenerLock = new ReentrantLock ();
157
+ private static final ReentrantLock delegatesLockLock = new ReentrantLock ();
158
+ private static final ReentrantLock preloadCacheLock = new ReentrantLock ();
159
+ private static final ReentrantLock delegateForLock = new ReentrantLock ();
160
+ private static final ReentrantLock wikiEventListenersLock = new ReentrantLock ();
161
+ private static final ReentrantLock wikiEventListenerLock = new ReentrantLock ();
162
+ private static final ReentrantLock removeWikiEventListenerLock2 = new ReentrantLock ();
163
+ private static final ReentrantLock isListeningLock = new ReentrantLock ();
164
+ private static final ReentrantLock fireEventLock = new ReentrantLock ();
165
+
166
+
154
167
155
168
156
169
/** Constructor for a WikiEventManager. */
@@ -167,15 +180,12 @@ private WikiEventManager() {
167
180
*/
168
181
public static WikiEventManager getInstance () {
169
182
if (c_instance == null ) {
170
- lock .lock ();
171
- try {
183
+ Synchronizer .synchronize (instanceLock , () -> {
172
184
if (c_instance == null ) {
173
185
c_instance = new WikiEventManager ();
174
186
// start up any post-instantiation services here
175
187
}
176
- } finally {
177
- lock .unlock ();
178
- }
188
+ });
179
189
}
180
190
return c_instance ;
181
191
}
@@ -255,41 +265,28 @@ public static Set<WikiEventListener> getWikiEventListeners( final Object client
255
265
* @return true if the listener was found and removed.
256
266
*/
257
267
public static boolean removeWikiEventListener ( final WikiEventListener listener ) {
258
- boolean removed = false ;
268
+ final AtomicBoolean removed = new AtomicBoolean ( false ) ;
259
269
// get the Map.entry object for the entire Map, then check match on entry (listener)
260
270
final WikiEventManager mgr = getInstance ();
261
271
final Map < Object , WikiEventDelegate > sources = Collections .synchronizedMap ( mgr .getDelegates () );
262
- lock .lock ();
263
- try {
272
+ Synchronizer .synchronize (removeWikiEventListenerLock , () -> {
264
273
// get an iterator over the Map.Enty objects in the map
265
274
for ( final Map .Entry < Object , WikiEventDelegate > entry : sources .entrySet () ) {
266
275
// the entry value is the delegate
267
276
final WikiEventDelegate delegate = entry .getValue ();
268
277
269
278
// now see if we can remove the listener from the delegate (delegate may be null because this is a weak reference)
270
279
if ( delegate != null && delegate .removeWikiEventListener ( listener ) ) {
271
- removed = true ; // was removed
280
+ removed . set ( true ) ; // was removed
272
281
}
273
282
}
274
- } finally {
275
- lock .unlock ();
276
- }
277
- return removed ;
283
+ });
284
+ return removed .get ();
278
285
}
279
286
280
287
private void removeDelegates () {
281
- lock .lock ();
282
- try {
283
- m_delegates .clear ();
284
- } finally {
285
- lock .unlock ();
286
- }
287
- lock .lock ();
288
- try {
289
- m_preloadCache .clear ();
290
- } finally {
291
- lock .unlock ();
292
- }
288
+ Synchronizer .synchronize (delegatesLockLock , m_delegates ::clear );
289
+ Synchronizer .synchronize (preloadCacheLock , m_preloadCache ::clear );
293
290
}
294
291
295
292
public static void shutdown () {
@@ -340,38 +337,35 @@ private Map< Object, WikiEventDelegate > getDelegates() {
340
337
* @param client the client Object, or alternately a Class reference
341
338
* @return the WikiEventDelegate.
342
339
*/
343
- private WikiEventDelegate getDelegateFor ( final Object client ) {
344
- lock .lock ();
345
- try {
346
- if ( client == null || client instanceof Class ) { // then preload the cache
347
- final WikiEventDelegate delegate = new WikiEventDelegate ( client );
348
- m_preloadCache .add ( delegate );
349
- m_delegates .put ( client , delegate );
340
+ private WikiEventDelegate getDelegateFor (final Object client ) {
341
+ return Synchronizer .synchronize (delegateForLock , () -> {
342
+ if (client == null || client instanceof Class ) { // then preload the cache
343
+ final WikiEventDelegate delegate = new WikiEventDelegate (client );
344
+ m_preloadCache .add (delegate );
345
+ m_delegates .put (client , delegate );
350
346
return delegate ;
351
- } else if ( !m_preloadCache .isEmpty () ) {
347
+ } else if ( !m_preloadCache .isEmpty ()) {
352
348
// then see if any of the cached delegates match the class of the incoming client
353
- for ( int i = m_preloadCache .size ()- 1 ; i >= 0 ; i -- ) { // start with most-recently added
354
- final WikiEventDelegate delegate = m_preloadCache .elementAt ( i );
355
- if ( delegate .getClientClass () == null || delegate .getClientClass ().equals ( client .getClass () ) ) {
349
+ for ( int i = m_preloadCache .size () - 1 ; i >= 0 ; i --) { // start with most-recently added
350
+ final WikiEventDelegate delegate = m_preloadCache .elementAt (i );
351
+ if ( delegate .getClientClass () == null || delegate .getClientClass ().equals (client .getClass ()) ) {
356
352
// we have a hit, so use it, but only on a client we haven't seen before
357
- if ( !m_delegates .containsKey ( client ) ) {
358
- m_preloadCache .remove ( delegate );
359
- m_delegates .put ( client , delegate );
353
+ if ( !m_delegates .containsKey (client ) ) {
354
+ m_preloadCache .remove (delegate );
355
+ m_delegates .put (client , delegate );
360
356
return delegate ;
361
357
}
362
358
}
363
359
}
364
360
}
365
361
// otherwise treat normally...
366
- WikiEventDelegate delegate = m_delegates .get ( client );
367
- if ( delegate == null ) {
368
- delegate = new WikiEventDelegate ( client );
369
- m_delegates .put ( client , delegate );
362
+ WikiEventDelegate delegate = m_delegates .get (client );
363
+ if ( delegate == null ) {
364
+ delegate = new WikiEventDelegate (client );
365
+ m_delegates .put (client , delegate );
370
366
}
371
367
return delegate ;
372
- } finally {
373
- lock .unlock ();
374
- }
368
+ });
375
369
}
376
370
377
371
@@ -415,8 +409,7 @@ private static final class WikiEventDelegate {
415
409
* @throws java.lang.UnsupportedOperationException if any attempt is made to modify the Set
416
410
*/
417
411
public Set < WikiEventListener > getWikiEventListeners () {
418
- lock .lock ();
419
- try {
412
+ return Synchronizer .synchronize (wikiEventListenersLock , () -> {
420
413
final TreeSet < WikiEventListener > set = new TreeSet <>( new WikiEventListenerComparator () );
421
414
for ( final WeakReference < WikiEventListener > wikiEventListenerWeakReference : m_listenerList ) {
422
415
final WikiEventListener l = wikiEventListenerWeakReference .get ();
@@ -426,9 +419,7 @@ public Set< WikiEventListener > getWikiEventListeners() {
426
419
}
427
420
428
421
return Collections .unmodifiableSet ( set );
429
- } finally {
430
- lock .unlock ();
431
- }
422
+ });
432
423
}
433
424
434
425
/**
@@ -438,18 +429,15 @@ public Set< WikiEventListener > getWikiEventListeners() {
438
429
* @return true if the listener was added (i.e., it was not already in the list and was added)
439
430
*/
440
431
public boolean addWikiEventListener ( final WikiEventListener listener ) {
441
- lock .lock ();
442
- try {
432
+ return Synchronizer .synchronize (wikiEventListenerLock , () -> {
443
433
final boolean listenerAlreadyContained = m_listenerList .stream ()
444
434
.map ( WeakReference ::get )
445
435
.anyMatch ( ref -> ref == listener );
446
436
if ( !listenerAlreadyContained ) {
447
437
return m_listenerList .add ( new WeakReference <>( listener ) );
448
438
}
449
- } finally {
450
- lock .unlock ();
451
- }
452
- return false ;
439
+ return false ;
440
+ });
453
441
}
454
442
455
443
/**
@@ -459,67 +447,54 @@ public boolean addWikiEventListener( final WikiEventListener listener ) {
459
447
* @return true if the listener was removed (i.e., it was actually in the list and was removed)
460
448
*/
461
449
public boolean removeWikiEventListener ( final WikiEventListener listener ) {
462
- lock .lock ();
463
- try {
464
- for ( final Iterator < WeakReference < WikiEventListener > > i = m_listenerList .iterator (); i .hasNext (); ) {
450
+ return Synchronizer .synchronize (removeWikiEventListenerLock2 , () -> {
451
+ for (final Iterator <WeakReference <WikiEventListener >> i = m_listenerList .iterator (); i .hasNext (); ) {
465
452
final WikiEventListener l = i .next ().get ();
466
- if ( l == listener ) {
453
+ if ( l == listener ) {
467
454
i .remove ();
468
455
return true ;
469
456
}
470
457
}
471
- } finally {
472
- lock .unlock ();
473
- }
474
-
475
- return false ;
458
+ return false ;
459
+ });
476
460
}
477
461
478
462
/**
479
463
* Returns true if there are one or more listeners registered with this instance.
480
464
*/
481
465
public boolean isListening () {
482
- lock .lock ();
483
- try {
484
- return !m_listenerList .isEmpty ();
485
- } finally {
486
- lock .unlock ();
487
- }
466
+ return Synchronizer .synchronize (isListeningLock , () -> !m_listenerList .isEmpty ());
488
467
}
489
468
490
469
/**
491
470
* Notify all listeners having a registered interest in change events of the supplied WikiEvent.
492
471
*/
493
- public void fireEvent ( final WikiEvent event ) {
494
- boolean needsCleanup = false ;
472
+ public void fireEvent (final WikiEvent event ) {
473
+ final AtomicBoolean needsCleanup = new AtomicBoolean ( false ) ;
495
474
try {
496
- lock .lock ();
497
- try {
498
- for ( final WeakReference < WikiEventListener > wikiEventListenerWeakReference : m_listenerList ) {
475
+ Synchronizer .synchronize (fireEventLock , () -> {
476
+ for (final WeakReference <WikiEventListener > wikiEventListenerWeakReference : m_listenerList ) {
499
477
final WikiEventListener listener = wikiEventListenerWeakReference .get ();
500
- if ( listener != null ) {
501
- listener .actionPerformed ( event );
478
+ if ( listener != null ) {
479
+ listener .actionPerformed (event );
502
480
} else {
503
- needsCleanup = true ;
481
+ needsCleanup . set ( true ) ;
504
482
}
505
483
}
506
484
507
- // Remove all such listeners which have expired
508
- if ( needsCleanup ) {
509
- for ( int i = 0 ; i < m_listenerList .size (); i ++ ) {
510
- final WeakReference < WikiEventListener > w = m_listenerList .get ( i );
511
- if ( w .get () == null ) {
485
+ // Remove all such listeners which have expired
486
+ if ( needsCleanup . get () ) {
487
+ for ( int i = 0 ; i < m_listenerList .size (); i ++) {
488
+ final WeakReference <WikiEventListener > w = m_listenerList .get (i );
489
+ if ( w .get () == null ) {
512
490
m_listenerList .remove (i --);
513
491
}
514
492
}
515
493
}
516
-
517
- } finally {
518
- lock .unlock ();
519
- }
520
- } catch ( final ConcurrentModificationException e ) {
521
- // We don't die, we just don't do notifications in that case.
522
- LOG .info ( "Concurrent modification of event list; please report this." , e );
494
+ });
495
+ } catch (final ConcurrentModificationException e ) {
496
+ // We don't die, we just don't do notifications in that case.
497
+ LOG .info ("Concurrent modification of event list; please report this." , e );
523
498
}
524
499
}
525
500
}
0 commit comments