diff --git a/core/src/main/java/org/acegisecurity/acl/basic/BasicAclEntryCache.java b/core/src/main/java/org/acegisecurity/acl/basic/BasicAclEntryCache.java index e6c6d1cd3c..1302d45996 100644 --- a/core/src/main/java/org/acegisecurity/acl/basic/BasicAclEntryCache.java +++ b/core/src/main/java/org/acegisecurity/acl/basic/BasicAclEntryCache.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -58,4 +58,12 @@ public interface BasicAclEntryCache { * from the {@link BasicAclEntry#getAclObjectIdentity()} method */ public void putEntriesInCache(BasicAclEntry[] basicAclEntry); + + /** + * Removes all ACL entries related to an {@link AclObjectIdentity} from the + * cache. + * + * @param aclObjectIdentity which should be removed from the cache + */ + public void removeEntriesFromCache(AclObjectIdentity aclObjectIdentity); } diff --git a/core/src/main/java/org/acegisecurity/acl/basic/cache/EhCacheBasedAclEntryCache.java b/core/src/main/java/org/acegisecurity/acl/basic/cache/EhCacheBasedAclEntryCache.java index 8e8bcf75df..dbc2996dc6 100644 --- a/core/src/main/java/org/acegisecurity/acl/basic/cache/EhCacheBasedAclEntryCache.java +++ b/core/src/main/java/org/acegisecurity/acl/basic/cache/EhCacheBasedAclEntryCache.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,20 +15,21 @@ package org.acegisecurity.acl.basic.cache; -import org.acegisecurity.acl.basic.AclObjectIdentity; -import org.acegisecurity.acl.basic.BasicAclEntry; -import org.acegisecurity.acl.basic.BasicAclEntryCache; - import net.sf.ehcache.Cache; import net.sf.ehcache.CacheException; import net.sf.ehcache.Element; +import org.acegisecurity.acl.basic.AclObjectIdentity; +import org.acegisecurity.acl.basic.BasicAclEntry; +import org.acegisecurity.acl.basic.BasicAclEntryCache; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.InitializingBean; import org.springframework.dao.DataRetrievalFailureException; + import org.springframework.util.Assert; @@ -51,8 +52,8 @@ public class EhCacheBasedAclEntryCache implements BasicAclEntryCache, //~ Methods ================================================================ - public void setCache(Cache cache) { - this.cache = cache; + public void afterPropertiesSet() throws Exception { + Assert.notNull(cache, "cache mandatory"); } public Cache getCache() { @@ -89,10 +90,6 @@ public class EhCacheBasedAclEntryCache implements BasicAclEntryCache, return holder.getBasicAclEntries(); } - public void afterPropertiesSet() throws Exception { - Assert.notNull(cache, "cache mandatory"); - } - public void putEntriesInCache(BasicAclEntry[] basicAclEntry) { BasicAclEntryHolder holder = new BasicAclEntryHolder(basicAclEntry); Element element = new Element(basicAclEntry[0].getAclObjectIdentity(), @@ -104,4 +101,12 @@ public class EhCacheBasedAclEntryCache implements BasicAclEntryCache, cache.put(element); } + + public void removeEntriesFromCache(AclObjectIdentity aclObjectIdentity) { + cache.remove(aclObjectIdentity); + } + + public void setCache(Cache cache) { + this.cache = cache; + } } diff --git a/core/src/main/java/org/acegisecurity/acl/basic/cache/NullAclEntryCache.java b/core/src/main/java/org/acegisecurity/acl/basic/cache/NullAclEntryCache.java index c95f90bac0..50f8b09356 100644 --- a/core/src/main/java/org/acegisecurity/acl/basic/cache/NullAclEntryCache.java +++ b/core/src/main/java/org/acegisecurity/acl/basic/cache/NullAclEntryCache.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -53,4 +53,11 @@ public class NullAclEntryCache implements BasicAclEntryCache { * @param basicAclEntry ignored */ public void putEntriesInCache(BasicAclEntry[] basicAclEntry) {} + + /** + * Meets method signature but doesn't remove from cache. + * + * @param aclObjectIdentity ignored + */ + public void removeEntriesFromCache(AclObjectIdentity aclObjectIdentity) {} } diff --git a/core/src/main/java/org/acegisecurity/acl/basic/jdbc/JdbcExtendedDaoImpl.java b/core/src/main/java/org/acegisecurity/acl/basic/jdbc/JdbcExtendedDaoImpl.java index cedb3cffcb..c4af3bade6 100644 --- a/core/src/main/java/org/acegisecurity/acl/basic/jdbc/JdbcExtendedDaoImpl.java +++ b/core/src/main/java/org/acegisecurity/acl/basic/jdbc/JdbcExtendedDaoImpl.java @@ -17,7 +17,9 @@ package org.acegisecurity.acl.basic.jdbc; import org.acegisecurity.acl.basic.AclObjectIdentity; import org.acegisecurity.acl.basic.BasicAclEntry; +import org.acegisecurity.acl.basic.BasicAclEntryCache; import org.acegisecurity.acl.basic.BasicAclExtendedDao; +import org.acegisecurity.acl.basic.cache.NullAclEntryCache; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -32,6 +34,8 @@ import org.springframework.jdbc.core.SqlParameter; import org.springframework.jdbc.object.MappingSqlQuery; import org.springframework.jdbc.object.SqlUpdate; +import org.springframework.util.Assert; + import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; @@ -54,6 +58,13 @@ import javax.sql.DataSource; *
* *
+ * If you are using a cache with BasicAclProvider
, you should
+ * specify that cache via {@link #setBasicAclEntryCache(BasicAclEntryCache)}.
+ * This will cause cache evictions (removals) to take place whenever a DAO
+ * mutator method is called.
+ *
* This implementation works with String
based recipients and
* {@link org.acegisecurity.acl.basic.NamedEntityObjectIdentity} only. The
* latter can be changed by overriding {@link
@@ -82,6 +93,7 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl
private AclPermissionDelete aclPermissionDelete;
private AclPermissionInsert aclPermissionInsert;
private AclPermissionUpdate aclPermissionUpdate;
+ private BasicAclEntryCache basicAclEntryCache = new NullAclEntryCache();
private MappingSqlQuery lookupPermissionIdMapping;
private String aclObjectIdentityDeleteStatement;
private String aclObjectIdentityInsertStatement;
@@ -105,6 +117,8 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl
public void changeMask(AclObjectIdentity aclObjectIdentity,
Object recipient, Integer newMask) throws DataAccessException {
+ basicAclEntryCache.removeEntriesFromCache(aclObjectIdentity);
+
// Retrieve acl_object_identity record details
AclDetailsHolder aclDetailsHolder = lookupAclDetailsHolder(aclObjectIdentity);
@@ -164,6 +178,9 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl
*/
private void createAclObjectIdentityIfRequired(BasicAclEntry basicAclEntry)
throws DataAccessException {
+ basicAclEntryCache.removeEntriesFromCache(basicAclEntry
+ .getAclObjectIdentity());
+
String aclObjectIdentityString = convertAclObjectIdentityToString(basicAclEntry
.getAclObjectIdentity());
@@ -189,6 +206,8 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl
public void delete(AclObjectIdentity aclObjectIdentity)
throws DataAccessException {
+ basicAclEntryCache.removeEntriesFromCache(aclObjectIdentity);
+
// Retrieve acl_object_identity record details
AclDetailsHolder aclDetailsHolder = lookupAclDetailsHolder(aclObjectIdentity);
@@ -209,6 +228,8 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl
public void delete(AclObjectIdentity aclObjectIdentity, Object recipient)
throws DataAccessException {
+ basicAclEntryCache.removeEntriesFromCache(aclObjectIdentity);
+
// Retrieve acl_object_identity record details
AclDetailsHolder aclDetailsHolder = lookupAclDetailsHolder(aclObjectIdentity);
@@ -257,6 +278,10 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl
return aclPermissionUpdateStatement;
}
+ public BasicAclEntryCache getBasicAclEntryCache() {
+ return basicAclEntryCache;
+ }
+
public MappingSqlQuery getLookupPermissionIdMapping() {
return lookupPermissionIdMapping;
}
@@ -371,6 +396,11 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl
this.aclPermissionUpdateStatement = aclPermissionUpdateStatement;
}
+ public void setBasicAclEntryCache(BasicAclEntryCache basicAclEntryCache) {
+ Assert.notNull(basicAclEntryCache, "Cache cannot be set to null");
+ this.basicAclEntryCache = basicAclEntryCache;
+ }
+
public void setLookupPermissionIdMapping(
MappingSqlQuery lookupPermissionIdMapping) {
this.lookupPermissionIdMapping = lookupPermissionIdMapping;
diff --git a/core/src/test/java/org/acegisecurity/acl/basic/BasicAclProviderTests.java b/core/src/test/java/org/acegisecurity/acl/basic/BasicAclProviderTests.java
index 1395492501..024e17e540 100644
--- a/core/src/test/java/org/acegisecurity/acl/basic/BasicAclProviderTests.java
+++ b/core/src/test/java/org/acegisecurity/acl/basic/BasicAclProviderTests.java
@@ -1,4 +1,4 @@
-/* Copyright 2004, 2005 Acegi Technology Pty Limited
+/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,10 +19,12 @@ import junit.framework.TestCase;
import org.acegisecurity.Authentication;
import org.acegisecurity.PopulatedDatabase;
+
import org.acegisecurity.acl.AclEntry;
import org.acegisecurity.acl.basic.cache.BasicAclEntryHolder;
import org.acegisecurity.acl.basic.cache.NullAclEntryCache;
import org.acegisecurity.acl.basic.jdbc.JdbcDaoImpl;
+
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import java.util.HashMap;
@@ -52,14 +54,22 @@ public class BasicAclProviderTests extends TestCase {
//~ Methods ================================================================
- public final void setUp() throws Exception {
- super.setUp();
- }
-
public static void main(String[] args) {
junit.textui.TestRunner.run(BasicAclProviderTests.class);
}
+ private JdbcDaoImpl makePopulatedJdbcDao() throws Exception {
+ JdbcDaoImpl dao = new JdbcDaoImpl();
+ dao.setDataSource(PopulatedDatabase.getDataSource());
+ dao.afterPropertiesSet();
+
+ return dao;
+ }
+
+ public final void setUp() throws Exception {
+ super.setUp();
+ }
+
public void testCachingUsedProperly() throws Exception {
BasicAclProvider provider = new BasicAclProvider();
provider.setBasicAclDao(makePopulatedJdbcDao());
@@ -316,14 +326,6 @@ public class BasicAclProviderTests extends TestCase {
assertFalse(provider.supports(new Integer(34)));
}
- private JdbcDaoImpl makePopulatedJdbcDao() throws Exception {
- JdbcDaoImpl dao = new JdbcDaoImpl();
- dao.setDataSource(PopulatedDatabase.getDataSource());
- dao.afterPropertiesSet();
-
- return dao;
- }
-
//~ Inner Classes ==========================================================
private class MockCache implements BasicAclEntryCache {
@@ -371,6 +373,8 @@ public class BasicAclProviderTests extends TestCase {
BasicAclEntryHolder holder = new BasicAclEntryHolder(basicAclEntry);
map.put(basicAclEntry[0].getAclObjectIdentity(), holder);
}
+
+ public void removeEntriesFromCache(AclObjectIdentity aclObjectIdentity) {}
}
private class MockDao implements BasicAclDao {
diff --git a/core/src/test/java/org/acegisecurity/acl/basic/cache/EhCacheBasedAclEntryCacheTests.java b/core/src/test/java/org/acegisecurity/acl/basic/cache/EhCacheBasedAclEntryCacheTests.java
index f87e78cbdd..a2bb707621 100644
--- a/core/src/test/java/org/acegisecurity/acl/basic/cache/EhCacheBasedAclEntryCacheTests.java
+++ b/core/src/test/java/org/acegisecurity/acl/basic/cache/EhCacheBasedAclEntryCacheTests.java
@@ -1,4 +1,4 @@
-/* Copyright 2004 Acegi Technology Pty Limited
+/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,14 +17,15 @@ package org.acegisecurity.acl.basic.cache;
import junit.framework.TestCase;
+import net.sf.ehcache.Cache;
+
import org.acegisecurity.MockApplicationContext;
+
import org.acegisecurity.acl.basic.AclObjectIdentity;
import org.acegisecurity.acl.basic.BasicAclEntry;
import org.acegisecurity.acl.basic.NamedEntityObjectIdentity;
import org.acegisecurity.acl.basic.SimpleAclEntry;
-import net.sf.ehcache.Cache;
-
import org.springframework.context.ApplicationContext;
@@ -60,14 +61,20 @@ public class EhCacheBasedAclEntryCacheTests extends TestCase {
//~ Methods ================================================================
- public final void setUp() throws Exception {
- super.setUp();
+ private Cache getCache() {
+ ApplicationContext ctx = MockApplicationContext.getContext();
+
+ return (Cache) ctx.getBean("eHCacheBackend");
}
public static void main(String[] args) {
junit.textui.TestRunner.run(EhCacheBasedAclEntryCacheTests.class);
}
+ public final void setUp() throws Exception {
+ super.setUp();
+ }
+
public void testCacheOperation() throws Exception {
EhCacheBasedAclEntryCache cache = new EhCacheBasedAclEntryCache();
cache.setCache(getCache());
@@ -88,6 +95,12 @@ public class EhCacheBasedAclEntryCacheTests extends TestCase {
new NamedEntityObjectIdentity("OBJECT", "200"))[0]);
assertNull(cache.getEntriesFromCache(
new NamedEntityObjectIdentity("OBJECT", "NOT_IN_CACHE")));
+
+ // Check after eviction we cannot get them from cache
+ cache.removeEntriesFromCache(new NamedEntityObjectIdentity("OBJECT",
+ "100"));
+ assertNull(cache.getEntriesFromCache(
+ new NamedEntityObjectIdentity("OBJECT", "100")));
}
public void testStartupDetectsMissingCache() throws Exception {
@@ -104,10 +117,4 @@ public class EhCacheBasedAclEntryCacheTests extends TestCase {
cache.setCache(myCache);
assertEquals(myCache, cache.getCache());
}
-
- private Cache getCache() {
- ApplicationContext ctx = MockApplicationContext.getContext();
-
- return (Cache) ctx.getBean("eHCacheBackend");
- }
}
diff --git a/core/src/test/java/org/acegisecurity/acl/basic/cache/NullAclEntryCacheTests.java b/core/src/test/java/org/acegisecurity/acl/basic/cache/NullAclEntryCacheTests.java
index 507f4ff4b4..41fc145f00 100644
--- a/core/src/test/java/org/acegisecurity/acl/basic/cache/NullAclEntryCacheTests.java
+++ b/core/src/test/java/org/acegisecurity/acl/basic/cache/NullAclEntryCacheTests.java
@@ -1,4 +1,4 @@
-/* Copyright 2004 Acegi Technology Pty Limited
+/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -41,18 +41,20 @@ public class NullAclEntryCacheTests extends TestCase {
//~ Methods ================================================================
- public final void setUp() throws Exception {
- super.setUp();
- }
-
public static void main(String[] args) {
junit.textui.TestRunner.run(NullAclEntryCacheTests.class);
}
+ public final void setUp() throws Exception {
+ super.setUp();
+ }
+
public void testCacheOperation() throws Exception {
NullAclEntryCache cache = new NullAclEntryCache();
cache.putEntriesInCache(new BasicAclEntry[] {new SimpleAclEntry()});
cache.getEntriesFromCache(new NamedEntityObjectIdentity("not_used",
"not_used"));
+ cache.removeEntriesFromCache(new NamedEntityObjectIdentity("not_used",
+ "not_used"));
}
}