فهرست منبع

Refactor EH-CACHE integration classes to work with Spring IoC provided Cache rather than manage our own cache internally.

Ben Alex 21 سال پیش
والد
کامیت
76c82db196

+ 12 - 40
core/src/main/java/org/acegisecurity/acl/basic/cache/EhCacheBasedAclEntryCache.java

@@ -21,40 +21,43 @@ import net.sf.acegisecurity.acl.basic.BasicAclEntryCache;
 
 
 import net.sf.ehcache.Cache;
 import net.sf.ehcache.Cache;
 import net.sf.ehcache.CacheException;
 import net.sf.ehcache.CacheException;
-import net.sf.ehcache.CacheManager;
 import net.sf.ehcache.Element;
 import net.sf.ehcache.Element;
 
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.commons.logging.LogFactory;
 
 
-import org.springframework.beans.factory.DisposableBean;
 import org.springframework.beans.factory.InitializingBean;
 import org.springframework.beans.factory.InitializingBean;
 
 
 import org.springframework.dao.DataRetrievalFailureException;
 import org.springframework.dao.DataRetrievalFailureException;
 
 
 
 
 /**
 /**
- * Caches <code>BasicAclEntry</code>s using  <A
+ * Caches <code>BasicAclEntry</code>s using a Spring IoC defined <A
  * HREF="http://ehcache.sourceforge.net">EHCACHE</a>.
  * HREF="http://ehcache.sourceforge.net">EHCACHE</a>.
  *
  *
  * @author Ben Alex
  * @author Ben Alex
  * @version $Id$
  * @version $Id$
  */
  */
 public class EhCacheBasedAclEntryCache implements BasicAclEntryCache,
 public class EhCacheBasedAclEntryCache implements BasicAclEntryCache,
