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 {

Reply via email to