This is an automated email from the ASF dual-hosted git repository. juanpablo pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/jspwiki.git
commit 835e5664c3f9fb2024bb3fac378fad54888101d6 Author: Juan Pablo Santos RodrÃguez <[email protected]> AuthorDate: Fri May 9 19:48:32 2025 +0200 Introduce CachingManager#registerListener(..) so that caching providers are able to register expired cache listeners - closes #362 --- .../java/org/apache/wiki/cache/CachingManager.java | 9 +++++++++ .../org/apache/wiki/cache/EhcacheCachingManager.java | 19 +++++++++++++++++++ .../wiki/providers/CachingAttachmentProvider.java | 8 +++++--- .../org/apache/wiki/providers/CachingProvider.java | 8 +++++--- 4 files changed, 38 insertions(+), 6 deletions(-) diff --git a/jspwiki-cache/src/main/java/org/apache/wiki/cache/CachingManager.java b/jspwiki-cache/src/main/java/org/apache/wiki/cache/CachingManager.java index 245e1efe7..2062bd97e 100644 --- a/jspwiki-cache/src/main/java/org/apache/wiki/cache/CachingManager.java +++ b/jspwiki-cache/src/main/java/org/apache/wiki/cache/CachingManager.java @@ -121,4 +121,13 @@ public interface CachingManager { */ void remove( String cacheName, Serializable key ); + /** + * Register a listener associated with the given cache and type of listener. + * @param cacheName the name of the cache where the listener will be registered. + * @param listener the kind of listener to be registered + * @param args arguments needed to instantiate and register the listener. + * @return {@code true} if the listener is created & registered, {@code false} otherwise. + */ + default boolean registerListener( String cacheName, String listener, Object... args ) { return false; } + } diff --git a/jspwiki-cache/src/main/java/org/apache/wiki/cache/EhcacheCachingManager.java b/jspwiki-cache/src/main/java/org/apache/wiki/cache/EhcacheCachingManager.java index a624f0734..cb6009d13 100644 --- a/jspwiki-cache/src/main/java/org/apache/wiki/cache/EhcacheCachingManager.java +++ b/jspwiki-cache/src/main/java/org/apache/wiki/cache/EhcacheCachingManager.java @@ -20,7 +20,9 @@ package org.apache.wiki.cache; import net.sf.ehcache.Cache; import net.sf.ehcache.CacheManager; +import net.sf.ehcache.Ehcache; import net.sf.ehcache.Element; +import net.sf.ehcache.event.CacheEventListenerAdapter; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.wiki.api.core.Engine; @@ -36,6 +38,7 @@ import java.util.List; import java.util.Map; import java.util.Properties; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicBoolean; /** @@ -159,6 +162,22 @@ public class EhcacheCachingManager implements CachingManager, Initializable { } } + /** {@inheritDoc} */ + @Override + public boolean registerListener( final String cacheName, final String listener, final Object... args ) { + if( enabled( cacheName ) && "expired".equals( listener ) ) { + final AtomicBoolean allRequested = ( AtomicBoolean )args[0]; + final CacheEventListenerAdapter expiredCacheListenerAdapter = new CacheEventListenerAdapter() { + @Override + public void notifyElementExpired( final Ehcache cache, final Element element ) { + allRequested.set( false ); // signal that the cache no longer contains all elements... + } + }; + return cacheMap.get( cacheName ).getCacheEventNotificationService().registerListener( expiredCacheListenerAdapter ); + } + return false; + } + boolean keyAndCacheAreNotNull( final String cacheName, final Serializable key ) { return enabled( cacheName ) && key != null; } diff --git a/jspwiki-main/src/main/java/org/apache/wiki/providers/CachingAttachmentProvider.java b/jspwiki-main/src/main/java/org/apache/wiki/providers/CachingAttachmentProvider.java index e8523d071..eda06dadd 100644 --- a/jspwiki-main/src/main/java/org/apache/wiki/providers/CachingAttachmentProvider.java +++ b/jspwiki-main/src/main/java/org/apache/wiki/providers/CachingAttachmentProvider.java @@ -44,6 +44,7 @@ import java.util.Date; import java.util.List; import java.util.NoSuchElementException; import java.util.Properties; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; @@ -59,7 +60,7 @@ public class CachingAttachmentProvider implements AttachmentProvider { private AttachmentProvider provider; private CachingManager cachingManager; - private boolean allRequested; + private final AtomicBoolean allRequested = new AtomicBoolean(); private final AtomicLong attachments = new AtomicLong( 0L ); /** @@ -69,6 +70,7 @@ public class CachingAttachmentProvider implements AttachmentProvider { public void initialize( final Engine engine, final Properties properties ) throws NoRequiredPropertyException, IOException { LOG.info( "Initing CachingAttachmentProvider" ); cachingManager = engine.getManager( CachingManager.class ); + cachingManager.registerListener( CachingManager.CACHE_ATTACHMENTS, "expired", allRequested ); // Find and initialize real provider. final String classname; @@ -137,7 +139,7 @@ public class CachingAttachmentProvider implements AttachmentProvider { @Override public List< Attachment > listAllChanged( final Date timestamp ) throws ProviderException { final List< Attachment > all; - if ( !allRequested ) { + if ( !allRequested.get() ) { all = provider.listAllChanged( timestamp ); // Make sure that all attachments are in the cache. @@ -146,7 +148,7 @@ public class CachingAttachmentProvider implements AttachmentProvider { cachingManager.put( CachingManager.CACHE_ATTACHMENTS, att.getName(), att ); } if( timestamp.getTime() == 0L ) { // all attachments requested - allRequested = true; + allRequested.set( true ); attachments.set( all.size() ); } } diff --git a/jspwiki-main/src/main/java/org/apache/wiki/providers/CachingProvider.java b/jspwiki-main/src/main/java/org/apache/wiki/providers/CachingProvider.java index 5b1260f46..eeb1db3ab 100644 --- a/jspwiki-main/src/main/java/org/apache/wiki/providers/CachingProvider.java +++ b/jspwiki-main/src/main/java/org/apache/wiki/providers/CachingProvider.java @@ -44,6 +44,7 @@ import java.util.List; import java.util.NoSuchElementException; import java.util.Properties; import java.util.TreeSet; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; @@ -67,7 +68,7 @@ public class CachingProvider implements PageProvider { private PageProvider provider; private Engine engine; - private boolean allRequested; + private final AtomicBoolean allRequested = new AtomicBoolean(); private final AtomicLong pages = new AtomicLong( 0L ); /** @@ -80,6 +81,7 @@ public class CachingProvider implements PageProvider { // engine is used for getting the search engine this.engine = engine; cachingManager = this.engine.getManager( CachingManager.class ); + cachingManager.registerListener( CachingManager.CACHE_PAGES, "expired", allRequested ); // Find and initialize real provider. final String classname; @@ -240,14 +242,14 @@ public class CachingProvider implements PageProvider { @Override public Collection< Page > getAllPages() throws ProviderException { final Collection< Page > all; - if ( !allRequested ) { + if ( !allRequested.get() ) { all = provider.getAllPages(); // Make sure that all pages are in the cache. synchronized( this ) { for( final Page p : all ) { cachingManager.put( CachingManager.CACHE_PAGES, p.getName(), p ); } - allRequested = true; + allRequested.set( true ); } pages.set( all.size() ); } else {