-    InitializingBean, DisposableBean {
+    InitializingBean {
     //~ Static fields/initializers =============================================
     //~ Static fields/initializers =============================================
 
 
     private static final Log logger = LogFactory.getLog(EhCacheBasedAclEntryCache.class);
     private static final Log logger = LogFactory.getLog(EhCacheBasedAclEntryCache.class);
-    private static final String CACHE_NAME = "ehCacheBasedAclEntryCache";
 
 
     //~ Instance fields ========================================================
     //~ Instance fields ========================================================
 
 
     private Cache cache;
     private Cache cache;
-    private CacheManager manager;
-    private int minutesToIdle = 5;
 
 
     //~ Methods ================================================================
     //~ Methods ================================================================
 
 
+    public void setCache(Cache cache) {
+        this.cache = cache;
+    }
+
+    public Cache getCache() {
+        return cache;
+    }
+
     public BasicAclEntry[] getEntriesFromCache(
     public BasicAclEntry[] getEntriesFromCache(
         AclObjectIdentity aclObjectIdentity) {
         AclObjectIdentity aclObjectIdentity) {
         Element element = null;
         Element element = null;
@@ -85,43 +88,12 @@ public class EhCacheBasedAclEntryCache implements BasicAclEntryCache,
         return holder.getBasicAclEntries();
         return holder.getBasicAclEntries();
     }
     }
 
 
-    public void setMinutesToIdle(int minutesToIdle) {
-        this.minutesToIdle = minutesToIdle;
-    }
-
-    /**
-     * Specifies how many minutes an entry will remain in the cache from when
-     * it was last accessed.
-     * 
-     * <P>
-     * Defaults to 5 minutes.
-     * </p>
-     *
-     * @return Returns the minutes an element remains in the cache
-     */
-    public int getMinutesToIdle() {
-        return minutesToIdle;
-    }
-
     public void afterPropertiesSet() throws Exception {
     public void afterPropertiesSet() throws Exception {
-        if (CacheManager.getInstance().cacheExists(CACHE_NAME)) {
-            // don’t remove the cache
-            cache = CacheManager.getInstance().getCache(CACHE_NAME);
-        } else {
-            manager = CacheManager.create();
-
-            // Cache name, max memory, overflowToDisk, eternal, timeToLive, timeToIdle
-            cache = new Cache(CACHE_NAME, Integer.MAX_VALUE, false, false,
-                    minutesToIdle * 60, minutesToIdle * 60);
-
-            manager.addCache(cache);
+        if (cache == null) {
+            throw new IllegalArgumentException("cache mandatory");
         }
         }
     }
     }
 
 
-    public void destroy() throws Exception {
-        manager.removeCache(CACHE_NAME);
-    }
-
     public void putEntriesInCache(BasicAclEntry[] basicAclEntry) {
     public void putEntriesInCache(BasicAclEntry[] basicAclEntry) {
         BasicAclEntryHolder holder = new BasicAclEntryHolder(basicAclEntry);
         BasicAclEntryHolder holder = new BasicAclEntryHolder(basicAclEntry);
         Element element = new Element(basicAclEntry[0].getAclObjectIdentity(),
         Element element = new Element(basicAclEntry[0].getAclObjectIdentity(),

+ 9 - 36
core/src/main/java/org/acegisecurity/providers/cas/cache/EhCacheBasedTicketCache.java

@@ -20,36 +20,32 @@ import net.sf.acegisecurity.providers.cas.StatelessTicketCache;
 
 
 import net.sf.ehcache.Cache;
 import net.sf.ehcache.Cache;
 import net.sf.ehcache.CacheException;
 import net.sf.ehcache.CacheException;
-import net.sf.ehcache.CacheManager;
 import net.sf.ehcache.Element;
 import net.sf.ehcache.Element;
 
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.commons.logging.LogFactory;
 
 
-import org.springframework.beans.factory.DisposableBean;
 import org.springframework.beans.factory.InitializingBean;
 import org.springframework.beans.factory.InitializingBean;
 
 
 import org.springframework.dao.DataRetrievalFailureException;
 import org.springframework.dao.DataRetrievalFailureException;
 
 
 
 
 /**
 /**
- * Caches tickets using  <A HREF="http://ehcache.sourceforge.net">EHCACHE</a>.
+ * Caches tickets using a Spring IoC defined <A
+ * HREF="http://ehcache.sourceforge.net">EHCACHE</a>.
  *
  *
  * @author Ben Alex
  * @author Ben Alex
  * @version $Id$
  * @version $Id$
  */
  */
 public class EhCacheBasedTicketCache implements StatelessTicketCache,
 public class EhCacheBasedTicketCache implements StatelessTicketCache,
-    InitializingBean, DisposableBean {
+    InitializingBean {
     //~ Static fields/initializers =============================================
     //~ Static fields/initializers =============================================
 
 
     private static final Log logger = LogFactory.getLog(EhCacheBasedTicketCache.class);
     private static final Log logger = LogFactory.getLog(EhCacheBasedTicketCache.class);
-    private static final String CACHE_NAME = "ehCacheBasedTicketCache";
 
 
     //~ Instance fields ========================================================
     //~ Instance fields ========================================================
 
 
     private Cache cache;
     private Cache cache;
-    private CacheManager manager;
-    private int minutesToIdle = 20;
 
 
     //~ Methods ================================================================
     //~ Methods ================================================================
 
 
@@ -75,43 +71,20 @@ public class EhCacheBasedTicketCache implements StatelessTicketCache,
         }
         }
     }
     }
 
 
-    public void setMinutesToIdle(int minutesToIdle) {
-        this.minutesToIdle = minutesToIdle;
+    public void setCache(Cache cache) {
+        this.cache = cache;
     }
     }
 
 
-    /**
-     * Specifies how many minutes an entry will remain in the cache from  when
-     * it was last accessed. This is effectively the session duration.
-     * 
-     * <P>
-     * Defaults to 20 minutes.
-     * </p>
-     *
-     * @return Returns the minutes an element remains in the cache
-     */
-    public int getMinutesToIdle() {
-        return minutesToIdle;
+    public Cache getCache() {
+        return cache;
     }
     }
 
 
     public void afterPropertiesSet() throws Exception {
     public void afterPropertiesSet() throws Exception {
-        if (CacheManager.getInstance().cacheExists(CACHE_NAME)) {
-            // don’t remove the cache
-            cache = CacheManager.getInstance().getCache(CACHE_NAME);
-        } else {
-            manager = CacheManager.create();
-
-            // Cache name, max memory, overflowToDisk, eternal, timeToLive, timeToIdle
-            cache = new Cache(CACHE_NAME, Integer.MAX_VALUE, false, false,
-                    minutesToIdle * 60, minutesToIdle * 60);
-
-            manager.addCache(cache);
+        if (cache == null) {
+            throw new IllegalArgumentException("cache mandatory");
         }
         }
     }
     }
 
 
-    public void destroy() throws Exception {
-        manager.removeCache(CACHE_NAME);
-    }
-
     public void putTicketInCache(CasAuthenticationToken token) {
     public void putTicketInCache(CasAuthenticationToken token) {
         Element element = new Element(token.getCredentials().toString(), token);
         Element element = new Element(token.getCredentials().toString(), token);
 
 

+ 8 - 37
core/src/main/java/org/acegisecurity/providers/dao/cache/EhCacheBasedUserCache.java

@@ -20,56 +20,40 @@ import net.sf.acegisecurity.providers.dao.UserCache;
 
 
 import net.sf.ehcache.Cache;
 import net.sf.ehcache.Cache;
 import net.sf.ehcache.CacheException;
 import net.sf.ehcache.CacheException;
-import net.sf.ehcache.CacheManager;
 import net.sf.ehcache.Element;
 import net.sf.ehcache.Element;
 
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.commons.logging.LogFactory;
 
 
-import org.springframework.beans.factory.DisposableBean;
 import org.springframework.beans.factory.InitializingBean;
 import org.springframework.beans.factory.InitializingBean;
 
 
 import org.springframework.dao.DataRetrievalFailureException;
 import org.springframework.dao.DataRetrievalFailureException;
 
 
 
 
 /**
 /**
- * Caches <code>User</code> objects using <A
+ * Caches <code>User</code> objects using a Spring IoC defined <A
  * HREF="http://ehcache.sourceforge.net">EHCACHE</a>.
  * HREF="http://ehcache.sourceforge.net">EHCACHE</a>.
  *
  *
  * @author Ben Alex
  * @author Ben Alex
  * @version $Id$
  * @version $Id$
  */
  */
-public class EhCacheBasedUserCache implements UserCache, InitializingBean,
-    DisposableBean {
+public class EhCacheBasedUserCache implements UserCache, InitializingBean {
     //~ Static fields/initializers =============================================
     //~ Static fields/initializers =============================================
 
 
     private static final Log logger = LogFactory.getLog(EhCacheBasedUserCache.class);
     private static final Log logger = LogFactory.getLog(EhCacheBasedUserCache.class);
-    private static final String CACHE_NAME = "ehCacheBasedUserCache";
 
 
     //~ Instance fields ========================================================
     //~ Instance fields ========================================================
 
 
     private Cache cache;
     private Cache cache;
-    private CacheManager manager;
-    private int minutesToIdle = 5;
 
 
     //~ Methods ================================================================
     //~ Methods ================================================================
 
 
-    public void setMinutesToIdle(int minutesToIdle) {
-        this.minutesToIdle = minutesToIdle;
+    public void setCache(Cache cache) {
+        this.cache = cache;
     }
     }
 
 
-    /**
-     * Specifies how many minutes an entry will remain in the cache from when
-     * it was last accessed. This is effectively the session duration.
-     * 
-     * <P>
-     * Defaults to 5 minutes.
-     * </p>
-     *
-     * @return Returns the minutes an element remains in the cache
-     */
-    public int getMinutesToIdle() {
-        return minutesToIdle;
+    public Cache getCache() {
+        return cache;
     }
     }
 
 
     public UserDetails getUserFromCache(String username) {
     public UserDetails getUserFromCache(String username) {
@@ -95,24 +79,11 @@ public class EhCacheBasedUserCache implements UserCache, InitializingBean,
     }
     }
 
 
     public void afterPropertiesSet() throws Exception {
     public void afterPropertiesSet() throws Exception {
-        if (CacheManager.getInstance().cacheExists(CACHE_NAME)) {
-            // don’t remove the cache
-            cache = CacheManager.getInstance().getCache(CACHE_NAME);
-        } else {
-            manager = CacheManager.create();
-
-            // Cache name, max memory, overflowToDisk, eternal, timeToLive, timeToIdle
-            cache = new Cache(CACHE_NAME, Integer.MAX_VALUE, false, false,
-                    minutesToIdle * 60, minutesToIdle * 60);
-
-            manager.addCache(cache);
+        if (cache == null) {
+            throw new IllegalArgumentException("cache mandatory");
         }
         }
     }
     }
 
 
-    public void destroy() throws Exception {
-        manager.removeCache(CACHE_NAME);
-    }
-
     public void putUserInCache(UserDetails user) {
     public void putUserInCache(UserDetails user) {
         Element element = new Element(user.getUsername(), user);
         Element element = new Element(user.getUsername(), user);
 
 

+ 26 - 8
core/src/test/java/org/acegisecurity/acl/basic/cache/EhCacheBasedAclEntryCacheTests.java

@@ -17,11 +17,16 @@ package net.sf.acegisecurity.acl.basic.cache;
 
 
 import junit.framework.TestCase;
 import junit.framework.TestCase;
 
 
+import net.sf.acegisecurity.MockApplicationContext;
 import net.sf.acegisecurity.acl.basic.AclObjectIdentity;
 import net.sf.acegisecurity.acl.basic.AclObjectIdentity;
 import net.sf.acegisecurity.acl.basic.BasicAclEntry;
 import net.sf.acegisecurity.acl.basic.BasicAclEntry;
 import net.sf.acegisecurity.acl.basic.NamedEntityObjectIdentity;
 import net.sf.acegisecurity.acl.basic.NamedEntityObjectIdentity;
 import net.sf.acegisecurity.acl.basic.SimpleAclEntry;
 import net.sf.acegisecurity.acl.basic.SimpleAclEntry;
 
 
+import net.sf.ehcache.Cache;
+
+import org.springframework.context.ApplicationContext;
+
 
 
 /**
 /**
  * Tests {@link EhCacheBasedAclEntryCache}.
  * Tests {@link EhCacheBasedAclEntryCache}.
@@ -65,9 +70,7 @@ public class EhCacheBasedAclEntryCacheTests extends TestCase {
 
 
     public void testCacheOperation() throws Exception {
     public void testCacheOperation() throws Exception {
         EhCacheBasedAclEntryCache cache = new EhCacheBasedAclEntryCache();
         EhCacheBasedAclEntryCache cache = new EhCacheBasedAclEntryCache();
-        cache.afterPropertiesSet();
-
-        // execute a second time to test detection of existing instance
+        cache.setCache(getCache());
         cache.afterPropertiesSet();
         cache.afterPropertiesSet();
 
 
         cache.putEntriesInCache(new BasicAclEntry[] {OBJECT_100_SCOTT, OBJECT_100_MARISSA});
         cache.putEntriesInCache(new BasicAclEntry[] {OBJECT_100_SCOTT, OBJECT_100_MARISSA});
@@ -83,13 +86,28 @@ public class EhCacheBasedAclEntryCacheTests extends TestCase {
         assertEquals(OBJECT_200_PETER,
         assertEquals(OBJECT_200_PETER,
             cache.getEntriesFromCache(
             cache.getEntriesFromCache(
                 new NamedEntityObjectIdentity("OBJECT", "200"))[0]);
                 new NamedEntityObjectIdentity("OBJECT", "200"))[0]);
-
-        cache.destroy();
+        assertNull(cache.getEntriesFromCache(
+                new NamedEntityObjectIdentity("OBJECT", "NOT_IN_CACHE")));
     }
     }
 
 
-    public void testGettersSetters() {
+    public void testStartupDetectsMissingCache() throws Exception {
         EhCacheBasedAclEntryCache cache = new EhCacheBasedAclEntryCache();
         EhCacheBasedAclEntryCache cache = new EhCacheBasedAclEntryCache();
-        cache.setMinutesToIdle(15);
-        assertEquals(15, cache.getMinutesToIdle());
+
+        try {
+            cache.afterPropertiesSet();
+            fail("Should have thrown IllegalArgumentException");
+        } catch (IllegalArgumentException expected) {
+            assertTrue(true);
+        }
+
+        Cache myCache = getCache();
+        cache.setCache(myCache);
+        assertEquals(myCache, cache.getCache());
+    }
+
+    private Cache getCache() {
+        ApplicationContext ctx = MockApplicationContext.getContext();
+
+        return (Cache) ctx.getBean("eHCacheBackend");
     }
     }
 }
 }

+ 24 - 6
core/src/test/java/org/acegisecurity/providers/cas/cache/EhCacheBasedTicketCacheTests.java

@@ -19,9 +19,14 @@ import junit.framework.TestCase;
 
 
 import net.sf.acegisecurity.GrantedAuthority;
 import net.sf.acegisecurity.GrantedAuthority;
 import net.sf.acegisecurity.GrantedAuthorityImpl;
 import net.sf.acegisecurity.GrantedAuthorityImpl;
+import net.sf.acegisecurity.MockApplicationContext;
 import net.sf.acegisecurity.providers.cas.CasAuthenticationToken;
 import net.sf.acegisecurity.providers.cas.CasAuthenticationToken;
 import net.sf.acegisecurity.providers.dao.User;
 import net.sf.acegisecurity.providers.dao.User;
 
 
+import net.sf.ehcache.Cache;
+
+import org.springframework.context.ApplicationContext;
+
 import java.util.List;
 import java.util.List;
 import java.util.Vector;
 import java.util.Vector;
 
 
@@ -55,8 +60,8 @@ public class EhCacheBasedTicketCacheTests extends TestCase {
 
 
     public void testCacheOperation() throws Exception {
     public void testCacheOperation() throws Exception {
         EhCacheBasedTicketCache cache = new EhCacheBasedTicketCache();
         EhCacheBasedTicketCache cache = new EhCacheBasedTicketCache();
+        cache.setCache(getCache());
         cache.afterPropertiesSet();
         cache.afterPropertiesSet();
-        cache.afterPropertiesSet(); // second run for test coverage
 
 
         // Check it gets stored in the cache
         // Check it gets stored in the cache
         cache.putTicketInCache(getToken());
         cache.putTicketInCache(getToken());
@@ -70,14 +75,27 @@ public class EhCacheBasedTicketCacheTests extends TestCase {
         // Check it doesn't return values for null or unknown service tickets
         // Check it doesn't return values for null or unknown service tickets
         assertNull(cache.getByTicketId(null));
         assertNull(cache.getByTicketId(null));
         assertNull(cache.getByTicketId("UNKNOWN_SERVICE_TICKET"));
         assertNull(cache.getByTicketId("UNKNOWN_SERVICE_TICKET"));
-
-        cache.destroy();
     }
     }
 
 
-    public void testGettersSetters() {
+    public void testStartupDetectsMissingCache() throws Exception {
         EhCacheBasedTicketCache cache = new EhCacheBasedTicketCache();
         EhCacheBasedTicketCache cache = new EhCacheBasedTicketCache();
-        cache.setMinutesToIdle(5);
-        assertEquals(5, cache.getMinutesToIdle());
+
+        try {
+            cache.afterPropertiesSet();
+            fail("Should have thrown IllegalArgumentException");
+        } catch (IllegalArgumentException expected) {
+            assertTrue(true);
+        }
+
+        Cache myCache = getCache();
+        cache.setCache(myCache);
+        assertEquals(myCache, cache.getCache());
+    }
+
+    private Cache getCache() {
+        ApplicationContext ctx = MockApplicationContext.getContext();
+
+        return (Cache) ctx.getBean("eHCacheBackend");
     }
     }
 
 
     private CasAuthenticationToken getToken() {
     private CasAuthenticationToken getToken() {

+ 24 - 5
core/src/test/java/org/acegisecurity/providers/dao/cache/EhCacheBasedUserCacheTests.java

@@ -19,8 +19,13 @@ import junit.framework.TestCase;
 
 
 import net.sf.acegisecurity.GrantedAuthority;
 import net.sf.acegisecurity.GrantedAuthority;
 import net.sf.acegisecurity.GrantedAuthorityImpl;
 import net.sf.acegisecurity.GrantedAuthorityImpl;
+import net.sf.acegisecurity.MockApplicationContext;
 import net.sf.acegisecurity.providers.dao.User;
 import net.sf.acegisecurity.providers.dao.User;
 
 
+import net.sf.ehcache.Cache;
+
+import org.springframework.context.ApplicationContext;
+
 
 
 /**
 /**
  * Tests {@link EhCacheBasedUserCache}.
  * Tests {@link EhCacheBasedUserCache}.
@@ -51,6 +56,7 @@ public class EhCacheBasedUserCacheTests extends TestCase {
 
 
     public void testCacheOperation() throws Exception {
     public void testCacheOperation() throws Exception {
         EhCacheBasedUserCache cache = new EhCacheBasedUserCache();
         EhCacheBasedUserCache cache = new EhCacheBasedUserCache();
+        cache.setCache(getCache());
         cache.afterPropertiesSet();
         cache.afterPropertiesSet();
 
 
         // Check it gets stored in the cache
         // Check it gets stored in the cache
@@ -65,14 +71,27 @@ public class EhCacheBasedUserCacheTests extends TestCase {
         // Check it doesn't return values for null or unknown users
         // Check it doesn't return values for null or unknown users
         assertNull(cache.getUserFromCache(null));
         assertNull(cache.getUserFromCache(null));
         assertNull(cache.getUserFromCache("UNKNOWN_USER"));
         assertNull(cache.getUserFromCache("UNKNOWN_USER"));
-
-        cache.destroy();
     }
     }
 
 
-    public void testGettersSetters() {
+    public void testStartupDetectsMissingCache() throws Exception {
         EhCacheBasedUserCache cache = new EhCacheBasedUserCache();
         EhCacheBasedUserCache cache = new EhCacheBasedUserCache();
-        cache.setMinutesToIdle(15);
-        assertEquals(15, cache.getMinutesToIdle());
+
+        try {
+            cache.afterPropertiesSet();
+            fail("Should have thrown IllegalArgumentException");
+        } catch (IllegalArgumentException expected) {
+            assertTrue(true);
+        }
+
+        Cache myCache = getCache();
+        cache.setCache(myCache);
+        assertEquals(myCache, cache.getCache());
+    }
+
+    private Cache getCache() {
+        ApplicationContext ctx = MockApplicationContext.getContext();
+
+        return (Cache) ctx.getBean("eHCacheBackend");
     }
     }
 
 
     private User getUser() {
     private User getUser() {

+ 14 - 0
core/src/test/resources/org/acegisecurity/applicationContext.xml

@@ -26,4 +26,18 @@
    <!-- Automatically receives AuthenticationEvent messages from AbstractSecurityInterceptor -->
    <!-- Automatically receives AuthenticationEvent messages from AbstractSecurityInterceptor -->
    <bean id="secureObjectLoggerListener" class="net.sf.acegisecurity.intercept.event.LoggerListener"/>
    <bean id="secureObjectLoggerListener" class="net.sf.acegisecurity.intercept.event.LoggerListener"/>
 
 
+   <!-- Setup a cache we can use in tests of the caching layer -->
+   <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
+   </bean>  
+
+   <bean id="eHCacheBackend" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
+      <property name="cacheManager">
+         <ref local="cacheManager"/>
+      </property>
+      <property name="cacheName">
+         <value>testingCache</value>
+      </property>
+   </bean>
+
+
 </beans>
 </beans>

+ 36 - 24
doc/docbook/index.xml

@@ -110,36 +110,17 @@
         release. These are:</para>
         release. These are:</para>
 
 
         <itemizedlist spacing="compact">
         <itemizedlist spacing="compact">
-          <listitem>
-            <para>Replacing the Ant build with a Maven build. When this
-            happens the <literal>lib</literal> directory will no longer be
-            distributed in ZIP releases or hosted in CVS.</para>
-          </listitem>
-
           <listitem>
           <listitem>
             <para>"Remember me" functionality. Some discussion on this can be
             <para>"Remember me" functionality. Some discussion on this can be
             found at
             found at
             <literal>http://sourceforge.net/mailarchive/forum.php?thread_id=5177499&amp;forum_id=40659</literal>.</para>
             <literal>http://sourceforge.net/mailarchive/forum.php?thread_id=5177499&amp;forum_id=40659</literal>.</para>
           </listitem>
           </listitem>
 
 
-          <listitem>
-            <para>A sample web application which demonstrates the access
-            control list package.</para>
-          </listitem>
-
           <listitem>
           <listitem>
             <para>Implementation of an
             <para>Implementation of an
             <literal>ObjectDefinitionSource</literal> that retrieves its
             <literal>ObjectDefinitionSource</literal> that retrieves its
             details from a database.</para>
             details from a database.</para>
           </listitem>
           </listitem>
-
-          <listitem>
-            <para>Deprecation of Acegi Security's various EH-CACHE-based cache
-            implementations. Instead Acegi Security will provide new cache
-            implementations which use Spring Framework's new (currently in
-            CVS) <literal>EhCacheManagerFactoryBean</literal> factory. The
-            deprecated classes may be removed from the 1.0.0 release.</para>
-          </listitem>
         </itemizedlist>
         </itemizedlist>
 
 
         <para>Whilst this list is subject to change and not in any particular
         <para>Whilst this list is subject to change and not in any particular
@@ -982,7 +963,7 @@ public aspect DomainObjectInstanceSecurityAspect implements InitializingBean {
         authorities that have been granted to the principal. The principal and
         authorities that have been granted to the principal. The principal and
         its credentials are populated by the client code, whilst the granted
         its credentials are populated by the client code, whilst the granted
         authorities are populated by the
         authorities are populated by the
-        <literal>AuthenticationManager</literal>. </para>
+        <literal>AuthenticationManager</literal>.</para>
 
 
         <para><mediaobject>
         <para><mediaobject>
             <imageobject role="html">
             <imageobject role="html">
@@ -1232,10 +1213,30 @@ public aspect DomainObjectInstanceSecurityAspect implements InitializingBean {
   &lt;property name="userCache"&gt;&lt;ref bean="userCache"/&gt;&lt;/property&gt;
   &lt;property name="userCache"&gt;&lt;ref bean="userCache"/&gt;&lt;/property&gt;
 &lt;/bean&gt;
 &lt;/bean&gt;
 
 
+&lt;bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/&gt;
+    
+&lt;bean id="userCacheBackend" class="org.springframework.cache.ehcache.EhCacheFactoryBean"&gt;
+  &lt;property name="cacheManager"&gt;
+    &lt;ref local="cacheManager"/&gt;
+  &lt;/property&gt;
+  &lt;property name="cacheName"&gt;
+    &lt;value&gt;userCache&lt;/value&gt;
+  &lt;/property&gt;
+&lt;/bean&gt;
+   
 &lt;bean id="userCache" class="net.sf.acegisecurity.providers.dao.cache.EhCacheBasedUserCache"&gt;
 &lt;bean id="userCache" class="net.sf.acegisecurity.providers.dao.cache.EhCacheBasedUserCache"&gt;
-  &lt;property name="minutesToIdle"&gt;&lt;value&gt;5&lt;/value&gt;&lt;/property&gt;
+  &lt;property name="cache"&gt;&lt;ref local="userCacheBackend"/&gt;&lt;/property&gt;
 &lt;/bean&gt;</programlisting></para>
 &lt;/bean&gt;</programlisting></para>
 
 
+        <para>All Acegi Security EH-CACHE implementations (including
+        <literal>EhCacheBasedUserCache</literal>) require an EH-CACHE
+        <literal>Cache</literal> object. The <literal>Cache</literal> object
+        can be obtained from wherever you like, although we recommend you use
+        Spring's factory classes as shown in the above configuration. If using
+        Spring's factory classes, please refer to the Spring documentation for
+        further details on how to optimise the cache storage location, memory
+        usage, eviction policies, timeouts etc.</para>
+
         <para>For a class to be able to provide the
         <para>For a class to be able to provide the
         <literal>DaoAuthenticationProvider</literal> with access to an
         <literal>DaoAuthenticationProvider</literal> with access to an
         authentication repository, it must implement the
         authentication repository, it must implement the
@@ -3415,8 +3416,19 @@ $CATALINA_HOME/bin/startup.sh</programlisting></para>
   &lt;!-- &lt;property name="trustStore"&gt;&lt;value&gt;/some/path/to/your/lib/security/cacerts&lt;/value&gt;&lt;/property&gt; --&gt;
   &lt;!-- &lt;property name="trustStore"&gt;&lt;value&gt;/some/path/to/your/lib/security/cacerts&lt;/value&gt;&lt;/property&gt; --&gt;
 &lt;/bean&gt;
 &lt;/bean&gt;
 
 
+&lt;bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/&gt;
+    
+&lt;bean id="ticketCacheBackend" class="org.springframework.cache.ehcache.EhCacheFactoryBean"&gt;
+  &lt;property name="cacheManager"&gt;
+    &lt;ref local="cacheManager"/&gt;
+  &lt;/property&gt;
+  &lt;property name="cacheName"&gt;
+    &lt;value&gt;ticketCache&lt;/value&gt;
+  &lt;/property&gt;
+&lt;/bean&gt;
+   
 &lt;bean id="statelessTicketCache" class="net.sf.acegisecurity.providers.cas.cache.EhCacheBasedTicketCache"&gt;
 &lt;bean id="statelessTicketCache" class="net.sf.acegisecurity.providers.cas.cache.EhCacheBasedTicketCache"&gt;
-  &lt;property name="minutesToIdle"&gt;&lt;value&gt;20&lt;/value&gt;&lt;/property&gt;
+  &lt;property name="cache"&gt;&lt;ref local="ticketCacheBackend"/&gt;&lt;/property&gt;
 &lt;/bean&gt;
 &lt;/bean&gt;
 
 
 &lt;bean id="casAuthoritiesPopulator" class="net.sf.acegisecurity.providers.cas.populator.DaoCasAuthoritiesPopulator"&gt;
 &lt;bean id="casAuthoritiesPopulator" class="net.sf.acegisecurity.providers.cas.populator.DaoCasAuthoritiesPopulator"&gt;
@@ -3785,7 +3797,7 @@ $CATALINA_HOME/bin/startup.sh</programlisting></para>
         <para>The <literal>net.sf.acegisecurity.acl</literal> package is very
         <para>The <literal>net.sf.acegisecurity.acl</literal> package is very
         simple, comprising only a handful of interfaces and a single class, as
         simple, comprising only a handful of interfaces and a single class, as
         shown in Figure 5. It provides the basic foundation for access control
         shown in Figure 5. It provides the basic foundation for access control
-        list (ACL) lookups. </para>
+        list (ACL) lookups.</para>
 
 
         <para><mediaobject>
         <para><mediaobject>
             <imageobject role="html">
             <imageobject role="html">
@@ -3847,7 +3859,7 @@ public AclEntry[] getAcls(java.lang.Object domainInstance, Authentication authen
         <title>Integer Masked ACLs</title>
         <title>Integer Masked ACLs</title>
 
 
         <para>Acegi Security System for Spring includes a production-quality
         <para>Acegi Security System for Spring includes a production-quality
-        ACL provider implementation, which is shown in Figure 6. </para>
+        ACL provider implementation, which is shown in Figure 6.</para>
 
 
         <para><mediaobject>
         <para><mediaobject>
             <imageobject role="html">
             <imageobject role="html">

+ 1 - 0
doc/xdocs/changes.xml

@@ -49,6 +49,7 @@
       <action dev="benalex" type="update">Improved performance of JBoss container adapter (see reference docs)</action>
       <action dev="benalex" type="update">Improved performance of JBoss container adapter (see reference docs)</action>
       <action dev="benalex" type="update">Made DaoAuthenticationProvider detect null in Authentication.principal</action>
       <action dev="benalex" type="update">Made DaoAuthenticationProvider detect null in Authentication.principal</action>
       <action dev="benalex" type="update">Improved JaasAuthenticationProvider startup error detection</action>
       <action dev="benalex" type="update">Improved JaasAuthenticationProvider startup error detection</action>
+      <action dev="benalex" type="update">Refactored EH-CACHE implementations to use Spring IoC defined caches instead</action>
       <action dev="benalex" type="fix">Fixed AbstractProcessingFilter to use removeAttribute (JRun compatibility)</action>
       <action dev="benalex" type="fix">Fixed AbstractProcessingFilter to use removeAttribute (JRun compatibility)</action>
       <action dev="benalex" type="fix">Fixed GrantedAuthorityEffectiveAclResolver support of UserDetails principals</action>
       <action dev="benalex" type="fix">Fixed GrantedAuthorityEffectiveAclResolver support of UserDetails principals</action>
       <action dev="benalex" type="update">Moved MethodSecurityInterceptor to ...intercept.method.aopalliance package</action>
       <action dev="benalex" type="update">Moved MethodSecurityInterceptor to ...intercept.method.aopalliance package</action>

+ 9 - 0
doc/xdocs/upgrade/upgrade-06-07.html

@@ -34,6 +34,15 @@ applications:
   net.sf.acegisecurity.intercept.method.MethodSecurityInterceptor to
   net.sf.acegisecurity.intercept.method.MethodSecurityInterceptor to
   net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor.
   net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor.
   A simple find and replace will suffice to update your application contexts.</li>
   A simple find and replace will suffice to update your application contexts.</li>
+
+<li>All of the EH-CACHE cache implementations provided with Acegi Security have
+	now been refactored to use a net.sf.ehcache.Cache obtained from
+	EhCacheManagerFactoryBean, which is included with Spring 1.1.1 and above.
+	See http://opensource.atlassian.com/confluence/spring/display/DISC/Caching+the+result+of+methods+using+Spring+and+EHCache
+	for more about this bean, or the Contacts sample application for how to
+	configure the EH-CACHE implementations provided with Acegi Security.
+	Note the "cache" property is now required, and the old internally-managed
+	cache properties have been removed.</li>
 </ul>
 </ul>
 </body>
 </body>
 </html>
 </html>

+ 12 - 1
samples/contacts/src/main/webapp/cas/WEB-INF/applicationContext-acegi-security.xml

@@ -52,8 +52,19 @@
         <!-- <property name="trustStore"><value>/some/path/to/your/lib/security/cacerts</value></property> -->
         <!-- <property name="trustStore"><value>/some/path/to/your/lib/security/cacerts</value></property> -->
 	</bean>
 	</bean>
 
 
+    <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>
+    
+    <bean id="ticketCacheBackend" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
+       <property name="cacheManager">
+          <ref local="cacheManager"/>
+       </property>
+       <property name="cacheName">
+          <value>ticketCache</value>
+       </property>
+    </bean>
+   
 	<bean id="statelessTicketCache" class="net.sf.acegisecurity.providers.cas.cache.EhCacheBasedTicketCache">
 	<bean id="statelessTicketCache" class="net.sf.acegisecurity.providers.cas.cache.EhCacheBasedTicketCache">
-		<property name="minutesToIdle"><value>20</value></property>
+      <property name="cache"><ref local="ticketCacheBackend"/></property>
 	</bean>
 	</bean>
 
 
 	<bean id="casAuthoritiesPopulator" class="net.sf.acegisecurity.providers.cas.populator.DaoCasAuthoritiesPopulator">
 	<bean id="casAuthoritiesPopulator" class="net.sf.acegisecurity.providers.cas.populator.DaoCasAuthoritiesPopulator">

+ 12 - 1
samples/contacts/src/main/webapp/filter/WEB-INF/applicationContext-acegi-security.xml

@@ -34,8 +34,19 @@
       <property name="passwordEncoder"><ref local="passwordEncoder"/></property>
       <property name="passwordEncoder"><ref local="passwordEncoder"/></property>
    </bean>
    </bean>
 
 
+   <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>
+    
+   <bean id="userCacheBackend" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
+      <property name="cacheManager">
+         <ref local="cacheManager"/>
+      </property>
+      <property name="cacheName">
+         <value>userCache</value>
+      </property>
+   </bean>
+   
    <bean id="userCache" class="net.sf.acegisecurity.providers.dao.cache.EhCacheBasedUserCache">
    <bean id="userCache" class="net.sf.acegisecurity.providers.dao.cache.EhCacheBasedUserCache">
-      <property name="minutesToIdle"><value>5</value></property>
+      <property name="cache"><ref local="userCacheBackend"/></property>
    </bean>
    </bean>
 
 
    <!-- Automatically receives AuthenticationEvent messages from DaoAuthenticationProvider -->
    <!-- Automatically receives AuthenticationEvent messages from DaoAuthenticationProvider -->