@Override protected Collection<String> getCacheNames(CacheOperationInvocationContext<?> context) { BasicOperation operation = context.getOperation(); if (!(operation instanceof CacheResultOperation)) { throw new IllegalStateException("Could not extract exception cache name from " + operation); } CacheResultOperation cacheResultOperation = (CacheResultOperation) operation; String exceptionCacheName = cacheResultOperation.getExceptionCacheName(); if (exceptionCacheName != null) { return Collections.singleton(exceptionCacheName); } return null; }
protected Collection<? extends Cache> getCaches( CacheOperationInvocationContext<CacheOperation> context, CacheResolver cacheResolver) { Collection<? extends Cache> caches = cacheResolver.resolveCaches(context); if (caches.isEmpty()) { throw new IllegalStateException("No cache could be resolved for '" + context.getOperation() + "' using resolver '" + cacheResolver + "'. At least one cache should be provided per cache operation."); } return caches; }
@Override protected Collection<String> getCacheNames(CacheOperationInvocationContext<?> context) { return context.getOperation().getCacheNames(); }
/** * Resolve the cache to use. * @param context the invocation context * @return the cache to use (never null) */ protected Cache resolveCache(CacheOperationInvocationContext<O> context) { Collection<? extends Cache> caches = context.getOperation().getCacheResolver().resolveCaches(context); Cache cache = extractFrom(caches); if (cache == null) { throw new IllegalStateException("Cache could not have been resolved for " + context.getOperation()); } return cache; }
protected Collection<? extends Cache> getCaches( CacheOperationInvocationContext<CacheOperation> context, CacheResolver cacheResolver) { Collection<? extends Cache> caches = cacheResolver.resolveCaches(context); if (caches.isEmpty()) { throw new IllegalStateException("No cache could be resolved for '" + context.getOperation() + "' using resolver '" + cacheResolver + "'. At least one cache should be provided per cache operation."); } return caches; }
@Nullable private Cache resolveExceptionCache(CacheOperationInvocationContext<CacheResultOperation> context) { CacheResolver exceptionCacheResolver = context.getOperation().getExceptionCacheResolver(); if (exceptionCacheResolver != null) { return extractFrom(context.getOperation().getExceptionCacheResolver().resolveCaches(context)); } return null; }
@Override protected Collection<String> getCacheNames(CacheOperationInvocationContext<?> context) { return context.getOperation().getCacheNames(); }
/** * Generate a key for the specified invocation. * @param context the context of the invocation * @return the key to use */ protected Object generateKey(CacheOperationInvocationContext<O> context) { KeyGenerator keyGenerator = context.getOperation().getKeyGenerator(); Object key = keyGenerator.generate(context.getTarget(), context.getMethod(), context.getArgs()); if (logger.isTraceEnabled()) { logger.trace("Computed cache key " + key + " for operation " + context.getOperation()); } return key; }
protected void removeAll(CacheOperationInvocationContext<CacheRemoveAllOperation> context) { Cache cache = resolveCache(context); if (logger.isTraceEnabled()) { logger.trace("Invalidating entire cache '" + cache.getName() + "' for operation " + context.getOperation()); } doClear(cache); }
@Override public Collection<? extends Cache> resolveCaches(CacheOperationInvocationContext<?> context) { Collection<String> cacheNames = getCacheNames(context); if (cacheNames == null) { return Collections.emptyList(); } Collection<Cache> result = new ArrayList<>(cacheNames.size()); for (String cacheName : cacheNames) { Cache cache = getCacheManager().getCache(cacheName); if (cache == null) { throw new IllegalArgumentException("Cannot find cache named '" + cacheName + "' for " + context.getOperation()); } result.add(cache); } return result; }
private void removeValue(CacheOperationInvocationContext<CacheRemoveOperation> context) { Object key = generateKey(context); Cache cache = resolveCache(context); if (logger.isTraceEnabled()) { logger.trace("Invalidating key [" + key + "] on cache '" + cache.getName() + "' for operation " + context.getOperation()); } doEvict(cache, key); }
/** * Create a {@link CacheKeyInvocationContext} based on the specified invocation. * @param context the context of the invocation. * @return the related {@code CacheKeyInvocationContext} */ protected CacheKeyInvocationContext<A> createCacheKeyInvocationContext(CacheOperationInvocationContext<O> context) { return new DefaultCacheKeyInvocationContext<>(context.getOperation(), context.getTarget(), context.getArgs()); }
@Override public Collection<? extends Cache> resolveCaches(CacheOperationInvocationContext<?> context) { Collection<String> cacheNames = getCacheNames(context); if (cacheNames == null) { return Collections.emptyList(); } Collection<Cache> result = new ArrayList<>(cacheNames.size()); for (String cacheName : cacheNames) { Cache cache = getCacheManager().getCache(cacheName); if (cache == null) { throw new IllegalArgumentException("Cannot find cache named '" + cacheName + "' for " + context.getOperation()); } result.add(cache); } return result; }
@SuppressWarnings("unchecked") @Nullable private Object execute(CacheOperationInvocationContext<?> context, CacheOperationInvoker invoker) { CacheOperationInvoker adapter = new CacheOperationInvokerAdapter(invoker); BasicOperation operation = context.getOperation(); if (operation instanceof CacheResultOperation) { Assert.state(this.cacheResultInterceptor != null, "No CacheResultInterceptor"); return this.cacheResultInterceptor.invoke( (CacheOperationInvocationContext<CacheResultOperation>) context, adapter); } else if (operation instanceof CachePutOperation) { Assert.state(this.cachePutInterceptor != null, "No CachePutInterceptor"); return this.cachePutInterceptor.invoke( (CacheOperationInvocationContext<CachePutOperation>) context, adapter); } else if (operation instanceof CacheRemoveOperation) { Assert.state(this.cacheRemoveEntryInterceptor != null, "No CacheRemoveEntryInterceptor"); return this.cacheRemoveEntryInterceptor.invoke( (CacheOperationInvocationContext<CacheRemoveOperation>) context, adapter); } else if (operation instanceof CacheRemoveAllOperation) { Assert.state(this.cacheRemoveAllInterceptor != null, "No CacheRemoveAllInterceptor"); return this.cacheRemoveAllInterceptor.invoke( (CacheOperationInvocationContext<CacheRemoveAllOperation>) context, adapter); } else { throw new IllegalArgumentException("Cannot handle " + operation); } }
@Nullable private Cache resolveExceptionCache(CacheOperationInvocationContext<CacheResultOperation> context) { CacheResolver exceptionCacheResolver = context.getOperation().getExceptionCacheResolver(); if (exceptionCacheResolver != null) { return extractFrom(context.getOperation().getExceptionCacheResolver().resolveCaches(context)); } return null; }
protected void removeAll(CacheOperationInvocationContext<CacheRemoveAllOperation> context) { Cache cache = resolveCache(context); if (logger.isTraceEnabled()) { logger.trace("Invalidating entire cache '" + cache.getName() + "' for operation " + context.getOperation()); } doClear(cache); }
@Override protected Object invoke( CacheOperationInvocationContext<CacheRemoveAllOperation> context, CacheOperationInvoker invoker) { CacheRemoveAllOperation operation = context.getOperation(); boolean earlyRemove = operation.isEarlyRemove(); if (earlyRemove) { removeAll(context); } try { Object result = invoker.invoke(); if (!earlyRemove) { removeAll(context); } return result; } catch (CacheOperationInvoker.ThrowableWrapper ex) { Throwable original = ex.getOriginal(); if (!earlyRemove && operation.getExceptionTypeFilter().match(original.getClass())) { removeAll(context); } throw ex; } }
@Override protected Object invoke( CacheOperationInvocationContext<CacheRemoveOperation> context, CacheOperationInvoker invoker) { CacheRemoveOperation operation = context.getOperation(); boolean earlyRemove = operation.isEarlyRemove(); if (earlyRemove) { removeValue(context); } try { Object result = invoker.invoke(); if (!earlyRemove) { removeValue(context); } return result; } catch (CacheOperationInvoker.ThrowableWrapper wrapperException) { Throwable ex = wrapperException.getOriginal(); if (!earlyRemove && operation.getExceptionTypeFilter().match(ex.getClass())) { removeValue(context); } throw wrapperException; } }
@Override protected Object invoke( CacheOperationInvocationContext<CachePutOperation> context, CacheOperationInvoker invoker) { CachePutOperation operation = context.getOperation(); CacheKeyInvocationContext<CachePut> invocationContext = createCacheKeyInvocationContext(context); boolean earlyPut = operation.isEarlyPut(); Object value = invocationContext.getValueParameter().getValue(); if (earlyPut) { cacheValue(context, value); } try { Object result = invoker.invoke(); if (!earlyPut) { cacheValue(context, value); } return result; } catch (CacheOperationInvoker.ThrowableWrapper ex) { Throwable original = ex.getOriginal(); if (!earlyPut && operation.getExceptionTypeFilter().match(original.getClass())) { cacheValue(context, value); } throw ex; } }
@Override @Nullable protected Object invoke( CacheOperationInvocationContext<CacheResultOperation> context, CacheOperationInvoker invoker) { CacheResultOperation operation = context.getOperation(); Object cacheKey = generateKey(context); Cache cache = resolveCache(context); Cache exceptionCache = resolveExceptionCache(context); if (!operation.isAlwaysInvoked()) { Cache.ValueWrapper cachedValue = doGet(cache, cacheKey); if (cachedValue != null) { return cachedValue.get(); } checkForCachedException(exceptionCache, cacheKey); } try { Object invocationResult = invoker.invoke(); doPut(cache, cacheKey, invocationResult); return invocationResult; } catch (CacheOperationInvoker.ThrowableWrapper ex) { Throwable original = ex.getOriginal(); cacheException(exceptionCache, operation.getExceptionTypeFilter(), cacheKey, original); throw ex; } }