diff --git a/spring-aspects/src/test/java/org/springframework/cache/config/AnnotatedJCacheableService.java b/spring-aspects/src/test/java/org/springframework/cache/config/AnnotatedJCacheableService.java index dc3deb0add5..0ca82330a62 100644 --- a/spring-aspects/src/test/java/org/springframework/cache/config/AnnotatedJCacheableService.java +++ b/spring-aspects/src/test/java/org/springframework/cache/config/AnnotatedJCacheableService.java @@ -29,8 +29,8 @@ import javax.cache.annotation.CacheResult; import javax.cache.annotation.CacheValue; import org.springframework.cache.Cache; +import org.springframework.cache.interceptor.SimpleKeyGenerator; import org.springframework.cache.jcache.config.JCacheableService; -import org.springframework.cache.jcache.interceptor.SimpleGeneratedCacheKey; import org.springframework.cache.jcache.support.TestableCacheKeyGenerator; import org.springframework.cache.jcache.support.TestableCacheResolverFactory; @@ -111,7 +111,7 @@ public class AnnotatedJCacheableService implements JCacheableService { @Override @CachePut(afterInvocation = false) public void earlyPut(String id, @CacheValue Object value) { - SimpleGeneratedCacheKey key = new SimpleGeneratedCacheKey(id); + Object key = SimpleKeyGenerator.generateKey(id); Cache.ValueWrapper valueWrapper = defaultCache.get(key); if (valueWrapper == null) { throw new AssertionError("Excepted value to be put in cache with key " + key); @@ -143,7 +143,7 @@ public class AnnotatedJCacheableService implements JCacheableService { @Override @CacheRemove(afterInvocation = false) public void earlyRemove(String id) { - SimpleGeneratedCacheKey key = new SimpleGeneratedCacheKey(id); + Object key = SimpleKeyGenerator.generateKey(id); Cache.ValueWrapper valueWrapper = defaultCache.get(key); if (valueWrapper != null) { throw new AssertionError("Value with key " + key + " expected to be already remove from cache"); diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/config/AbstractJCacheConfiguration.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/config/AbstractJCacheConfiguration.java index af2ebfb02d0..ff2b7ea75fd 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/config/AbstractJCacheConfiguration.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/config/AbstractJCacheConfiguration.java @@ -49,18 +49,17 @@ public class AbstractJCacheConfiguration extends AbstractCachingConfiguration, A extends Annotation> +abstract class AbstractCacheInterceptor, A extends Annotation> extends AbstractCacheInvoker implements Serializable { protected final Log logger = LogFactory.getLog(getClass()); diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/AbstractFallbackJCacheOperationSource.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/AbstractFallbackJCacheOperationSource.java index e2642e7226a..c38849b787b 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/AbstractFallbackJCacheOperationSource.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/AbstractFallbackJCacheOperationSource.java @@ -25,7 +25,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.cache.interceptor.MethodCacheKey; -import org.springframework.cache.jcache.model.JCacheOperation; import org.springframework.core.BridgeMethodResolver; import org.springframework.util.ClassUtils; @@ -58,7 +57,7 @@ public abstract class AbstractFallbackJCacheOperationSource return cached; } else { - JCacheOperation operation = computeCacheOperations(method, targetClass); + JCacheOperation operation = computeCacheOperation(method, targetClass); if (operation != null) { if (logger.isDebugEnabled()) { logger.debug("Adding cacheable method '" + method.getName() @@ -70,7 +69,7 @@ public abstract class AbstractFallbackJCacheOperationSource } } - private JCacheOperation computeCacheOperations(Method method, Class targetClass) { + private JCacheOperation computeCacheOperation(Method method, Class targetClass) { // Don't allow no-public methods as required. if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) { return null; diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/model/BaseKeyCacheOperation.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/AbstractJCacheKeyOperation.java similarity index 87% rename from spring-context-support/src/main/java/org/springframework/cache/jcache/model/BaseKeyCacheOperation.java rename to spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/AbstractJCacheKeyOperation.java index b32e55f7162..facc4d37457 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/model/BaseKeyCacheOperation.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/AbstractJCacheKeyOperation.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cache.jcache.model; +package org.springframework.cache.jcache.interceptor; import java.lang.annotation.Annotation; import java.util.ArrayList; @@ -32,30 +32,33 @@ import org.springframework.cache.interceptor.KeyGenerator; * @author Stephane Nicoll * @since 4.1 */ -public abstract class BaseKeyCacheOperation extends BaseCacheOperation { +abstract class AbstractJCacheKeyOperation extends AbstractJCacheOperation { private final KeyGenerator keyGenerator; private final List keyParameterDetails; + /** * Create a new instance. * @param methodDetails the {@link CacheMethodDetails} related to the cached method * @param cacheResolver the cache resolver to resolve regular caches * @param keyGenerator the key generator to compute cache keys */ - protected BaseKeyCacheOperation(CacheMethodDetails methodDetails, + protected AbstractJCacheKeyOperation(CacheMethodDetails methodDetails, CacheResolver cacheResolver, KeyGenerator keyGenerator) { + super(methodDetails, cacheResolver); this.keyGenerator = keyGenerator; - this.keyParameterDetails = initializeKeyParameterDetails(allParameterDetails); + this.keyParameterDetails = initializeKeyParameterDetails(this.allParameterDetails); } + /** * Return the {@link KeyGenerator} to use to compute cache keys. */ public KeyGenerator getKeyGenerator() { - return keyGenerator; + return this.keyGenerator; } /** @@ -72,7 +75,7 @@ public abstract class BaseKeyCacheOperation extends BaseCa */ public CacheInvocationParameter[] getKeyParameters(Object... values) { List result = new ArrayList(); - for (CacheParameterDetail keyParameterDetail : keyParameterDetails) { + for (CacheParameterDetail keyParameterDetail : this.keyParameterDetails) { int parameterPosition = keyParameterDetail.getParameterPosition(); if (parameterPosition >= values.length) { throw new IllegalStateException("Values mismatch, key parameter at position " @@ -95,7 +98,7 @@ public abstract class BaseKeyCacheOperation extends BaseCa annotated.add(allParameter); } } - return annotated.size() == 0 ? all : annotated; + return (annotated.isEmpty() ? all : annotated); } } diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/model/BaseCacheOperation.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/AbstractJCacheOperation.java similarity index 92% rename from spring-context-support/src/main/java/org/springframework/cache/jcache/model/BaseCacheOperation.java rename to spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/AbstractJCacheOperation.java index 39581881b2e..6db0afb80ed 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/model/BaseCacheOperation.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/AbstractJCacheOperation.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cache.jcache.model; +package org.springframework.cache.jcache.interceptor; import java.lang.annotation.Annotation; import java.lang.reflect.Method; @@ -40,7 +40,7 @@ import static java.util.Arrays.*; * @author Stephane Nicoll * @since 4.1 */ -public abstract class BaseCacheOperation implements JCacheOperation { +abstract class AbstractJCacheOperation implements JCacheOperation { private final CacheMethodDetails methodDetails; @@ -54,7 +54,7 @@ public abstract class BaseCacheOperation implements JCache * @param methodDetails the {@link CacheMethodDetails} related to the cached method * @param cacheResolver the cache resolver to resolve regular caches */ - protected BaseCacheOperation(CacheMethodDetails methodDetails, CacheResolver cacheResolver) { + protected AbstractJCacheOperation(CacheMethodDetails methodDetails, CacheResolver cacheResolver) { Assert.notNull(methodDetails, "method details must not be null."); Assert.notNull(cacheResolver, "cache resolver must not be null."); this.methodDetails = methodDetails; @@ -159,13 +159,13 @@ public abstract class BaseCacheOperation implements JCache private final boolean isValue; - public CacheParameterDetail(Method m, int parameterPosition) { - this.rawType = m.getParameterTypes()[parameterPosition]; + public CacheParameterDetail(Method method, int parameterPosition) { + this.rawType = method.getParameterTypes()[parameterPosition]; this.annotations = new LinkedHashSet(); boolean foundKeyAnnotation = false; boolean foundValueAnnotation = false; - for (Annotation annotation : m.getParameterAnnotations()[parameterPosition]) { - annotations.add(annotation); + for (Annotation annotation : method.getParameterAnnotations()[parameterPosition]) { + this.annotations.add(annotation); if (CacheKey.class.isAssignableFrom(annotation.annotationType())) { foundKeyAnnotation = true; } diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/AbstractKeyCacheInterceptor.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/AbstractKeyCacheInterceptor.java index 33259e31a0f..d8431a55b1c 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/AbstractKeyCacheInterceptor.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/AbstractKeyCacheInterceptor.java @@ -23,7 +23,6 @@ import javax.cache.annotation.CacheKeyInvocationContext; import org.springframework.cache.interceptor.CacheErrorHandler; import org.springframework.cache.interceptor.CacheOperationInvocationContext; import org.springframework.cache.interceptor.KeyGenerator; -import org.springframework.cache.jcache.model.BaseKeyCacheOperation; /** * A base interceptor for JSR-107 key-based cache annotations. @@ -32,7 +31,7 @@ import org.springframework.cache.jcache.model.BaseKeyCacheOperation; * @since 4.1 */ @SuppressWarnings("serial") -public abstract class AbstractKeyCacheInterceptor, A extends Annotation> +abstract class AbstractKeyCacheInterceptor, A extends Annotation> extends AbstractCacheInterceptor { protected AbstractKeyCacheInterceptor(CacheErrorHandler errorHandler) { diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/AnnotationCacheOperationSource.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/AnnotationJCacheOperationSource.java similarity index 94% rename from spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/AnnotationCacheOperationSource.java rename to spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/AnnotationJCacheOperationSource.java index 34fd6423ce6..768879e39d9 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/AnnotationCacheOperationSource.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/AnnotationJCacheOperationSource.java @@ -32,12 +32,6 @@ import javax.cache.annotation.CacheResult; import org.springframework.cache.interceptor.CacheResolver; import org.springframework.cache.interceptor.KeyGenerator; -import org.springframework.cache.jcache.model.CachePutOperation; -import org.springframework.cache.jcache.model.CacheRemoveAllOperation; -import org.springframework.cache.jcache.model.CacheRemoveOperation; -import org.springframework.cache.jcache.model.CacheResultOperation; -import org.springframework.cache.jcache.model.DefaultCacheMethodDetails; -import org.springframework.cache.jcache.model.JCacheOperation; import org.springframework.util.StringUtils; /** @@ -48,8 +42,7 @@ import org.springframework.util.StringUtils; * @author Stephane Nicoll * @since 4.1 */ -public abstract class AnnotationCacheOperationSource - extends AbstractFallbackJCacheOperationSource { +public abstract class AnnotationJCacheOperationSource extends AbstractFallbackJCacheOperationSource { /** * Locate or create an instance of the specified {@code type}. @@ -236,7 +229,6 @@ public abstract class AnnotationCacheOperationSource /** * Generate a default cache name for the specified {@link Method}. - * * @param method the annotated method * @return the default cache name, according to JSR-107 */ diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CachePutInterceptor.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CachePutInterceptor.java index 7049661e1a8..ee339ce4621 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CachePutInterceptor.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CachePutInterceptor.java @@ -23,7 +23,6 @@ import org.springframework.cache.Cache; import org.springframework.cache.interceptor.CacheErrorHandler; import org.springframework.cache.interceptor.CacheOperationInvocationContext; import org.springframework.cache.interceptor.CacheOperationInvoker; -import org.springframework.cache.jcache.model.CachePutOperation; /** * Intercept methods annotated with {@link CachePut}. @@ -32,7 +31,7 @@ import org.springframework.cache.jcache.model.CachePutOperation; * @since 4.1 */ @SuppressWarnings("serial") -public class CachePutInterceptor extends AbstractKeyCacheInterceptor { +class CachePutInterceptor extends AbstractKeyCacheInterceptor { public CachePutInterceptor(CacheErrorHandler errorHandler) { super(errorHandler); @@ -41,11 +40,12 @@ public class CachePutInterceptor extends AbstractKeyCacheInterceptor context, CacheOperationInvoker invoker) { + CacheKeyInvocationContext invocationContext = createCacheKeyInvocationContext(context); CachePutOperation operation = context.getOperation(); - final boolean earlyPut = operation.isEarlyPut(); - final Object value = invocationContext.getValueParameter().getValue(); + boolean earlyPut = operation.isEarlyPut(); + Object value = invocationContext.getValueParameter().getValue(); if (earlyPut) { cacheValue(context, value); @@ -58,12 +58,12 @@ public class CachePutInterceptor extends AbstractKeyCacheInterceptor { +class CachePutOperation extends AbstractJCacheKeyOperation { private final ExceptionTypeFilter exceptionTypeFilter; @@ -47,8 +47,8 @@ public class CachePutOperation extends BaseKeyCacheOperation { super(methodDetails, cacheResolver, keyGenerator); CachePut ann = methodDetails.getCacheAnnotation(); this.exceptionTypeFilter = createExceptionTypeFilter(ann.cacheFor(), ann.noCacheFor()); - this.valueParameterDetail = initializeValueParameterDetail(methodDetails.getMethod(), allParameterDetails); - if (valueParameterDetail == null) { + this.valueParameterDetail = initializeValueParameterDetail(methodDetails.getMethod(), this.allParameterDetails); + if (this.valueParameterDetail == null) { throw new IllegalArgumentException("No parameter annotated with @CacheValue was found for " + "" + methodDetails.getMethod()); } diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CacheRemoveAllInterceptor.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CacheRemoveAllInterceptor.java index 25b866932fc..78212f9bd80 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CacheRemoveAllInterceptor.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CacheRemoveAllInterceptor.java @@ -22,7 +22,6 @@ import org.springframework.cache.Cache; import org.springframework.cache.interceptor.CacheErrorHandler; import org.springframework.cache.interceptor.CacheOperationInvocationContext; import org.springframework.cache.interceptor.CacheOperationInvoker; -import org.springframework.cache.jcache.model.CacheRemoveAllOperation; /** * Intercept methods annotated with {@link CacheRemoveAll}. @@ -31,7 +30,7 @@ import org.springframework.cache.jcache.model.CacheRemoveAllOperation; * @since 4.1 */ @SuppressWarnings("serial") -public class CacheRemoveAllInterceptor +class CacheRemoveAllInterceptor extends AbstractCacheInterceptor { protected CacheRemoveAllInterceptor(CacheErrorHandler errorHandler) { @@ -41,9 +40,10 @@ public class CacheRemoveAllInterceptor @Override protected Object invoke(CacheOperationInvocationContext context, CacheOperationInvoker invoker) { + CacheRemoveAllOperation operation = context.getOperation(); - final boolean earlyRemove = operation.isEarlyRemove(); + boolean earlyRemove = operation.isEarlyRemove(); if (earlyRemove) { removeAll(context); @@ -56,12 +56,12 @@ public class CacheRemoveAllInterceptor } return result; } - catch (CacheOperationInvoker.ThrowableWrapper t) { - Throwable ex = t.getOriginal(); - if (!earlyRemove && operation.getExceptionTypeFilter().match(ex.getClass())) { + catch (CacheOperationInvoker.ThrowableWrapper ex) { + Throwable original = ex.getOriginal(); + if (!earlyRemove && operation.getExceptionTypeFilter().match(original.getClass())) { removeAll(context); } - throw t; + throw ex; } } diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/model/CacheRemoveAllOperation.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CacheRemoveAllOperation.java similarity index 92% rename from spring-context-support/src/main/java/org/springframework/cache/jcache/model/CacheRemoveAllOperation.java rename to spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CacheRemoveAllOperation.java index b3c24152a1a..553d7f3dde0 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/model/CacheRemoveAllOperation.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CacheRemoveAllOperation.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cache.jcache.model; +package org.springframework.cache.jcache.interceptor; import javax.cache.annotation.CacheMethodDetails; import javax.cache.annotation.CacheRemoveAll; @@ -29,7 +29,7 @@ import org.springframework.util.ExceptionTypeFilter; * @since 4.1 * @see CacheRemoveAll */ -public class CacheRemoveAllOperation extends BaseCacheOperation { +class CacheRemoveAllOperation extends AbstractJCacheOperation { private final ExceptionTypeFilter exceptionTypeFilter; diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CacheRemoveEntryInterceptor.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CacheRemoveEntryInterceptor.java index 4fcb3fc7c2c..19bbc2c27be 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CacheRemoveEntryInterceptor.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CacheRemoveEntryInterceptor.java @@ -22,7 +22,6 @@ import org.springframework.cache.Cache; import org.springframework.cache.interceptor.CacheErrorHandler; import org.springframework.cache.interceptor.CacheOperationInvocationContext; import org.springframework.cache.interceptor.CacheOperationInvoker; -import org.springframework.cache.jcache.model.CacheRemoveOperation; /** * Intercept methods annotated with {@link CacheRemove}. @@ -31,7 +30,7 @@ import org.springframework.cache.jcache.model.CacheRemoveOperation; * @since 4.1 */ @SuppressWarnings("serial") -public class CacheRemoveEntryInterceptor extends AbstractKeyCacheInterceptor { +class CacheRemoveEntryInterceptor extends AbstractKeyCacheInterceptor { protected CacheRemoveEntryInterceptor(CacheErrorHandler errorHandler) { super(errorHandler); diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/model/CacheRemoveOperation.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CacheRemoveOperation.java similarity index 93% rename from spring-context-support/src/main/java/org/springframework/cache/jcache/model/CacheRemoveOperation.java rename to spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CacheRemoveOperation.java index d05335d7b8d..93997701664 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/model/CacheRemoveOperation.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CacheRemoveOperation.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cache.jcache.model; +package org.springframework.cache.jcache.interceptor; import javax.cache.annotation.CacheMethodDetails; import javax.cache.annotation.CacheRemove; @@ -30,7 +30,7 @@ import org.springframework.util.ExceptionTypeFilter; * @since 4.1 * @see CacheRemove */ -public class CacheRemoveOperation extends BaseKeyCacheOperation { +class CacheRemoveOperation extends AbstractJCacheKeyOperation { private final ExceptionTypeFilter exceptionTypeFilter; diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CacheResolverAdapter.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CacheResolverAdapter.java index f544e92b9ad..83526d98702 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CacheResolverAdapter.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CacheResolverAdapter.java @@ -20,7 +20,7 @@ import org.springframework.util.Assert; * @author Stephane Nicoll * @since 4.1 */ -public class CacheResolverAdapter implements CacheResolver { +class CacheResolverAdapter implements CacheResolver { private final javax.cache.annotation.CacheResolver target; diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CacheResultInterceptor.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CacheResultInterceptor.java index 81ed04f5ddf..e472729401d 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CacheResultInterceptor.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CacheResultInterceptor.java @@ -23,9 +23,8 @@ import org.springframework.cache.interceptor.CacheErrorHandler; import org.springframework.cache.interceptor.CacheOperationInvocationContext; import org.springframework.cache.interceptor.CacheOperationInvoker; import org.springframework.cache.interceptor.CacheResolver; -import org.springframework.cache.jcache.model.CacheResultOperation; -import org.springframework.util.SerializationUtils; import org.springframework.util.ExceptionTypeFilter; +import org.springframework.util.SerializationUtils; /** * Intercept methods annotated with {@link CacheResult}. @@ -34,7 +33,7 @@ import org.springframework.util.ExceptionTypeFilter; * @since 4.1 */ @SuppressWarnings("serial") -public class CacheResultInterceptor extends AbstractKeyCacheInterceptor { +class CacheResultInterceptor extends AbstractKeyCacheInterceptor { public CacheResultInterceptor(CacheErrorHandler errorHandler) { super(errorHandler); @@ -43,9 +42,9 @@ public class CacheResultInterceptor extends AbstractKeyCacheInterceptor context, CacheOperationInvoker invoker) { - CacheResultOperation operation = context.getOperation(); - final Object cacheKey = generateKey(context); + CacheResultOperation operation = context.getOperation(); + Object cacheKey = generateKey(context); Cache cache = resolveCache(context); Cache exceptionCache = resolveExceptionCache(context); diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/model/CacheResultOperation.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CacheResultOperation.java similarity index 95% rename from spring-context-support/src/main/java/org/springframework/cache/jcache/model/CacheResultOperation.java rename to spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CacheResultOperation.java index 777f2a9c709..314fdc62a14 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/model/CacheResultOperation.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CacheResultOperation.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cache.jcache.model; +package org.springframework.cache.jcache.interceptor; import javax.cache.annotation.CacheMethodDetails; import javax.cache.annotation.CacheResult; @@ -31,7 +31,7 @@ import org.springframework.util.StringUtils; * @since 4.1 * @see CacheResult */ -public class CacheResultOperation extends BaseKeyCacheOperation { +class CacheResultOperation extends AbstractJCacheKeyOperation { private final ExceptionTypeFilter exceptionTypeFilter; diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/DefaultCacheInvocationContext.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/DefaultCacheInvocationContext.java index 2b9fe231465..5c5cdd4e8f3 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/DefaultCacheInvocationContext.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/DefaultCacheInvocationContext.java @@ -25,7 +25,6 @@ import javax.cache.annotation.CacheInvocationContext; import javax.cache.annotation.CacheInvocationParameter; import org.springframework.cache.interceptor.CacheOperationInvocationContext; -import org.springframework.cache.jcache.model.JCacheOperation; /** * The default {@link CacheOperationInvocationContext} implementation used @@ -35,7 +34,7 @@ import org.springframework.cache.jcache.model.JCacheOperation; * @author Stephane Nicoll * @since 4.1 */ -public class DefaultCacheInvocationContext +class DefaultCacheInvocationContext implements CacheInvocationContext, CacheOperationInvocationContext> { private final JCacheOperation operation; @@ -56,42 +55,42 @@ public class DefaultCacheInvocationContext @Override public JCacheOperation getOperation() { - return operation; + return this.operation; } @Override public Method getMethod() { - return operation.getMethod(); + return this.operation.getMethod(); } @Override public Object[] getArgs() { - return args.clone(); + return this.args.clone(); } @Override public Set getAnnotations() { - return operation.getAnnotations(); + return this.operation.getAnnotations(); } @Override public A getCacheAnnotation() { - return operation.getCacheAnnotation(); + return this.operation.getCacheAnnotation(); } @Override public String getCacheName() { - return operation.getCacheName(); + return this.operation.getCacheName(); } @Override public Object getTarget() { - return target; + return this.target; } @Override public CacheInvocationParameter[] getAllParameters() { - return allParameters.clone(); + return this.allParameters.clone(); } @Override diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/DefaultCacheKeyInvocationContext.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/DefaultCacheKeyInvocationContext.java index 97e9f5a69b5..0e2235943db 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/DefaultCacheKeyInvocationContext.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/DefaultCacheKeyInvocationContext.java @@ -21,23 +21,20 @@ import java.lang.annotation.Annotation; import javax.cache.annotation.CacheInvocationParameter; import javax.cache.annotation.CacheKeyInvocationContext; -import org.springframework.cache.jcache.model.BaseKeyCacheOperation; -import org.springframework.cache.jcache.model.CachePutOperation; - /** * The default {@link CacheKeyInvocationContext} implementation. * * @author Stephane Nicoll * @since 4.1 */ -public class DefaultCacheKeyInvocationContext +class DefaultCacheKeyInvocationContext extends DefaultCacheInvocationContext implements CacheKeyInvocationContext { private final CacheInvocationParameter[] keyParameters; private final CacheInvocationParameter valueParameter; - public DefaultCacheKeyInvocationContext(BaseKeyCacheOperation operation, + public DefaultCacheKeyInvocationContext(AbstractJCacheKeyOperation operation, Object target, Object[] args) { super(operation, target, args); this.keyParameters = operation.getKeyParameters(args); diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/model/DefaultCacheMethodDetails.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/DefaultCacheMethodDetails.java similarity index 76% rename from spring-context-support/src/main/java/org/springframework/cache/jcache/model/DefaultCacheMethodDetails.java rename to spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/DefaultCacheMethodDetails.java index d77760473be..2df8b9740a1 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/model/DefaultCacheMethodDetails.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/DefaultCacheMethodDetails.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cache.jcache.model; +package org.springframework.cache.jcache.interceptor; import static java.util.Arrays.*; @@ -32,7 +32,7 @@ import javax.cache.annotation.CacheMethodDetails; * @author Stephane Nicoll * @since 4.1 */ -public class DefaultCacheMethodDetails implements CacheMethodDetails { +class DefaultCacheMethodDetails implements CacheMethodDetails { private final Method method; @@ -42,8 +42,8 @@ public class DefaultCacheMethodDetails implements CacheMet private final String cacheName; - public DefaultCacheMethodDetails(Method method, A cacheAnnotation, - String cacheName) { + + public DefaultCacheMethodDetails(Method method, A cacheAnnotation, String cacheName) { this.method = method; this.annotations = Collections.unmodifiableSet( new LinkedHashSet(asList(method.getAnnotations()))); @@ -51,32 +51,33 @@ public class DefaultCacheMethodDetails implements CacheMet this.cacheName = cacheName; } + @Override public Method getMethod() { - return method; + return this.method; } @Override public Set getAnnotations() { - return annotations; + return this.annotations; } @Override public A getCacheAnnotation() { - return cacheAnnotation; + return this.cacheAnnotation; } @Override public String getCacheName() { - return cacheName; + return this.cacheName; } @Override public String toString() { - final StringBuilder sb = new StringBuilder("details["); - sb.append("method=").append(method); - sb.append(", cacheAnnotation=").append(cacheAnnotation); - sb.append(", cacheName='").append(cacheName).append('\''); + StringBuilder sb = new StringBuilder("CacheMethodDetails["); + sb.append("method=").append(this.method); + sb.append(", cacheAnnotation=").append(this.cacheAnnotation); + sb.append(", cacheName='").append(this.cacheName).append('\''); sb.append(']'); return sb.toString(); } diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/DefaultJCacheOperationSource.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/DefaultJCacheOperationSource.java index ede0dd2aef7..bd31dbc52bf 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/DefaultJCacheOperationSource.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/DefaultJCacheOperationSource.java @@ -25,6 +25,7 @@ import org.springframework.cache.CacheManager; import org.springframework.cache.interceptor.CacheResolver; import org.springframework.cache.interceptor.KeyGenerator; import org.springframework.cache.interceptor.SimpleCacheResolver; +import org.springframework.cache.interceptor.SimpleKeyGenerator; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.util.Assert; @@ -37,12 +38,14 @@ import org.springframework.util.Assert; * @author Stephane Nicoll * @since 4.1 */ -public class DefaultJCacheOperationSource extends AnnotationCacheOperationSource +public class DefaultJCacheOperationSource extends AnnotationJCacheOperationSource implements InitializingBean, ApplicationContextAware { private CacheManager cacheManager; - private KeyGenerator keyGenerator; + private KeyGenerator keyGenerator = new SimpleKeyGenerator(); + + private KeyGenerator adaptedKeyGenerator; private CacheResolver cacheResolver; @@ -50,23 +53,6 @@ public class DefaultJCacheOperationSource extends AnnotationCacheOperationSource private ApplicationContext applicationContext; - @Override - public void afterPropertiesSet() { - Assert.state((cacheResolver != null && exceptionCacheResolver != null) - || cacheManager != null, "'cacheManager' is required if cache resolvers are not set."); - Assert.state(this.applicationContext != null, "The application context was not injected as it should."); - - if (keyGenerator == null) { - keyGenerator = new KeyGeneratorAdapter(this, new SimpleCacheKeyGenerator()); - } - if (cacheResolver == null) { - cacheResolver = new SimpleCacheResolver(cacheManager); - } - if (exceptionCacheResolver == null) { - exceptionCacheResolver = new SimpleExceptionCacheResolver(cacheManager); - } - } - /** * Set the default {@link CacheManager} to use to lookup cache by name. Only mandatory * if the {@linkplain CacheResolver cache resolvers} have not been set. @@ -76,13 +62,18 @@ public class DefaultJCacheOperationSource extends AnnotationCacheOperationSource } /** - * Set the default {@link KeyGenerator}. If none is set, a default JSR-107 compliant - * key generator is used. + * Set the default {@link KeyGenerator}. If none is set, a {@link SimpleKeyGenerator} + * honoringKe the JSR-107 {@link javax.cache.annotation.CacheKey} and + * {@link javax.cache.annotation.CacheValue} will be used. */ public void setKeyGenerator(KeyGenerator keyGenerator) { this.keyGenerator = keyGenerator; } + public KeyGenerator getKeyGenerator() { + return this.keyGenerator; + } + /** * Set the {@link CacheResolver} to resolve regular caches. If none is set, a default * implementation using the specified cache manager will be used. @@ -91,6 +82,10 @@ public class DefaultJCacheOperationSource extends AnnotationCacheOperationSource this.cacheResolver = cacheResolver; } + public CacheResolver getCacheResolver() { + return this.cacheResolver; + } + /** * Set the {@link CacheResolver} to resolve exception caches. If none is set, a default * implementation using the specified cache manager will be used. @@ -99,14 +94,33 @@ public class DefaultJCacheOperationSource extends AnnotationCacheOperationSource this.exceptionCacheResolver = exceptionCacheResolver; } + public CacheResolver getExceptionCacheResolver() { + return this.exceptionCacheResolver; + } + @Override public void setApplicationContext(ApplicationContext applicationContext) { this.applicationContext = applicationContext; } + @Override + public void afterPropertiesSet() { + Assert.state((this.cacheResolver != null && this.exceptionCacheResolver != null) + || this.cacheManager != null, "'cacheManager' is required if cache resolvers are not set."); + Assert.state(this.applicationContext != null, "The application context was not injected as it should."); + + this.adaptedKeyGenerator = new KeyGeneratorAdapter(this, this.keyGenerator); + if (this.cacheResolver == null) { + this.cacheResolver = new SimpleCacheResolver(this.cacheManager); + } + if (this.exceptionCacheResolver == null) { + this.exceptionCacheResolver = new SimpleExceptionCacheResolver(this.cacheManager); + } + } + @Override protected T getBean(Class type) { - Map map = BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, type); + Map map = BeanFactoryUtils.beansOfTypeIncludingAncestors(this.applicationContext, type); if (map.size() == 1) { return map.values().iterator().next(); } @@ -116,18 +130,18 @@ public class DefaultJCacheOperationSource extends AnnotationCacheOperationSource } @Override - public CacheResolver getDefaultCacheResolver() { - return cacheResolver; + protected CacheResolver getDefaultCacheResolver() { + return this.cacheResolver; } @Override - public CacheResolver getDefaultExceptionCacheResolver() { - return exceptionCacheResolver; + protected CacheResolver getDefaultExceptionCacheResolver() { + return this.exceptionCacheResolver; } @Override - public KeyGenerator getDefaultKeyGenerator() { - return keyGenerator; + protected KeyGenerator getDefaultKeyGenerator() { + return this.adaptedKeyGenerator; } } diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/JCacheAspectSupport.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/JCacheAspectSupport.java index c3b0b2e3204..2c62c4768e3 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/JCacheAspectSupport.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/JCacheAspectSupport.java @@ -25,14 +25,9 @@ import org.apache.commons.logging.LogFactory; import org.springframework.aop.framework.AopProxyUtils; import org.springframework.beans.factory.InitializingBean; import org.springframework.cache.interceptor.AbstractCacheInvoker; -import org.springframework.cache.interceptor.BasicCacheOperation; +import org.springframework.cache.interceptor.BasicOperation; import org.springframework.cache.interceptor.CacheOperationInvocationContext; import org.springframework.cache.interceptor.CacheOperationInvoker; -import org.springframework.cache.jcache.model.CachePutOperation; -import org.springframework.cache.jcache.model.CacheRemoveAllOperation; -import org.springframework.cache.jcache.model.CacheRemoveOperation; -import org.springframework.cache.jcache.model.CacheResultOperation; -import org.springframework.cache.jcache.model.JCacheOperation; import org.springframework.util.Assert; /** @@ -134,7 +129,7 @@ public class JCacheAspectSupport extends AbstractCacheInvoker implements Initial CacheOperationInvoker adapter = new CacheOperationInvokerAdapter(invoker); - BasicCacheOperation operation = context.getOperation(); + BasicOperation operation = context.getOperation(); if (operation instanceof CacheResultOperation) { return cacheResultInterceptor.invoke( (CacheOperationInvocationContext) context, adapter); diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/JCacheInterceptor.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/JCacheInterceptor.java index 469b8299efb..3addafe5bf3 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/JCacheInterceptor.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/JCacheInterceptor.java @@ -35,11 +35,11 @@ import org.springframework.cache.interceptor.CacheOperationInvoker; *

JCacheInterceptors are thread-safe. * * @author Stephane Nicoll + * @since 4.1 * @see org.springframework.cache.interceptor.CacheInterceptor */ @SuppressWarnings("serial") -public class JCacheInterceptor extends JCacheAspectSupport - implements MethodInterceptor, Serializable { +public class JCacheInterceptor extends JCacheAspectSupport implements MethodInterceptor, Serializable { @Override public Object invoke(final MethodInvocation invocation) throws Throwable { diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/model/JCacheOperation.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/JCacheOperation.java similarity index 87% rename from spring-context-support/src/main/java/org/springframework/cache/jcache/model/JCacheOperation.java rename to spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/JCacheOperation.java index fd65033a4d9..37dbddb75a8 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/model/JCacheOperation.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/JCacheOperation.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.cache.jcache.model; +package org.springframework.cache.jcache.interceptor; import java.lang.annotation.Annotation; import javax.cache.annotation.CacheInvocationParameter; import javax.cache.annotation.CacheMethodDetails; -import org.springframework.cache.interceptor.BasicCacheOperation; +import org.springframework.cache.interceptor.BasicOperation; import org.springframework.cache.interceptor.CacheResolver; /** @@ -33,8 +33,7 @@ import org.springframework.cache.interceptor.CacheResolver; * @author Stephane Nicoll * @since 4.1 */ -public interface JCacheOperation - extends CacheMethodDetails, BasicCacheOperation { +public interface JCacheOperation extends BasicOperation, CacheMethodDetails { /** * Return the {@link CacheResolver} instance to use to resolve the cache to diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/JCacheOperationSource.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/JCacheOperationSource.java index cc96976bd55..36177dda86b 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/JCacheOperationSource.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/JCacheOperationSource.java @@ -18,8 +18,6 @@ package org.springframework.cache.jcache.interceptor; import java.lang.reflect.Method; -import org.springframework.cache.jcache.model.JCacheOperation; - /** * Interface used by {@link JCacheInterceptor}. Implementations know how to source * cache operation attributes from standard JSR-107 annotations. diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/KeyGeneratorAdapter.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/KeyGeneratorAdapter.java index aa9655c1c9b..6e18c402776 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/KeyGeneratorAdapter.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/KeyGeneratorAdapter.java @@ -2,58 +2,103 @@ package org.springframework.cache.jcache.interceptor; import java.lang.annotation.Annotation; import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import javax.cache.annotation.CacheInvocationParameter; import javax.cache.annotation.CacheKeyGenerator; import javax.cache.annotation.CacheKeyInvocationContext; import org.springframework.cache.interceptor.KeyGenerator; -import org.springframework.cache.jcache.model.BaseKeyCacheOperation; -import org.springframework.cache.jcache.model.JCacheOperation; import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; /** - * Spring's {@link KeyGenerator} implementation that delegates to a standard - * JSR-107 {@link javax.cache.annotation.CacheKeyGenerator}. - *

Used internally to invoke user-based JSR-107 cache key generators. + * Spring's {@link KeyGenerator} implementation that either delegates to a + * standard JSR-107 {@link javax.cache.annotation.CacheKeyGenerator}, or + * wrap a standard {@link KeyGenerator} so that only relevant parameters + * are handled. * * @author Stephane Nicoll * @since 4.1 */ -public class KeyGeneratorAdapter implements KeyGenerator { +class KeyGeneratorAdapter implements KeyGenerator { private final JCacheOperationSource cacheOperationSource; - private final CacheKeyGenerator target; + private KeyGenerator keyGenerator; - public KeyGeneratorAdapter(JCacheOperationSource cacheOperationSource, CacheKeyGenerator target) { - Assert.notNull(cacheOperationSource, "cacheOperationSource must be set."); - Assert.notNull(target, "cache key generator must be set."); + private CacheKeyGenerator cacheKeyGenerator; + + /** + * Create an instance with the given {@link KeyGenerator} so that {@link javax.cache.annotation.CacheKey} + * and {@link javax.cache.annotation.CacheValue} are handled according to the spec. + */ + public KeyGeneratorAdapter(JCacheOperationSource cacheOperationSource, KeyGenerator target) { + Assert.notNull(cacheOperationSource, "cacheOperationSource must not be null."); + Assert.notNull(target, "KeyGenerator must not be null"); this.cacheOperationSource = cacheOperationSource; - this.target = target; + this.keyGenerator = target; } /** - * Return the underlying {@link CacheKeyGenerator} that this instance is using. + * Create an instance used to wrap the specified {@link javax.cache.annotation.CacheKeyGenerator}. */ - protected CacheKeyGenerator getTarget() { - return target; + public KeyGeneratorAdapter(JCacheOperationSource cacheOperationSource, CacheKeyGenerator target) { + Assert.notNull(cacheOperationSource, "cacheOperationSource must not be null."); + Assert.notNull(target, "KeyGenerator must not be null"); + this.cacheOperationSource = cacheOperationSource; + this.cacheKeyGenerator = target; } + /** + * Return the target key generator to use in the form of either a {@link KeyGenerator} + * or a {@link CacheKeyGenerator}. + */ + public Object getTarget() { + return (this.keyGenerator != null ? this.keyGenerator : this.cacheKeyGenerator); + } + + @Override public Object generate(Object target, Method method, Object... params) { - JCacheOperation operation = cacheOperationSource.getCacheOperation(method, target.getClass()); - if (!(BaseKeyCacheOperation.class.isInstance(operation))) { + JCacheOperation operation = this.cacheOperationSource.getCacheOperation(method, target.getClass()); + if (!(AbstractJCacheKeyOperation.class.isInstance(operation))) { throw new IllegalStateException("Invalid operation, should be a key-based operation " + operation); } CacheKeyInvocationContext invocationContext = createCacheKeyInvocationContext(target, operation, params); - return this.target.generateCacheKey(invocationContext); + if (this.cacheKeyGenerator != null) { + return this.cacheKeyGenerator.generateCacheKey(invocationContext); + } + else { + return doGenerate(this.keyGenerator, invocationContext); + } } + @SuppressWarnings("unchecked") + private static Object doGenerate(KeyGenerator keyGenerator, CacheKeyInvocationContext context) { + List parameters = new ArrayList(); + for (CacheInvocationParameter param : context.getKeyParameters()) { + Object value = param.getValue(); + if (param.getParameterPosition() == context.getAllParameters().length - 1 && + context.getMethod().isVarArgs()) { + parameters.addAll((List) CollectionUtils.arrayToList(value)); + } + else { + parameters.add(value); + } + } + return keyGenerator.generate(context.getTarget(), context.getMethod(), + parameters.toArray(new Object[parameters.size()])); + + } + + @SuppressWarnings("unchecked") private CacheKeyInvocationContext createCacheKeyInvocationContext(Object target, JCacheOperation operation, Object[] params) { - BaseKeyCacheOperation keyCacheOperation = (BaseKeyCacheOperation) operation; + AbstractJCacheKeyOperation keyCacheOperation = (AbstractJCacheKeyOperation) operation; return new DefaultCacheKeyInvocationContext(keyCacheOperation, target, params); } diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/SimpleCacheKeyGenerator.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/SimpleCacheKeyGenerator.java deleted file mode 100644 index cc020dd3163..00000000000 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/SimpleCacheKeyGenerator.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2002-2014 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.jcache.interceptor; - -import java.lang.annotation.Annotation; - -import javax.cache.annotation.CacheInvocationParameter; -import javax.cache.annotation.CacheKeyGenerator; -import javax.cache.annotation.CacheKeyInvocationContext; -import javax.cache.annotation.GeneratedCacheKey; - -/** - * A JSR-107 compliant key generator. Uses only the parameters that have been annotated - * with {@link javax.cache.annotation.CacheKey} or all of them if none are set, except - * the {@link javax.cache.annotation.CacheValue} one. - * - * @author Stephane Nicoll - * @since 4.1 - * @see javax.cache.annotation.CacheKeyInvocationContext#getKeyParameters() - */ -public class SimpleCacheKeyGenerator implements CacheKeyGenerator { - - @Override - public GeneratedCacheKey generateCacheKey(CacheKeyInvocationContext context) { - CacheInvocationParameter[] keyParameters = context.getKeyParameters(); - final Object[] parameters = new Object[keyParameters.length]; - for (int i = 0; i < keyParameters.length; i++) { - parameters[i] = keyParameters[i].getValue(); - } - return new SimpleGeneratedCacheKey(parameters); - } - -} diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/SimpleExceptionCacheResolver.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/SimpleExceptionCacheResolver.java index 0809e13bc40..18d0292cd16 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/SimpleExceptionCacheResolver.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/SimpleExceptionCacheResolver.java @@ -20,11 +20,10 @@ import java.util.Collection; import java.util.Collections; import org.springframework.cache.CacheManager; -import org.springframework.cache.interceptor.BaseCacheResolver; -import org.springframework.cache.interceptor.BasicCacheOperation; +import org.springframework.cache.interceptor.AbstractCacheResolver; +import org.springframework.cache.interceptor.BasicOperation; import org.springframework.cache.interceptor.CacheOperationInvocationContext; import org.springframework.cache.interceptor.CacheResolver; -import org.springframework.cache.jcache.model.CacheResultOperation; /** * A simple {@link CacheResolver} that resolves the exception cache @@ -33,9 +32,9 @@ import org.springframework.cache.jcache.model.CacheResultOperation; * * @author Stephane Nicoll * @since 4.1 - * @see org.springframework.cache.jcache.model.CacheResultOperation#getExceptionCacheName() + * @see CacheResultOperation#getExceptionCacheName() */ -public class SimpleExceptionCacheResolver extends BaseCacheResolver { +public class SimpleExceptionCacheResolver extends AbstractCacheResolver { public SimpleExceptionCacheResolver(CacheManager cacheManager) { super(cacheManager); @@ -43,7 +42,7 @@ public class SimpleExceptionCacheResolver extends BaseCacheResolver { @Override protected Collection getCacheNames(CacheOperationInvocationContext context) { - BasicCacheOperation operation = context.getOperation(); + BasicOperation operation = context.getOperation(); if (!(operation instanceof CacheResultOperation)) { throw new IllegalStateException("Could not extract exception cache name from " + operation); } diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/SimpleGeneratedCacheKey.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/SimpleGeneratedCacheKey.java deleted file mode 100644 index a1f98a75fa1..00000000000 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/SimpleGeneratedCacheKey.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.springframework.cache.jcache.interceptor; - -import javax.cache.annotation.GeneratedCacheKey; - -import org.springframework.cache.interceptor.SimpleKey; - -/** - * A {@link SimpleKey} that implements the {@link GeneratedCacheKey} contract - * required by JSR-107 - * - * @author Stephane Nicoll - */ -@SuppressWarnings("serial") -public final class SimpleGeneratedCacheKey extends SimpleKey implements GeneratedCacheKey { - - public SimpleGeneratedCacheKey(Object... elements) { - super(elements); - } - -} diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/model/package-info.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/model/package-info.java deleted file mode 100644 index cb6fa53e260..00000000000 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/model/package-info.java +++ /dev/null @@ -1,5 +0,0 @@ -/** - * Resolved model of JSR-107 cache annotations. Used internally by the interceptors - * in org.springframework.cache.jcache.interceptor. - */ -package org.springframework.cache.jcache.model; \ No newline at end of file diff --git a/spring-context-support/src/test/java/org/springframework/cache/jcache/config/AbstractJCacheAnnotationTests.java b/spring-context-support/src/test/java/org/springframework/cache/jcache/config/AbstractJCacheAnnotationTests.java index f81402e538f..cd4eb3a23bc 100644 --- a/spring-context-support/src/test/java/org/springframework/cache/jcache/config/AbstractJCacheAnnotationTests.java +++ b/spring-context-support/src/test/java/org/springframework/cache/jcache/config/AbstractJCacheAnnotationTests.java @@ -28,7 +28,7 @@ import org.junit.rules.TestName; import org.springframework.cache.Cache; import org.springframework.cache.CacheManager; -import org.springframework.cache.jcache.interceptor.SimpleGeneratedCacheKey; +import org.springframework.cache.interceptor.SimpleKeyGenerator; import org.springframework.context.ApplicationContext; /** @@ -523,7 +523,7 @@ public abstract class AbstractJCacheAnnotationTests { private Object createKey(Object... params) { - return new SimpleGeneratedCacheKey(params); + return SimpleKeyGenerator.generateKey(params); } private Cache getCache(String name) { diff --git a/spring-context-support/src/test/java/org/springframework/cache/jcache/config/JCacheJavaConfigTests.java b/spring-context-support/src/test/java/org/springframework/cache/jcache/config/JCacheJavaConfigTests.java index 6952697b38b..29ef6c6651d 100644 --- a/spring-context-support/src/test/java/org/springframework/cache/jcache/config/JCacheJavaConfigTests.java +++ b/spring-context-support/src/test/java/org/springframework/cache/jcache/config/JCacheJavaConfigTests.java @@ -61,11 +61,11 @@ public class JCacheJavaConfigTests extends AbstractJCacheAnnotationTests { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(FullCachingConfig.class); DefaultJCacheOperationSource cos = context.getBean(DefaultJCacheOperationSource.class); - assertSame(context.getBean(KeyGenerator.class), cos.getDefaultKeyGenerator()); + assertSame(context.getBean(KeyGenerator.class), cos.getKeyGenerator()); assertSame(context.getBean("cacheResolver", CacheResolver.class), - cos.getDefaultCacheResolver()); + cos.getCacheResolver()); assertSame(context.getBean("exceptionCacheResolver", CacheResolver.class), - cos.getDefaultExceptionCacheResolver()); + cos.getExceptionCacheResolver()); JCacheInterceptor interceptor = context.getBean(JCacheInterceptor.class); assertSame(context.getBean("errorHandler", CacheErrorHandler.class), interceptor.getErrorHandler()); } @@ -76,14 +76,14 @@ public class JCacheJavaConfigTests extends AbstractJCacheAnnotationTests { new AnnotationConfigApplicationContext(EmptyConfigSupportConfig.class); DefaultJCacheOperationSource cos = context.getBean(DefaultJCacheOperationSource.class); - assertNotNull(cos.getDefaultCacheResolver()); - assertEquals(SimpleCacheResolver.class, cos.getDefaultCacheResolver().getClass()); + assertNotNull(cos.getCacheResolver()); + assertEquals(SimpleCacheResolver.class, cos.getCacheResolver().getClass()); assertSame(context.getBean(CacheManager.class), - ((SimpleCacheResolver) cos.getDefaultCacheResolver()).getCacheManager()); - assertNotNull(cos.getDefaultExceptionCacheResolver()); - assertEquals(SimpleExceptionCacheResolver.class, cos.getDefaultExceptionCacheResolver().getClass()); + ((SimpleCacheResolver) cos.getCacheResolver()).getCacheManager()); + assertNotNull(cos.getExceptionCacheResolver()); + assertEquals(SimpleExceptionCacheResolver.class, cos.getExceptionCacheResolver().getClass()); assertSame(context.getBean(CacheManager.class), - ((SimpleExceptionCacheResolver) cos.getDefaultExceptionCacheResolver()).getCacheManager()); + ((SimpleExceptionCacheResolver) cos.getExceptionCacheResolver()).getCacheManager()); context.close(); } @@ -93,9 +93,9 @@ public class JCacheJavaConfigTests extends AbstractJCacheAnnotationTests { new AnnotationConfigApplicationContext(FullCachingConfigSupport.class); DefaultJCacheOperationSource cos = context.getBean(DefaultJCacheOperationSource.class); - assertSame(context.getBean("cacheResolver"), cos.getDefaultCacheResolver()); - assertSame(context.getBean("keyGenerator"), cos.getDefaultKeyGenerator()); - assertSame(context.getBean("exceptionCacheResolver"), cos.getDefaultExceptionCacheResolver()); + assertSame(context.getBean("cacheResolver"), cos.getCacheResolver()); + assertSame(context.getBean("keyGenerator"), cos.getKeyGenerator()); + assertSame(context.getBean("exceptionCacheResolver"), cos.getExceptionCacheResolver()); context.close(); } diff --git a/spring-context-support/src/test/java/org/springframework/cache/jcache/config/JCacheNamespaceDrivenTests.java b/spring-context-support/src/test/java/org/springframework/cache/jcache/config/JCacheNamespaceDrivenTests.java index 0cdef3f159a..e5efebbc6e3 100644 --- a/spring-context-support/src/test/java/org/springframework/cache/jcache/config/JCacheNamespaceDrivenTests.java +++ b/spring-context-support/src/test/java/org/springframework/cache/jcache/config/JCacheNamespaceDrivenTests.java @@ -44,7 +44,7 @@ public class JCacheNamespaceDrivenTests extends AbstractJCacheAnnotationTests { "/org/springframework/cache/jcache/config/jCacheNamespaceDriven-resolver.xml"); DefaultJCacheOperationSource ci = context.getBean(DefaultJCacheOperationSource.class); - assertSame(context.getBean("cacheResolver"), ci.getDefaultCacheResolver()); + assertSame(context.getBean("cacheResolver"), ci.getCacheResolver()); context.close(); } diff --git a/spring-context-support/src/test/java/org/springframework/cache/jcache/model/AbstractCacheOperationTests.java b/spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/AbstractCacheOperationTests.java similarity index 98% rename from spring-context-support/src/test/java/org/springframework/cache/jcache/model/AbstractCacheOperationTests.java rename to spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/AbstractCacheOperationTests.java index 1e72f13922e..4ba8d7f807d 100644 --- a/spring-context-support/src/test/java/org/springframework/cache/jcache/model/AbstractCacheOperationTests.java +++ b/spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/AbstractCacheOperationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cache.jcache.model; +package org.springframework.cache.jcache.interceptor; import static org.junit.Assert.*; diff --git a/spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/AnnotatedJCacheableService.java b/spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/AnnotatedJCacheableService.java index e3e0caf2cb4..dc3f3b46ec0 100644 --- a/spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/AnnotatedJCacheableService.java +++ b/spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/AnnotatedJCacheableService.java @@ -29,6 +29,7 @@ import javax.cache.annotation.CacheResult; import javax.cache.annotation.CacheValue; import org.springframework.cache.Cache; +import org.springframework.cache.interceptor.SimpleKeyGenerator; import org.springframework.cache.jcache.config.JCacheableService; import org.springframework.cache.jcache.support.TestableCacheKeyGenerator; import org.springframework.cache.jcache.support.TestableCacheResolverFactory; @@ -109,7 +110,7 @@ public class AnnotatedJCacheableService implements JCacheableService { @Override @CachePut(afterInvocation = false) public void earlyPut(String id, @CacheValue Object value) { - SimpleGeneratedCacheKey key = new SimpleGeneratedCacheKey(id); + Object key = SimpleKeyGenerator.generateKey(id); Cache.ValueWrapper valueWrapper = defaultCache.get(key); if (valueWrapper == null) { throw new AssertionError("Excepted value to be put in cache with key " + key); @@ -141,7 +142,7 @@ public class AnnotatedJCacheableService implements JCacheableService { @Override @CacheRemove(afterInvocation = false) public void earlyRemove(String id) { - SimpleGeneratedCacheKey key = new SimpleGeneratedCacheKey(id); + Object key = SimpleKeyGenerator.generateKey(id); Cache.ValueWrapper valueWrapper = defaultCache.get(key); if (valueWrapper != null) { throw new AssertionError("Value with key " + key + " expected to be already remove from cache"); diff --git a/spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/AnnotationCacheOperationSourceTests.java b/spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/AnnotationCacheOperationSourceTests.java index dd74f59b065..0268b57499a 100644 --- a/spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/AnnotationCacheOperationSourceTests.java +++ b/spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/AnnotationCacheOperationSourceTests.java @@ -34,12 +34,6 @@ import org.junit.Test; import org.springframework.cache.interceptor.CacheResolver; import org.springframework.cache.interceptor.KeyGenerator; import org.springframework.cache.jcache.AbstractJCacheTests; -import org.springframework.cache.jcache.model.BaseKeyCacheOperation; -import org.springframework.cache.jcache.model.CachePutOperation; -import org.springframework.cache.jcache.model.CacheRemoveAllOperation; -import org.springframework.cache.jcache.model.CacheRemoveOperation; -import org.springframework.cache.jcache.model.CacheResultOperation; -import org.springframework.cache.jcache.model.JCacheOperation; import org.springframework.cache.jcache.support.TestableCacheKeyGenerator; import org.springframework.cache.jcache.support.TestableCacheResolver; import org.springframework.cache.jcache.support.TestableCacheResolverFactory; @@ -142,7 +136,8 @@ public class AnnotationCacheOperationSourceTests extends AbstractJCacheTests { getCacheOperation(CacheResultOperation.class, CustomService.class, name.getMethodName(), Long.class); assertJCacheResolver(operation.getCacheResolver(), TestableCacheResolver.class); assertJCacheResolver(operation.getExceptionCacheResolver(), null); - assertEquals(defaultKeyGenerator, operation.getKeyGenerator()); + assertEquals(KeyGeneratorAdapter.class, operation.getKeyGenerator().getClass()); + assertEquals(defaultKeyGenerator, ((KeyGeneratorAdapter) operation.getKeyGenerator()).getTarget()); } @Test @@ -184,9 +179,10 @@ public class AnnotationCacheOperationSourceTests extends AbstractJCacheTests { assertCacheKeyGenerator(operation.getKeyGenerator(), TestableCacheKeyGenerator.class); } - private void assertDefaults(BaseKeyCacheOperation operation) { + private void assertDefaults(AbstractJCacheKeyOperation operation) { assertEquals(defaultCacheResolver, operation.getCacheResolver()); - assertEquals(defaultKeyGenerator, operation.getKeyGenerator()); + assertEquals(KeyGeneratorAdapter.class, operation.getKeyGenerator().getClass()); + assertEquals(defaultKeyGenerator, ((KeyGeneratorAdapter) operation.getKeyGenerator()).getTarget()); } protected > T getDefaultCacheOperation(Class operationType, Class... parameterTypes) { diff --git a/spring-context-support/src/test/java/org/springframework/cache/jcache/model/CachePutOperationTests.java b/spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/CachePutOperationTests.java similarity index 98% rename from spring-context-support/src/test/java/org/springframework/cache/jcache/model/CachePutOperationTests.java rename to spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/CachePutOperationTests.java index 727be16a8f8..c9eaa5f67f6 100644 --- a/spring-context-support/src/test/java/org/springframework/cache/jcache/model/CachePutOperationTests.java +++ b/spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/CachePutOperationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cache.jcache.model; +package org.springframework.cache.jcache.interceptor; import static org.junit.Assert.*; diff --git a/spring-context-support/src/test/java/org/springframework/cache/jcache/model/CacheRemoveAllOperationTests.java b/spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/CacheRemoveAllOperationTests.java similarity index 96% rename from spring-context-support/src/test/java/org/springframework/cache/jcache/model/CacheRemoveAllOperationTests.java rename to spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/CacheRemoveAllOperationTests.java index 55937e207a2..7ee654ed80f 100644 --- a/spring-context-support/src/test/java/org/springframework/cache/jcache/model/CacheRemoveAllOperationTests.java +++ b/spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/CacheRemoveAllOperationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cache.jcache.model; +package org.springframework.cache.jcache.interceptor; import static org.junit.Assert.*; diff --git a/spring-context-support/src/test/java/org/springframework/cache/jcache/model/CacheRemoveOperationTests.java b/spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/CacheRemoveOperationTests.java similarity index 96% rename from spring-context-support/src/test/java/org/springframework/cache/jcache/model/CacheRemoveOperationTests.java rename to spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/CacheRemoveOperationTests.java index 91dbc9d6508..19c3963b355 100644 --- a/spring-context-support/src/test/java/org/springframework/cache/jcache/model/CacheRemoveOperationTests.java +++ b/spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/CacheRemoveOperationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cache.jcache.model; +package org.springframework.cache.jcache.interceptor; import static org.junit.Assert.*; diff --git a/spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/CacheResolverAdapterTests.java b/spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/CacheResolverAdapterTests.java index e6ca576d3e1..95c27ea2d99 100644 --- a/spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/CacheResolverAdapterTests.java +++ b/spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/CacheResolverAdapterTests.java @@ -34,8 +34,6 @@ import org.junit.rules.ExpectedException; import org.springframework.cache.Cache; import org.springframework.cache.jcache.AbstractJCacheTests; -import org.springframework.cache.jcache.model.CacheResultOperation; -import org.springframework.cache.jcache.model.DefaultCacheMethodDetails; import org.springframework.util.Assert; import org.springframework.util.ReflectionUtils; diff --git a/spring-context-support/src/test/java/org/springframework/cache/jcache/model/CacheResultOperationTests.java b/spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/CacheResultOperationTests.java similarity index 98% rename from spring-context-support/src/test/java/org/springframework/cache/jcache/model/CacheResultOperationTests.java rename to spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/CacheResultOperationTests.java index e6102eaeaa1..4cb9261d24e 100644 --- a/spring-context-support/src/test/java/org/springframework/cache/jcache/model/CacheResultOperationTests.java +++ b/spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/CacheResultOperationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cache.jcache.model; +package org.springframework.cache.jcache.interceptor; import static org.junit.Assert.*; diff --git a/spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/JCacheErrorHandlerTests.java b/spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/JCacheErrorHandlerTests.java index 96768a32109..34c4a8eb256 100644 --- a/spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/JCacheErrorHandlerTests.java +++ b/spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/JCacheErrorHandlerTests.java @@ -40,6 +40,7 @@ import org.springframework.cache.Cache; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.interceptor.CacheErrorHandler; +import org.springframework.cache.interceptor.SimpleKeyGenerator; import org.springframework.cache.jcache.config.JCacheConfigurerSupport; import org.springframework.cache.support.SimpleCacheManager; import org.springframework.context.annotation.AnnotationConfigApplicationContext; @@ -72,7 +73,7 @@ public class JCacheErrorHandlerTests { @Test public void getFail() { UnsupportedOperationException exception = new UnsupportedOperationException("Test exception on get"); - SimpleGeneratedCacheKey key = new SimpleGeneratedCacheKey(0L); + Object key = SimpleKeyGenerator.generateKey(0L); doThrow(exception).when(cache).get(key); this.simpleService.get(0L); @@ -82,7 +83,7 @@ public class JCacheErrorHandlerTests { @Test public void putFail() { UnsupportedOperationException exception = new UnsupportedOperationException("Test exception on put"); - SimpleGeneratedCacheKey key = new SimpleGeneratedCacheKey(0L); + Object key = SimpleKeyGenerator.generateKey(0L); doThrow(exception).when(cache).put(key, 234L); this.simpleService.put(0L, 234L); @@ -92,7 +93,7 @@ public class JCacheErrorHandlerTests { @Test public void evictFail() { UnsupportedOperationException exception = new UnsupportedOperationException("Test exception on evict"); - SimpleGeneratedCacheKey key = new SimpleGeneratedCacheKey(0L); + Object key = SimpleKeyGenerator.generateKey(0L); doThrow(exception).when(cache).evict(key); this.simpleService.evict(0L); diff --git a/spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/JCacheKeyGeneratorTests.java b/spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/JCacheKeyGeneratorTests.java new file mode 100644 index 00000000000..3998bbd9690 --- /dev/null +++ b/spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/JCacheKeyGeneratorTests.java @@ -0,0 +1,159 @@ +/* + * Copyright 2002-2014 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.jcache.interceptor; + +import static org.junit.Assert.*; + +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.concurrent.atomic.AtomicLong; + +import javax.cache.annotation.CacheDefaults; +import javax.cache.annotation.CacheKey; +import javax.cache.annotation.CacheResult; + +import org.junit.Before; +import org.junit.Test; + +import org.springframework.cache.Cache; +import org.springframework.cache.CacheManager; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.cache.concurrent.ConcurrentMapCacheManager; +import org.springframework.cache.interceptor.KeyGenerator; +import org.springframework.cache.interceptor.SimpleKey; +import org.springframework.cache.interceptor.SimpleKeyGenerator; +import org.springframework.cache.jcache.config.JCacheConfigurerSupport; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * + * @author Stephane Nicoll + */ +public class JCacheKeyGeneratorTests { + + private TestKeyGenerator keyGenerator; + + private SimpleService simpleService; + + private Cache cache; + + @Before + public void setup() { + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class); + this.keyGenerator = context.getBean(TestKeyGenerator.class); + this.simpleService = context.getBean(SimpleService.class); + this.cache = context.getBean(CacheManager.class).getCache("test"); + } + + @Test + public void getSimple() { + this.keyGenerator.expect(1L); + Object first = this.simpleService.get(1L); + Object second = this.simpleService.get(1L); + assertSame(first, second); + + Object key = new SimpleKey(1L); + assertEquals(first, cache.get(key).get()); + } + + @Test + public void getFlattenVararg() { + this.keyGenerator.expect(1L, "foo", "bar"); + Object first = this.simpleService.get(1L, "foo", "bar"); + Object second = this.simpleService.get(1L, "foo", "bar"); + assertSame(first, second); + + Object key = new SimpleKey(1L, "foo", "bar"); + assertEquals(first, cache.get(key).get()); + } + + @Test + public void getFiltered() { + this.keyGenerator.expect(1L); + Object first = this.simpleService.getFiltered(1L, "foo", "bar"); + Object second = this.simpleService.getFiltered(1L, "foo", "bar"); + assertSame(first, second); + + Object key = new SimpleKey(1L); + assertEquals(first, cache.get(key).get()); + } + + + @Configuration + @EnableCaching + static class Config extends JCacheConfigurerSupport { + + @Bean + @Override + public CacheManager cacheManager() { + return new ConcurrentMapCacheManager(); + } + + @Bean + @Override + public KeyGenerator keyGenerator() { + return new TestKeyGenerator(); + } + + @Bean + public SimpleService simpleService() { + return new SimpleService(); + } + + } + + @CacheDefaults(cacheName = "test") + public static class SimpleService { + private AtomicLong counter = new AtomicLong(); + + @CacheResult + public Object get(long id) { + return counter.getAndIncrement(); + } + + @CacheResult + public Object get(long id, String... items) { + return counter.getAndIncrement(); + } + + @CacheResult + public Object getFiltered(@CacheKey long id, String... items) { + return counter.getAndIncrement(); + } + + } + + + private static class TestKeyGenerator extends SimpleKeyGenerator { + + private Object[] expectedParams; + + private void expect(Object... params) { + this.expectedParams = params; + } + + @Override + public Object generate(Object target, Method method, Object... params) { + assertTrue("Unexpected parameters: expected: " + + Arrays.toString(this.expectedParams) + " but got: " + Arrays.toString(params), + Arrays.equals(expectedParams, params)); + return new SimpleKey(params); + } + } +} diff --git a/spring-context-support/src/test/java/org/springframework/cache/jcache/model/SampleObject.java b/spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/SampleObject.java similarity index 97% rename from spring-context-support/src/test/java/org/springframework/cache/jcache/model/SampleObject.java rename to spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/SampleObject.java index baf2d077a8c..60a2ee5fd57 100644 --- a/spring-context-support/src/test/java/org/springframework/cache/jcache/model/SampleObject.java +++ b/spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/SampleObject.java @@ -1,4 +1,4 @@ -package org.springframework.cache.jcache.model; +package org.springframework.cache.jcache.interceptor; import javax.cache.annotation.CacheKey; import javax.cache.annotation.CachePut; diff --git a/spring-context-support/src/test/java/org/springframework/cache/jcache/support/TestableCacheKeyGenerator.java b/spring-context-support/src/test/java/org/springframework/cache/jcache/support/TestableCacheKeyGenerator.java index db260026f25..0dc4a471e27 100644 --- a/spring-context-support/src/test/java/org/springframework/cache/jcache/support/TestableCacheKeyGenerator.java +++ b/spring-context-support/src/test/java/org/springframework/cache/jcache/support/TestableCacheKeyGenerator.java @@ -6,7 +6,7 @@ import javax.cache.annotation.CacheKeyGenerator; import javax.cache.annotation.CacheKeyInvocationContext; import javax.cache.annotation.GeneratedCacheKey; -import org.springframework.cache.jcache.interceptor.SimpleGeneratedCacheKey; +import org.springframework.cache.interceptor.SimpleKey; /** * A simple test key generator that only takes the first key arguments into @@ -22,4 +22,13 @@ public class TestableCacheKeyGenerator implements CacheKeyGenerator { return new SimpleGeneratedCacheKey(context.getKeyParameters()[0]); } + + private static class SimpleGeneratedCacheKey extends SimpleKey implements GeneratedCacheKey { + + public SimpleGeneratedCacheKey(Object... elements) { + super(elements); + } + + } + } diff --git a/spring-context/src/main/java/org/springframework/cache/interceptor/BaseCacheResolver.java b/spring-context/src/main/java/org/springframework/cache/interceptor/AbstractCacheResolver.java similarity index 82% rename from spring-context/src/main/java/org/springframework/cache/interceptor/BaseCacheResolver.java rename to spring-context/src/main/java/org/springframework/cache/interceptor/AbstractCacheResolver.java index f95ae11a2db..0ddb97460ac 100644 --- a/spring-context/src/main/java/org/springframework/cache/interceptor/BaseCacheResolver.java +++ b/spring-context/src/main/java/org/springframework/cache/interceptor/AbstractCacheResolver.java @@ -33,16 +33,18 @@ import org.springframework.util.Assert; * @author Stephane Nicoll * @since 4.1 */ -public abstract class BaseCacheResolver implements CacheResolver, InitializingBean { +public abstract class AbstractCacheResolver implements CacheResolver, InitializingBean { private CacheManager cacheManager; - protected BaseCacheResolver(CacheManager cacheManager) { + + protected AbstractCacheResolver() { + } + + protected AbstractCacheResolver(CacheManager cacheManager) { this.cacheManager = cacheManager; } - protected BaseCacheResolver() { - } /** * Set the {@link CacheManager} that this instance should use. @@ -55,14 +57,15 @@ public abstract class BaseCacheResolver implements CacheResolver, InitializingBe * Return the {@link CacheManager} that this instance use. */ public CacheManager getCacheManager() { - return cacheManager; + return this.cacheManager; } @Override public void afterPropertiesSet() { - Assert.notNull(cacheManager, "CacheManager must not be null"); + Assert.notNull(this.cacheManager, "CacheManager must not be null"); } + @Override public Collection resolveCaches(CacheOperationInvocationContext context) { Collection cacheNames = getCacheNames(context); @@ -72,8 +75,11 @@ public abstract class BaseCacheResolver implements CacheResolver, InitializingBe else { Collection result = new ArrayList(); for (String cacheName : cacheNames) { - Cache cache = cacheManager.getCache(cacheName); - Assert.notNull(cache, "Cannot find cache named '" + cacheName + "' for " + context.getOperation()); + Cache cache = this.cacheManager.getCache(cacheName); + if (cache == null) { + throw new IllegalArgumentException("Cannot find cache named '" + + cacheName + "' for " + context.getOperation()); + } result.add(cache); } return result; @@ -84,7 +90,6 @@ public abstract class BaseCacheResolver implements CacheResolver, InitializingBe * Provide the name of the cache(s) to resolve against the current cache manager. *

It is acceptable to return {@code null} to indicate that no cache could * be resolved for this invocation. - * * @param context the context of the particular invocation * @return the cache name(s) to resolve or {@code null} if no cache should be resolved */ diff --git a/spring-context/src/main/java/org/springframework/cache/interceptor/BasicCacheOperation.java b/spring-context/src/main/java/org/springframework/cache/interceptor/BasicOperation.java similarity index 95% rename from spring-context/src/main/java/org/springframework/cache/interceptor/BasicCacheOperation.java rename to spring-context/src/main/java/org/springframework/cache/interceptor/BasicOperation.java index 477d808f2aa..194874f5817 100644 --- a/spring-context/src/main/java/org/springframework/cache/interceptor/BasicCacheOperation.java +++ b/spring-context/src/main/java/org/springframework/cache/interceptor/BasicOperation.java @@ -24,7 +24,7 @@ import java.util.Set; * @author Stephane Nicoll * @since 4.1 */ -public interface BasicCacheOperation { +public interface BasicOperation { /** * Return the cache name(s) associated to the operation. diff --git a/spring-context/src/main/java/org/springframework/cache/interceptor/CacheOperation.java b/spring-context/src/main/java/org/springframework/cache/interceptor/CacheOperation.java index cc71cf62842..8bdbafc3a1d 100644 --- a/spring-context/src/main/java/org/springframework/cache/interceptor/CacheOperation.java +++ b/spring-context/src/main/java/org/springframework/cache/interceptor/CacheOperation.java @@ -29,7 +29,7 @@ import org.springframework.util.Assert; * @author Stephane Nicoll * @since 3.1 */ -public abstract class CacheOperation implements BasicCacheOperation { +public abstract class CacheOperation implements BasicOperation { private Set cacheNames = Collections.emptySet(); diff --git a/spring-context/src/main/java/org/springframework/cache/interceptor/CacheOperationInvocationContext.java b/spring-context/src/main/java/org/springframework/cache/interceptor/CacheOperationInvocationContext.java index f643e6d0f46..9d2e3977404 100644 --- a/spring-context/src/main/java/org/springframework/cache/interceptor/CacheOperationInvocationContext.java +++ b/spring-context/src/main/java/org/springframework/cache/interceptor/CacheOperationInvocationContext.java @@ -27,7 +27,7 @@ import java.lang.reflect.Method; * @author Stephane Nicoll * @since 4.1 */ -public interface CacheOperationInvocationContext { +public interface CacheOperationInvocationContext { /** * Return the cache operation diff --git a/spring-context/src/main/java/org/springframework/cache/interceptor/NamedCacheResolver.java b/spring-context/src/main/java/org/springframework/cache/interceptor/NamedCacheResolver.java index a629a46c06a..51e95c15330 100644 --- a/spring-context/src/main/java/org/springframework/cache/interceptor/NamedCacheResolver.java +++ b/spring-context/src/main/java/org/springframework/cache/interceptor/NamedCacheResolver.java @@ -30,7 +30,7 @@ import org.springframework.cache.CacheManager; * @author Stephane Nicoll * @since 4.1 */ -public class NamedCacheResolver extends BaseCacheResolver { +public class NamedCacheResolver extends AbstractCacheResolver { private Collection cacheNames; diff --git a/spring-context/src/main/java/org/springframework/cache/interceptor/SimpleCacheResolver.java b/spring-context/src/main/java/org/springframework/cache/interceptor/SimpleCacheResolver.java index 7eb01e19bfc..1b40d2d1212 100644 --- a/spring-context/src/main/java/org/springframework/cache/interceptor/SimpleCacheResolver.java +++ b/spring-context/src/main/java/org/springframework/cache/interceptor/SimpleCacheResolver.java @@ -24,13 +24,13 @@ import org.springframework.cache.CacheManager; /** * A simple {@link CacheResolver} that resolves the {@link Cache} instance(s) * based on a configurable {@link CacheManager} and the name of the - * cache(s) as provided by {@link BasicCacheOperation#getCacheNames() getCacheNames()} + * cache(s) as provided by {@link BasicOperation#getCacheNames() getCacheNames()} * * @author Stephane Nicoll * @since 4.1 - * @see BasicCacheOperation#getCacheNames() + * @see BasicOperation#getCacheNames() */ -public class SimpleCacheResolver extends BaseCacheResolver { +public class SimpleCacheResolver extends AbstractCacheResolver { public SimpleCacheResolver() { } diff --git a/spring-context/src/main/java/org/springframework/cache/interceptor/SimpleKeyGenerator.java b/spring-context/src/main/java/org/springframework/cache/interceptor/SimpleKeyGenerator.java index 452fe4bc19b..d6feb425654 100644 --- a/spring-context/src/main/java/org/springframework/cache/interceptor/SimpleKeyGenerator.java +++ b/spring-context/src/main/java/org/springframework/cache/interceptor/SimpleKeyGenerator.java @@ -39,6 +39,13 @@ public class SimpleKeyGenerator implements KeyGenerator { @Override public Object generate(Object target, Method method, Object... params) { + return generateKey(params); + } + + /** + * Generate a key based on the specified parameters. + */ + public static Object generateKey(Object... params) { if (params.length == 0) { return SimpleKey.EMPTY; } diff --git a/spring-context/src/test/java/org/springframework/cache/interceptor/CacheResolverCustomisationTests.java b/spring-context/src/test/java/org/springframework/cache/interceptor/CacheResolverCustomisationTests.java index 148a79df9e3..1a2bd2d27f8 100644 --- a/spring-context/src/test/java/org/springframework/cache/interceptor/CacheResolverCustomisationTests.java +++ b/spring-context/src/test/java/org/springframework/cache/interceptor/CacheResolverCustomisationTests.java @@ -250,7 +250,7 @@ public class CacheResolverCustomisationTests { * runtime (i.e. based on method invocation parameters). *

Expects the second argument to hold the name of the cache to use */ - private static class RuntimeCacheResolver extends BaseCacheResolver { + private static class RuntimeCacheResolver extends AbstractCacheResolver { private RuntimeCacheResolver(CacheManager cacheManager) { super(cacheManager); @@ -263,7 +263,7 @@ public class CacheResolverCustomisationTests { } } - private static class NullCacheResolver extends BaseCacheResolver { + private static class NullCacheResolver extends AbstractCacheResolver { private NullCacheResolver(CacheManager cacheManager) { super(cacheManager);