@@ -21,6 +21,7 @@ Licensed to the Apache Software Foundation (ASF) under one
2121
2222import org .apache .logging .log4j .LogManager ;
2323import org .apache .logging .log4j .Logger ;
24+ import org .apache .wiki .util .Synchronizer ;
2425
2526import java .lang .ref .WeakReference ;
2627import java .util .ArrayList ;
@@ -33,6 +34,7 @@ Licensed to the Apache Software Foundation (ASF) under one
3334import java .util .Set ;
3435import java .util .TreeSet ;
3536import java .util .Vector ;
37+ import java .util .concurrent .atomic .AtomicBoolean ;
3638import java .util .concurrent .locks .ReentrantLock ;
3739
3840/**
@@ -150,7 +152,18 @@ public final class WikiEventManager {
150152 *
151153 * @see java.util.concurrent.locks.ReentrantLock
152154 */
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+
154167
155168
156169 /** Constructor for a WikiEventManager. */
@@ -167,15 +180,12 @@ private WikiEventManager() {
167180 */
168181 public static WikiEventManager getInstance () {
169182 if (c_instance == null ) {
170- lock .lock ();
171- try {
183+ Synchronizer .synchronize (instanceLock , () -> {
172184 if (c_instance == null ) {
173185 c_instance = new WikiEventManager ();
174186 // start up any post-instantiation services here
175187 }
176- } finally {
177- lock .unlock ();
178- }
188+ });
179189 }
180190 return c_instance ;
181191 }
@@ -255,41 +265,28 @@ public static Set<WikiEventListener> getWikiEventListeners( final Object client
255265 * @return true if the listener was found and removed.
256266 */
257267 public static boolean removeWikiEventListener ( final WikiEventListener listener ) {
258- boolean removed = false ;
268+ final AtomicBoolean removed = new AtomicBoolean ( false ) ;
259269 // get the Map.entry object for the entire Map, then check match on entry (listener)
260270 final WikiEventManager mgr = getInstance ();
261271 final Map < Object , WikiEventDelegate > sources = Collections .synchronizedMap ( mgr .getDelegates () );
262- lock .lock ();
263- try {
272+ Synchronizer .synchronize (removeWikiEventListenerLock , () -> {
264273 // get an iterator over the Map.Enty objects in the map
265274 for ( final Map .Entry < Object , WikiEventDelegate > entry : sources .entrySet () ) {
266275 // the entry value is the delegate
267276 final WikiEventDelegate delegate = entry .getValue ();
268277
269278 // now see if we can remove the listener from the delegate (delegate may be null because this is a weak reference)
270279 if ( delegate != null && delegate .removeWikiEventListener ( listener ) ) {
271- removed = true ; // was removed
280+ removed . set ( true ) ; // was removed
272281 }
273282 }
274- } finally {
275- lock .unlock ();
276- }
277- return removed ;
283+ });
284+ return removed .get ();
278285 }
279286
280287 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 );
293290 }
294291
295292 public static void shutdown () {
@@ -340,38 +337,35 @@ private Map< Object, WikiEventDelegate > getDelegates() {
340337 * @param client the client Object, or alternately a Class reference
341338 * @return the WikiEventDelegate.
342339 */
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 );
350346 return delegate ;
351- } else if ( !m_preloadCache .isEmpty () ) {
347+ } else if ( !m_preloadCache .isEmpty ()) {
352348 // 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 ()) ) {
356352 // 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 );
360356 return delegate ;
361357 }
362358 }
363359 }
364360 }
365361 // 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 );
370366 }
371367 return delegate ;
372- } finally {
373- lock .unlock ();
374- }
368+ });
375369 }
376370
377371
@@ -415,8 +409,7 @@ private static final class WikiEventDelegate {
415409 * @throws java.lang.UnsupportedOperationException if any attempt is made to modify the Set
416410 */
417411 public Set < WikiEventListener > getWikiEventListeners () {
418- lock .lock ();
419- try {
412+ return Synchronizer .synchronize (wikiEventListenersLock , () -> {
420413 final TreeSet < WikiEventListener > set = new TreeSet <>( new WikiEventListenerComparator () );
421414 for ( final WeakReference < WikiEventListener > wikiEventListenerWeakReference : m_listenerList ) {
422415 final WikiEventListener l = wikiEventListenerWeakReference .get ();
@@ -426,9 +419,7 @@ public Set< WikiEventListener > getWikiEventListeners() {
426419 }
427420
428421 return Collections .unmodifiableSet ( set );
429- } finally {
430- lock .unlock ();
431- }
422+ });
432423 }
433424
434425 /**
@@ -438,18 +429,15 @@ public Set< WikiEventListener > getWikiEventListeners() {
438429 * @return true if the listener was added (i.e., it was not already in the list and was added)
439430 */
440431 public boolean addWikiEventListener ( final WikiEventListener listener ) {
441- lock .lock ();
442- try {
432+ return Synchronizer .synchronize (wikiEventListenerLock , () -> {
443433 final boolean listenerAlreadyContained = m_listenerList .stream ()
444434 .map ( WeakReference ::get )
445435 .anyMatch ( ref -> ref == listener );
446436 if ( !listenerAlreadyContained ) {
447437 return m_listenerList .add ( new WeakReference <>( listener ) );
448438 }
449- } finally {
450- lock .unlock ();
451- }
452- return false ;
439+ return false ;
440+ });
453441 }
454442
455443 /**
@@ -459,67 +447,54 @@ public boolean addWikiEventListener( final WikiEventListener listener ) {
459447 * @return true if the listener was removed (i.e., it was actually in the list and was removed)
460448 */
461449 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 (); ) {
465452 final WikiEventListener l = i .next ().get ();
466- if ( l == listener ) {
453+ if ( l == listener ) {
467454 i .remove ();
468455 return true ;
469456 }
470457 }
471- } finally {
472- lock .unlock ();
473- }
474-
475- return false ;
458+ return false ;
459+ });
476460 }
477461
478462 /**
479463 * Returns true if there are one or more listeners registered with this instance.
480464 */
481465 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 ());
488467 }
489468
490469 /**
491470 * Notify all listeners having a registered interest in change events of the supplied WikiEvent.
492471 */
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 ) ;
495474 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 ) {
499477 final WikiEventListener listener = wikiEventListenerWeakReference .get ();
500- if ( listener != null ) {
501- listener .actionPerformed ( event );
478+ if ( listener != null ) {
479+ listener .actionPerformed (event );
502480 } else {
503- needsCleanup = true ;
481+ needsCleanup . set ( true ) ;
504482 }
505483 }
506484
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 ) {
512490 m_listenerList .remove (i --);
513491 }
514492 }
515493 }
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 );
523498 }
524499 }
525500 }
0 commit comments