Fixed accidental use of JDK 8 getOrDefault method on MultiValueMap

Issue: SPR-10807
This commit is contained in:
Juergen Hoeller
2013-08-06 01:45:08 +02:00
parent 2626a35f2c
commit 9645799264

View File

@@ -25,6 +25,7 @@ import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.framework.AopProxyUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.cache.Cache;
@@ -67,19 +68,65 @@ public abstract class CacheAspectSupport implements InitializingBean {
protected final Log logger = LogFactory.getLog(getClass());
private final ExpressionEvaluator evaluator = new ExpressionEvaluator();
private CacheManager cacheManager;
private CacheOperationSource cacheOperationSource;
private final ExpressionEvaluator evaluator = new ExpressionEvaluator();
private KeyGenerator keyGenerator = new SimpleKeyGenerator();
private boolean initialized = false;
@Override
/**
* Set the CacheManager that this cache aspect should delegate to.
*/
public void setCacheManager(CacheManager cacheManager) {
this.cacheManager = cacheManager;
}
/**
* Return the CacheManager that this cache aspect delegates to.
*/
public CacheManager getCacheManager() {
return this.cacheManager;
}
/**
* Set one or more cache operation sources which are used to find the cache
* attributes. If more than one source is provided, they will be aggregated using a
* {@link CompositeCacheOperationSource}.
* @param cacheOperationSources must not be {@code null}
*/
public void setCacheOperationSources(CacheOperationSource... cacheOperationSources) {
Assert.notEmpty(cacheOperationSources);
this.cacheOperationSource = (cacheOperationSources.length > 1 ?
new CompositeCacheOperationSource(cacheOperationSources) : cacheOperationSources[0]);
}
/**
* Return the CacheOperationSource for this cache aspect.
*/
public CacheOperationSource getCacheOperationSource() {
return this.cacheOperationSource;
}
/**
* Set the KeyGenerator for this cache aspect.
* Default is {@link DefaultKeyGenerator}.
*/
public void setKeyGenerator(KeyGenerator keyGenerator) {
this.keyGenerator = keyGenerator;
}
/**
* Return the KeyGenerator for this cache aspect,
*/
public KeyGenerator getKeyGenerator() {
return this.keyGenerator;
}
public void afterPropertiesSet() {
Assert.state(this.cacheManager != null, "'cacheManager' is required");
Assert.state(this.cacheOperationSource != null, "The 'cacheOperationSources' "
@@ -88,6 +135,7 @@ public abstract class CacheAspectSupport implements InitializingBean {
this.initialized = true;
}
/**
* Convenience method to return a String representation of this Method
* for use in logging. Can be overridden in subclasses to provide a
@@ -113,22 +161,20 @@ public abstract class CacheAspectSupport implements InitializingBean {
return caches;
}
protected CacheOperationContext getOperationContext(CacheOperation operation,
Method method, Object[] args, Object target, Class<?> targetClass) {
protected CacheOperationContext getOperationContext(CacheOperation operation, Method method, Object[] args,
Object target, Class<?> targetClass) {
return new CacheOperationContext(operation, method, args, target, targetClass);
}
protected Object execute(Invoker invoker, Object target, Method method, Object[] args) {
// check whether aspect is enabled
// to cope with cases where the AJ is pulled in automatically
if (this.initialized) {
Class<?> targetClass = getTargetClass(target);
Collection<CacheOperation> operations = getCacheOperationSource().
getCacheOperations(method, targetClass);
Collection<CacheOperation> operations = getCacheOperationSource().getCacheOperations(method, targetClass);
if (!CollectionUtils.isEmpty(operations)) {
return execute(invoker, new CacheOperationContexts(operations,
method, args, target, targetClass));
return execute(invoker, new CacheOperationContexts(operations, method, args, target, targetClass));
}
}
@@ -144,30 +190,27 @@ public abstract class CacheAspectSupport implements InitializingBean {
}
private Object execute(Invoker invoker, CacheOperationContexts contexts) {
// Process any early evictions
processCacheEvicts(contexts.get(CacheEvictOperation.class), true, ExpressionEvaluator.NO_RESULT);
// Collect puts from any @Cachable miss
List<CachePutRequest> cachePutRequests = new ArrayList<CachePutRequest>();
collectPutRequests(contexts.get(CacheableOperation.class),
ExpressionEvaluator.NO_RESULT, cachePutRequests, true);
collectPutRequests(contexts.get(CacheableOperation.class), ExpressionEvaluator.NO_RESULT, cachePutRequests, true);
ValueWrapper result = null;
// We only attempt to get a cached result if there are no put requests
if(cachePutRequests.isEmpty() && contexts.get(CachePutOperation.class).isEmpty()) {
if (cachePutRequests.isEmpty() && contexts.get(CachePutOperation.class).isEmpty()) {
result = findCachedResult(contexts.get(CacheableOperation.class));
}
// Invoke the method if don't have a cache hit
if(result == null) {
if (result == null) {
result = new SimpleValueWrapper(invoker.invoke());
}
// Collect any explicit @CachePuts
collectPutRequests(contexts.get(CachePutOperation.class), result.get(),
cachePutRequests, false);
collectPutRequests(contexts.get(CachePutOperation.class), result.get(), cachePutRequests, false);
// Process any collected put requests, either from @CachePut or a @Cacheable miss
for (CachePutRequest cachePutRequest : cachePutRequests) {
@@ -180,26 +223,24 @@ public abstract class CacheAspectSupport implements InitializingBean {
return result.get();
}
private void processCacheEvicts(Collection<CacheOperationContext> contexts,
boolean beforeInvocation, Object result) {
private void processCacheEvicts(Collection<CacheOperationContext> contexts, boolean beforeInvocation, Object result) {
for (CacheOperationContext context : contexts) {
CacheEvictOperation operation = (CacheEvictOperation) context.operation;
if (beforeInvocation == operation.isBeforeInvocation() &&
isConditionPassing(context, result)) {
if (beforeInvocation == operation.isBeforeInvocation() && isConditionPassing(context, result)) {
performCacheEvict(context, operation, result);
}
}
}
private void performCacheEvict(CacheOperationContext context,
CacheEvictOperation operation, Object result) {
private void performCacheEvict(CacheOperationContext context, CacheEvictOperation operation, Object result) {
Object key = null;
for (Cache cache : context.getCaches()) {
if (operation.isCacheWide()) {
logInvalidating(context, operation, null);
cache.clear();
} else {
if(key == null) {
}
else {
if (key == null) {
key = context.generateKey(result);
}
logInvalidating(context, operation, key);
@@ -211,14 +252,14 @@ public abstract class CacheAspectSupport implements InitializingBean {
private void logInvalidating(CacheOperationContext context,
CacheEvictOperation operation, Object key) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Invalidating " +
(key == null ? "entire cache" : "cache key " + key) +
this.logger.trace("Invalidating " + (key == null ? "entire cache" : "cache key " + key) +
" for operation " + operation + " on method " + context.method);
}
}
private void collectPutRequests(Collection<CacheOperationContext> contexts,
Object result, Collection<CachePutRequest> putRequests, boolean whenNotInCache) {
for (CacheOperationContext context : contexts) {
if (isConditionPassing(context, result)) {
Object key = generateKey(context, result);
@@ -233,9 +274,8 @@ public abstract class CacheAspectSupport implements InitializingBean {
ValueWrapper result = null;
for (CacheOperationContext context : contexts) {
if (isConditionPassing(context, ExpressionEvaluator.NO_RESULT)) {
if(result == null) {
result = findInCaches(context,
generateKey(context, ExpressionEvaluator.NO_RESULT));
if (result == null) {
result = findInCaches(context, generateKey(context, ExpressionEvaluator.NO_RESULT));
}
}
}
@@ -254,7 +294,7 @@ public abstract class CacheAspectSupport implements InitializingBean {
private boolean isConditionPassing(CacheOperationContext context, Object result) {
boolean passing = context.isConditionPassing(result);
if(!passing && this.logger.isTraceEnabled()) {
if (!passing && this.logger.isTraceEnabled()) {
this.logger.trace("Cache condition failed on method " + context.method + " for operation " + context.operation);
}
return passing;
@@ -262,9 +302,8 @@ public abstract class CacheAspectSupport implements InitializingBean {
private Object generateKey(CacheOperationContext context, Object result) {
Object key = context.generateKey(result);
Assert.notNull(key, "Null key returned for cache operation (maybe you "
+ "are using named params on classes without debug info?) "
+ context.operation);
Assert.notNull(key, "Null key returned for cache operation (maybe you are using named params " +
"on classes without debug info?) " + context.operation);
if (this.logger.isTraceEnabled()) {
this.logger.trace("Computed cache key " + key + " for operation " + context.operation);
}
@@ -272,58 +311,8 @@ public abstract class CacheAspectSupport implements InitializingBean {
}
/**
* Set the CacheManager that this cache aspect should delegate to.
*/
public void setCacheManager(CacheManager cacheManager) {
this.cacheManager = cacheManager;
}
/**
* Return the CacheManager that this cache aspect delegates to.
*/
public CacheManager getCacheManager() {
return this.cacheManager;
}
/**
* Set one or more cache operation sources which are used to find the cache
* attributes. If more than one source is provided, they will be aggregated using a
* {@link CompositeCacheOperationSource}.
* @param cacheOperationSources must not be {@code null}
*/
public void setCacheOperationSources(CacheOperationSource... cacheOperationSources) {
Assert.notEmpty(cacheOperationSources);
this.cacheOperationSource =
(cacheOperationSources.length > 1 ?
new CompositeCacheOperationSource(cacheOperationSources) :
cacheOperationSources[0]);
}
/**
* Return the CacheOperationSource for this cache aspect.
*/
public CacheOperationSource getCacheOperationSource() {
return this.cacheOperationSource;
}
/**
* Set the KeyGenerator for this cache aspect.
* Default is {@link SimpleKeyGenerator}.
*/
public void setKeyGenerator(KeyGenerator keyGenerator) {
this.keyGenerator = keyGenerator;
}
/**
* Return the KeyGenerator for this cache aspect,
*/
public KeyGenerator getKeyGenerator() {
return this.keyGenerator;
}
public interface Invoker {
Object invoke();
}
@@ -335,6 +324,7 @@ public abstract class CacheAspectSupport implements InitializingBean {
public CacheOperationContexts(Collection<? extends CacheOperation> operations,
Method method, Object[] args, Object target, Class<?> targetClass) {
for (CacheOperation operation : operations) {
this.contexts.add(operation.getClass(), new CacheOperationContext(operation,
method, args, target, targetClass));
@@ -342,7 +332,8 @@ public abstract class CacheAspectSupport implements InitializingBean {
}
public Collection<CacheOperationContext> get(Class<? extends CacheOperation> operationClass) {
return this.contexts.getOrDefault(operationClass, Collections.<CacheOperationContext> emptyList());
Collection<CacheOperationContext> result = this.contexts.get(operationClass);
return (result != null ? result : Collections.<CacheOperationContext> emptyList());
}
}
@@ -361,7 +352,6 @@ public abstract class CacheAspectSupport implements InitializingBean {
private final Collection<Cache> caches;
public CacheOperationContext(CacheOperation operation, Method method, Object[] args, Object target, Class<?> targetClass) {
this.operation = operation;
this.method = method;
@@ -374,8 +364,7 @@ public abstract class CacheAspectSupport implements InitializingBean {
protected boolean isConditionPassing(Object result) {
if (StringUtils.hasText(this.operation.getCondition())) {
EvaluationContext evaluationContext = createEvaluationContext(result);
return CacheAspectSupport.this.evaluator.condition(this.operation.getCondition(), this.method,
evaluationContext);
return evaluator.condition(this.operation.getCondition(), this.method, evaluationContext);
}
return true;
}
@@ -388,9 +377,9 @@ public abstract class CacheAspectSupport implements InitializingBean {
else if (this.operation instanceof CachePutOperation) {
unless = ((CachePutOperation) this.operation).getUnless();
}
if(StringUtils.hasText(unless)) {
if (StringUtils.hasText(unless)) {
EvaluationContext evaluationContext = createEvaluationContext(value);
return !CacheAspectSupport.this.evaluator.unless(unless, this.method, evaluationContext);
return !evaluator.unless(unless, this.method, evaluationContext);
}
return true;
}
@@ -402,14 +391,13 @@ public abstract class CacheAspectSupport implements InitializingBean {
protected Object generateKey(Object result) {
if (StringUtils.hasText(this.operation.getKey())) {
EvaluationContext evaluationContext = createEvaluationContext(result);
return CacheAspectSupport.this.evaluator.key(this.operation.getKey(), this.method, evaluationContext);
return evaluator.key(this.operation.getKey(), this.method, evaluationContext);
}
return CacheAspectSupport.this.keyGenerator.generate(this.target, this.method, this.args);
return keyGenerator.generate(this.target, this.method, this.args);
}
private EvaluationContext createEvaluationContext(Object result) {
return CacheAspectSupport.this.evaluator.createEvaluationContext(this.caches, this.method, this.args,
this.target, this.targetClass, result);
return evaluator.createEvaluationContext(this.caches, this.method, this.args, this.target, this.targetClass, result);
}
protected Collection<Cache> getCaches() {
@@ -430,11 +418,12 @@ public abstract class CacheAspectSupport implements InitializingBean {
}
public void apply(Object result) {
if(this.context.canPutToCache(result)) {
if (this.context.canPutToCache(result)) {
for (Cache cache : this.context.getCaches()) {
cache.put(this.key, result);
}
}
}
}
}