diff --git a/build.gradle b/build.gradle index 8d02ac6ffeb..79cd71bc087 100644 --- a/build.gradle +++ b/build.gradle @@ -269,8 +269,6 @@ project('spring-context') { } compile("joda-time:joda-time:1.6", optional) compile("org.jruby:jruby:1.4.0", optional) - compile("javax.cache:cache-api:0.5", optional) - compile("net.sf.ehcache:ehcache-core:2.0.0", optional) compile("org.slf4j:slf4j-api:1.6.1", optional) compile("org.codehaus.jsr166-mirror:jsr166:1.7.0", provided) compile("org.aspectj:aspectjweaver:${aspectjVersion}", optional) @@ -361,6 +359,8 @@ project('spring-context-support') { compile(project(":spring-jdbc"), optional) // for Quartz support compile(project(":spring-tx"), optional) // for Quartz support compile("org.codehaus.fabric3.api:commonj:1.1.0", optional) + compile("javax.cache:cache-api:0.5", optional) + compile("net.sf.ehcache:ehcache-core:2.0.0", optional) compile("opensymphony:quartz:1.6.2", optional) compile("javax.mail:mail:1.4", optional) compile("velocity:velocity:1.5", optional) diff --git a/spring-context/src/main/java/org/springframework/cache/ehcache/EhCacheCache.java b/spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheCache.java similarity index 100% rename from spring-context/src/main/java/org/springframework/cache/ehcache/EhCacheCache.java rename to spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheCache.java diff --git a/spring-context/src/main/java/org/springframework/cache/ehcache/EhCacheCacheManager.java b/spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheCacheManager.java similarity index 79% rename from spring-context/src/main/java/org/springframework/cache/ehcache/EhCacheCacheManager.java rename to spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheCacheManager.java index edfa43bfa58..80ca887b9c3 100644 --- a/spring-context/src/main/java/org/springframework/cache/ehcache/EhCacheCacheManager.java +++ b/spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheCacheManager.java @@ -23,7 +23,7 @@ import net.sf.ehcache.Ehcache; import net.sf.ehcache.Status; import org.springframework.cache.Cache; -import org.springframework.cache.support.AbstractCacheManager; +import org.springframework.cache.transaction.AbstractTransactionSupportingCacheManager; import org.springframework.util.Assert; /** @@ -33,11 +33,27 @@ import org.springframework.util.Assert; * @author Juergen Hoeller * @since 3.1 */ -public class EhCacheCacheManager extends AbstractCacheManager { +public class EhCacheCacheManager extends AbstractTransactionSupportingCacheManager { private net.sf.ehcache.CacheManager cacheManager; + /** + * Create a new EhCacheCacheManager, setting the target EhCache CacheManager + * through the {@link #setCacheManager} bean property. + */ + public EhCacheCacheManager() { + } + + /** + * Create a new EhCacheCacheManager for the given backing EhCache. + * @param cacheManager the backing EhCache {@link net.sf.ehcache.CacheManager} + */ + public EhCacheCacheManager(net.sf.ehcache.CacheManager cacheManager) { + this.cacheManager = cacheManager; + } + + /** * Set the backing EhCache {@link net.sf.ehcache.CacheManager}. */ diff --git a/spring-context/src/main/java/org/springframework/cache/ehcache/EhCacheFactoryBean.java b/spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheFactoryBean.java similarity index 100% rename from spring-context/src/main/java/org/springframework/cache/ehcache/EhCacheFactoryBean.java rename to spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheFactoryBean.java diff --git a/spring-context/src/main/java/org/springframework/cache/ehcache/EhCacheManagerFactoryBean.java b/spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheManagerFactoryBean.java similarity index 100% rename from spring-context/src/main/java/org/springframework/cache/ehcache/EhCacheManagerFactoryBean.java rename to spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheManagerFactoryBean.java diff --git a/spring-context/src/main/java/org/springframework/cache/ehcache/package-info.java b/spring-context-support/src/main/java/org/springframework/cache/ehcache/package-info.java similarity index 100% rename from spring-context/src/main/java/org/springframework/cache/ehcache/package-info.java rename to spring-context-support/src/main/java/org/springframework/cache/ehcache/package-info.java diff --git a/spring-context/src/main/java/org/springframework/cache/jcache/JCacheCache.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/JCacheCache.java similarity index 100% rename from spring-context/src/main/java/org/springframework/cache/jcache/JCacheCache.java rename to spring-context-support/src/main/java/org/springframework/cache/jcache/JCacheCache.java diff --git a/spring-context/src/main/java/org/springframework/cache/jcache/JCacheCacheManager.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/JCacheCacheManager.java similarity index 82% rename from spring-context/src/main/java/org/springframework/cache/jcache/JCacheCacheManager.java rename to spring-context-support/src/main/java/org/springframework/cache/jcache/JCacheCacheManager.java index fe7212c145d..e06d8492d2a 100644 --- a/spring-context/src/main/java/org/springframework/cache/jcache/JCacheCacheManager.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/JCacheCacheManager.java @@ -18,11 +18,11 @@ package org.springframework.cache.jcache; import java.util.Collection; import java.util.LinkedHashSet; - +import javax.cache.CacheManager; import javax.cache.Status; import org.springframework.cache.Cache; -import org.springframework.cache.support.AbstractCacheManager; +import org.springframework.cache.transaction.AbstractTransactionSupportingCacheManager; import org.springframework.util.Assert; /** @@ -32,13 +32,29 @@ import org.springframework.util.Assert; * @author Juergen Hoeller * @since 3.2 */ -public class JCacheCacheManager extends AbstractCacheManager { +public class JCacheCacheManager extends AbstractTransactionSupportingCacheManager { private javax.cache.CacheManager cacheManager; private boolean allowNullValues = true; + /** + * Create a new JCacheCacheManager, setting the target JCache CacheManager + * through the {@link #setCacheManager} bean property. + */ + public JCacheCacheManager() { + } + + /** + * Create a new JCacheCacheManager for the given backing JCache. + * @param cacheManager the backing JCache {@link javax.cache.CacheManager} + */ + public JCacheCacheManager(CacheManager cacheManager) { + this.cacheManager = cacheManager; + } + + /** * Set the backing JCache {@link javax.cache.CacheManager}. */ diff --git a/spring-context/src/main/java/org/springframework/cache/jcache/JCacheManagerFactoryBean.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/JCacheManagerFactoryBean.java similarity index 89% rename from spring-context/src/main/java/org/springframework/cache/jcache/JCacheManagerFactoryBean.java rename to spring-context-support/src/main/java/org/springframework/cache/jcache/JCacheManagerFactoryBean.java index af1e1428bb6..b43c1d75b84 100644 --- a/spring-context/src/main/java/org/springframework/cache/jcache/JCacheManagerFactoryBean.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/JCacheManagerFactoryBean.java @@ -20,6 +20,7 @@ import javax.cache.CacheManager; import javax.cache.Caching; import org.springframework.beans.factory.BeanClassLoaderAware; +import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; @@ -33,7 +34,8 @@ import org.springframework.beans.factory.InitializingBean; * @see javax.cache.Caching#getCacheManager() * @see javax.cache.Caching#getCacheManager(String) */ -public class JCacheManagerFactoryBean implements FactoryBean, BeanClassLoaderAware, InitializingBean { +public class JCacheManagerFactoryBean + implements FactoryBean, BeanClassLoaderAware, InitializingBean, DisposableBean { private String cacheManagerName = Caching.DEFAULT_CACHE_MANAGER_NAME; @@ -74,4 +76,9 @@ public class JCacheManagerFactoryBean implements FactoryBean, Bean return true; } + + public void destroy() { + this.cacheManager.shutdown(); + } + } diff --git a/spring-context/src/main/java/org/springframework/cache/jcache/package-info.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/package-info.java similarity index 100% rename from spring-context/src/main/java/org/springframework/cache/jcache/package-info.java rename to spring-context-support/src/main/java/org/springframework/cache/jcache/package-info.java diff --git a/spring-context-support/src/main/java/org/springframework/cache/transaction/AbstractTransactionSupportingCacheManager.java b/spring-context-support/src/main/java/org/springframework/cache/transaction/AbstractTransactionSupportingCacheManager.java new file mode 100644 index 00000000000..3e7143cdf30 --- /dev/null +++ b/spring-context-support/src/main/java/org/springframework/cache/transaction/AbstractTransactionSupportingCacheManager.java @@ -0,0 +1,61 @@ +/* + * Copyright 2002-2012 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cache.transaction; + +import org.springframework.cache.Cache; +import org.springframework.cache.support.AbstractCacheManager; + +/** + * Base class for CacheManager implementations that want to support built-in + * awareness of Spring-managed transactions. This usually needs to be switched + * on explicitly through the {@link #setTransactionAware} bean property. + * + * @author Juergen Hoeller + * @since 3.2 + * @see #setTransactionAware + * @see TransactionAwareCacheDecorator + * @see TransactionAwareCacheManagerProxy + */ +public abstract class AbstractTransactionSupportingCacheManager extends AbstractCacheManager { + + private boolean transactionAware = false; + + + /** + * Set whether this CacheManager should expose transaction-aware Cache objects. + *

Default is "false". Set this to "true" to synchronize cache put/evict + * operations with ongoing Spring-managed transactions, performing the actual cache + * put/evict operation only in the after-commit phase of a successful transaction. + */ + public void setTransactionAware(boolean transactionAware) { + this.transactionAware = transactionAware; + } + + /** + * Return whether this CacheManager has been configured to be transaction-aware. + */ + public boolean isTransactionAware() { + return this.transactionAware; + } + + + @Override + protected Cache decorateCache(Cache cache) { + return (isTransactionAware() ? new TransactionAwareCacheDecorator(cache) : cache); + } + +} diff --git a/spring-context-support/src/main/java/org/springframework/cache/transaction/TransactionAwareCacheDecorator.java b/spring-context-support/src/main/java/org/springframework/cache/transaction/TransactionAwareCacheDecorator.java new file mode 100644 index 00000000000..7b7ac52f972 --- /dev/null +++ b/spring-context-support/src/main/java/org/springframework/cache/transaction/TransactionAwareCacheDecorator.java @@ -0,0 +1,94 @@ +/* + * Copyright 2002-2012 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cache.transaction; + +import org.springframework.cache.Cache; +import org.springframework.transaction.support.TransactionSynchronizationAdapter; +import org.springframework.transaction.support.TransactionSynchronizationManager; +import org.springframework.util.Assert; + +/** + * Cache decorator which synchronizes its {@link #put} and {@link #evict} operations with + * Spring-managed transactions (through Spring's {@link TransactionSynchronizationManager}, + * performing the actual cache put/evict operation only in the after-commit phase of a + * successful transaction. If no transaction is active, {@link #put} and {@link #evict} + * operations will be performed immediately, as usual. + * + * @author Juergen Hoeller + * @since 3.2 + * @see TransactionAwareCacheManagerProxy + */ +public class TransactionAwareCacheDecorator implements Cache { + + private final Cache targetCache; + + + /** + * Create a new TransactionAwareCache for the given target Cache. + * @param targetCache the target Cache to decorate + */ + public TransactionAwareCacheDecorator(Cache targetCache) { + Assert.notNull(targetCache, "Target Cache must not be null"); + this.targetCache = targetCache; + } + + + public String getName() { + return this.targetCache.getName(); + } + + public Object getNativeCache() { + return this.targetCache.getNativeCache(); + } + + public ValueWrapper get(Object key) { + return this.targetCache.get(key); + } + + public void put(final Object key, final Object value) { + if (TransactionSynchronizationManager.isSynchronizationActive()) { + TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() { + @Override + public void afterCommit() { + targetCache.put(key, value); + } + }); + } + else { + this.targetCache.put(key, value); + } + } + + public void evict(final Object key) { + if (TransactionSynchronizationManager.isSynchronizationActive()) { + TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() { + @Override + public void afterCommit() { + targetCache.evict(key); + } + }); + } + else { + this.targetCache.evict(key); + } + } + + public void clear() { + this.targetCache.clear(); + } + +} diff --git a/spring-context-support/src/main/java/org/springframework/cache/transaction/TransactionAwareCacheManagerProxy.java b/spring-context-support/src/main/java/org/springframework/cache/transaction/TransactionAwareCacheManagerProxy.java new file mode 100644 index 00000000000..efcfd8f54c3 --- /dev/null +++ b/spring-context-support/src/main/java/org/springframework/cache/transaction/TransactionAwareCacheManagerProxy.java @@ -0,0 +1,83 @@ +/* + * Copyright 2002-2012 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cache.transaction; + +import java.util.Collection; + +import org.springframework.beans.factory.InitializingBean; +import org.springframework.cache.Cache; +import org.springframework.cache.CacheManager; +import org.springframework.util.Assert; + +/** + * Proxy for a target {@link CacheManager}, exposing transaction-aware {@link Cache} objects + * which synchronize their {@link Cache#put} operations with Spring-managed transactions + * (through Spring's {@link org.springframework.transaction.support.TransactionSynchronizationManager}, + * performing the actual cache put operation only in the after-commit phase of a successful transaction. + * If no transaction is active, {@link Cache#put} operations will be performed immediately, as usual. + * + * @author Juergen Hoeller + * @since 3.2 + * @see #setTargetCacheManager + * @see TransactionAwareCacheDecorator + * @see org.springframework.transaction.support.TransactionSynchronizationManager + */ +public class TransactionAwareCacheManagerProxy implements CacheManager, InitializingBean { + + private CacheManager targetCacheManager; + + + /** + * Create a new TransactionAwareCacheManagerProxy, setting the target CacheManager + * through the {@link #setTargetCacheManager} bean property. + */ + public TransactionAwareCacheManagerProxy() { + } + + /** + * Create a new TransactionAwareCacheManagerProxy for the given target CacheManager. + * @param targetCacheManager the target CacheManager to proxy + */ + public TransactionAwareCacheManagerProxy(CacheManager targetCacheManager) { + Assert.notNull(targetCacheManager, "Target CacheManager must not be null"); + this.targetCacheManager = targetCacheManager; + } + + + /** + * Set the target CacheManager to proxy. + */ + public void setTargetCacheManager(CacheManager targetCacheManager) { + this.targetCacheManager = targetCacheManager; + } + + public void afterPropertiesSet() { + if (this.targetCacheManager == null) { + throw new IllegalStateException("'targetCacheManager' is required"); + } + } + + + public Cache getCache(String name) { + return new TransactionAwareCacheDecorator(this.targetCacheManager.getCache(name)); + } + + public Collection getCacheNames() { + return this.targetCacheManager.getCacheNames(); + } + +} diff --git a/spring-context-support/src/main/java/org/springframework/cache/transaction/package-info.java b/spring-context-support/src/main/java/org/springframework/cache/transaction/package-info.java new file mode 100644 index 00000000000..96743a8670c --- /dev/null +++ b/spring-context-support/src/main/java/org/springframework/cache/transaction/package-info.java @@ -0,0 +1,5 @@ +/** + * Transaction-aware decorators for the the org.springframework.cache package. + * Provides synchronization of put operations with Spring-managed transactions. + */ +package org.springframework.cache.transaction; diff --git a/spring-context/src/test/java/org/springframework/cache/vendor/AbstractNativeCacheTests.java b/spring-context-support/src/test/java/org/springframework/cache/ehcache/EhCacheCacheTests.java similarity index 63% rename from spring-context/src/test/java/org/springframework/cache/vendor/AbstractNativeCacheTests.java rename to spring-context-support/src/test/java/org/springframework/cache/ehcache/EhCacheCacheTests.java index 7afc1d1c27c..5cb15498324 100644 --- a/spring-context/src/test/java/org/springframework/cache/vendor/AbstractNativeCacheTests.java +++ b/spring-context-support/src/test/java/org/springframework/cache/ehcache/EhCacheCacheTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011 the original author or authors. + * Copyright 2010-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,38 +14,45 @@ * limitations under the License. */ -package org.springframework.cache.vendor; - -import static org.junit.Assert.*; +package org.springframework.cache.ehcache; +import net.sf.ehcache.CacheManager; +import net.sf.ehcache.Ehcache; +import net.sf.ehcache.Element; +import net.sf.ehcache.config.CacheConfiguration; import org.junit.Before; import org.junit.Test; + import org.springframework.cache.Cache; +import static org.junit.Assert.*; + /** - * Test for native cache implementations. - * * @author Costin Leau */ -public abstract class AbstractNativeCacheTests { +public class EhCacheCacheTests { - protected T nativeCache; - protected Cache cache; protected final static String CACHE_NAME = "testCache"; + protected Ehcache nativeCache; + + protected Cache cache; + + @Before public void setUp() throws Exception { - nativeCache = createNativeCache(); - cache = createCache(nativeCache); + if (CacheManager.getInstance().cacheExists(CACHE_NAME)) { + nativeCache = CacheManager.getInstance().getEhcache(CACHE_NAME); + } + else { + nativeCache = new net.sf.ehcache.Cache(new CacheConfiguration(CACHE_NAME, 100)); + CacheManager.getInstance().addCache(nativeCache); + } + cache = new EhCacheCache(nativeCache); cache.clear(); } - protected abstract T createNativeCache() throws Exception; - - protected abstract Cache createCache(T nativeCache); - - @Test public void testCacheName() throws Exception { assertEquals(CACHE_NAME, cache.getName()); @@ -85,4 +92,20 @@ public abstract class AbstractNativeCacheTests { assertNull(cache.get("vlaicu")); assertNull(cache.get("enescu")); } -} \ No newline at end of file + + @Test + public void testExpiredElements() throws Exception { + String key = "brancusi"; + String value = "constantin"; + Element brancusi = new Element(key, value); + // ttl = 10s + brancusi.setTimeToLive(3); + nativeCache.put(brancusi); + + assertEquals(value, cache.get(key).get()); + // wait for the entry to expire + Thread.sleep(5 * 1000); + assertNull(cache.get(key)); + } + +} diff --git a/spring-context/src/test/java/org/springframework/cache/ehcache/EhCacheSupportTests.java b/spring-context-support/src/test/java/org/springframework/cache/ehcache/EhCacheSupportTests.java similarity index 99% rename from spring-context/src/test/java/org/springframework/cache/ehcache/EhCacheSupportTests.java rename to spring-context-support/src/test/java/org/springframework/cache/ehcache/EhCacheSupportTests.java index b8f4c01b3c2..8ea783e17cc 100644 --- a/spring-context/src/test/java/org/springframework/cache/ehcache/EhCacheSupportTests.java +++ b/spring-context-support/src/test/java/org/springframework/cache/ehcache/EhCacheSupportTests.java @@ -17,7 +17,6 @@ package org.springframework.cache.ehcache; import junit.framework.TestCase; - import net.sf.ehcache.Cache; import net.sf.ehcache.CacheManager; import net.sf.ehcache.Ehcache; @@ -152,7 +151,7 @@ public class EhCacheSupportTests extends TestCase { assertTrue("overridden diskExpiryThreadIntervalSeconds is correct", config.getDiskExpiryThreadIntervalSeconds() == 10); } finally { - if (useCacheManagerFb) { + if (useCacheManagerFb && cacheManagerFb != null) { cacheManagerFb.destroy(); } else { diff --git a/spring-context/src/test/resources/org/springframework/cache/ehcache/testEhcache.xml b/spring-context-support/src/test/resources/org/springframework/cache/ehcache/testEhcache.xml similarity index 100% rename from spring-context/src/test/resources/org/springframework/cache/ehcache/testEhcache.xml rename to spring-context-support/src/test/resources/org/springframework/cache/ehcache/testEhcache.xml diff --git a/spring-context/src/main/java/org/springframework/cache/support/AbstractCacheManager.java b/spring-context/src/main/java/org/springframework/cache/support/AbstractCacheManager.java index 5b25f76420d..e5665734b92 100644 --- a/spring-context/src/main/java/org/springframework/cache/support/AbstractCacheManager.java +++ b/spring-context/src/main/java/org/springframework/cache/support/AbstractCacheManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2011 the original author or authors. + * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -51,16 +51,27 @@ public abstract class AbstractCacheManager implements CacheManager, Initializing // preserve the initial order of the cache names for (Cache cache : caches) { - this.cacheMap.put(cache.getName(), cache); + this.cacheMap.put(cache.getName(), decorateCache(cache)); this.cacheNames.add(cache.getName()); } } protected final void addCache(Cache cache) { - this.cacheMap.put(cache.getName(), cache); + this.cacheMap.put(cache.getName(), decorateCache(cache)); this.cacheNames.add(cache.getName()); } + /** + * Decorate the given Cache object if necessary. + * @param cache the Cache object to be added to this CacheManager + * @return the decorated Cache object to be used instead, + * or simply the passed-in Cache object by default + */ + protected Cache decorateCache(Cache cache) { + return cache; + } + + public Cache getCache(String name) { return this.cacheMap.get(name); } diff --git a/spring-context/src/test/java/org/springframework/cache/concurrent/ConcurrentCacheTests.java b/spring-context/src/test/java/org/springframework/cache/concurrent/ConcurrentCacheTests.java index 88ae4bfa889..fdc13fbd641 100644 --- a/spring-context/src/test/java/org/springframework/cache/concurrent/ConcurrentCacheTests.java +++ b/spring-context/src/test/java/org/springframework/cache/concurrent/ConcurrentCacheTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011 the original author or authors. + * Copyright 2010-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,21 +19,71 @@ package org.springframework.cache.concurrent; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import org.junit.Before; +import org.junit.Test; + import org.springframework.cache.Cache; -import org.springframework.cache.vendor.AbstractNativeCacheTests; + +import static org.junit.Assert.*; /** * @author Costin Leau */ -public class ConcurrentCacheTests extends AbstractNativeCacheTests> { +public class ConcurrentCacheTests { + + protected final static String CACHE_NAME = "testCache"; + + protected ConcurrentMap nativeCache; + + protected Cache cache; + + + @Before + public void setUp() throws Exception { + nativeCache = new ConcurrentHashMap(); + cache = new ConcurrentMapCache(CACHE_NAME, nativeCache, true); + cache.clear(); + } + - @Override - protected Cache createCache(ConcurrentMap nativeCache) { - return new ConcurrentMapCache(CACHE_NAME, nativeCache, true); + @Test + public void testCacheName() throws Exception { + assertEquals(CACHE_NAME, cache.getName()); } - @Override - protected ConcurrentMap createNativeCache() throws Exception { - return new ConcurrentHashMap(); + @Test + public void testNativeCache() throws Exception { + assertSame(nativeCache, cache.getNativeCache()); } + + @Test + public void testCachePut() throws Exception { + Object key = "enescu"; + Object value = "george"; + + assertNull(cache.get(key)); + cache.put(key, value); + assertEquals(value, cache.get(key).get()); + } + + @Test + public void testCacheRemove() throws Exception { + Object key = "enescu"; + Object value = "george"; + + assertNull(cache.get(key)); + cache.put(key, value); + } + + @Test + public void testCacheClear() throws Exception { + assertNull(cache.get("enescu")); + cache.put("enescu", "george"); + assertNull(cache.get("vlaicu")); + cache.put("vlaicu", "aurel"); + cache.clear(); + assertNull(cache.get("vlaicu")); + assertNull(cache.get("enescu")); + } + } diff --git a/spring-context/src/test/java/org/springframework/cache/ehcache/EhCacheCacheTests.java b/spring-context/src/test/java/org/springframework/cache/ehcache/EhCacheCacheTests.java deleted file mode 100644 index 3b188a585a1..00000000000 --- a/spring-context/src/test/java/org/springframework/cache/ehcache/EhCacheCacheTests.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2010-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cache.ehcache; - -import static org.junit.Assert.*; -import net.sf.ehcache.Ehcache; -import net.sf.ehcache.Element; - -import org.junit.Test; -import org.springframework.cache.Cache; -import org.springframework.cache.vendor.AbstractNativeCacheTests; - -/** - * Integration test for EhCache cache. - * - * @author Costin Leau - */ -public class EhCacheCacheTests extends AbstractNativeCacheTests { - - @Override - protected Ehcache createNativeCache() throws Exception { - EhCacheFactoryBean fb = new EhCacheFactoryBean(); - fb.setBeanName(CACHE_NAME); - fb.setCacheName(CACHE_NAME); - fb.afterPropertiesSet(); - return fb.getObject(); - } - - @Override - protected Cache createCache(Ehcache nativeCache) { - return new EhCacheCache(nativeCache); - } - - @Test - public void testExpiredElements() throws Exception { - String key = "brancusi"; - String value = "constantin"; - Element brancusi = new Element(key, value); - // ttl = 10s - brancusi.setTimeToLive(3); - nativeCache.put(brancusi); - - assertEquals(value, cache.get(key).get()); - // wait for the entry to expire - Thread.sleep(5 * 1000); - assertNull(cache.get(key)); - } -} \ No newline at end of file