/** * Validates the specified {@link CacheOperation}. * <p>Throws an {@link IllegalStateException} if the state of the operation is * invalid. As there might be multiple sources for default values, this ensure * that the operation is in a proper state before being returned. * @param ae the annotated element of the cache operation * @param operation the {@link CacheOperation} to validate */ private void validateCacheOperation(AnnotatedElement ae, CacheOperation operation) { if (StringUtils.hasText(operation.getKey()) && StringUtils.hasText(operation.getKeyGenerator())) { throw new IllegalStateException("Invalid cache annotation configuration on '" + ae.toString() + "'. Both 'key' and 'keyGenerator' attributes have been set. " + "These attributes are mutually exclusive: either set the SpEL expression used to" + "compute the key at runtime or set the name of the KeyGenerator bean to use."); } if (StringUtils.hasText(operation.getCacheManager()) && StringUtils.hasText(operation.getCacheResolver())) { throw new IllegalStateException("Invalid cache annotation configuration on '" + ae.toString() + "'. Both 'cacheManager' and 'cacheResolver' attributes have been set. " + "These attributes are mutually exclusive: the cache manager is used to configure a" + "default cache resolver if none is set. If a cache resolver is set, the cache manager" + "won't be used."); } }
@Override public int hashCode() { return (this.cacheOperation.hashCode() * 31 + this.methodCacheKey.hashCode()); }
if (metadata == null) { KeyGenerator operationKeyGenerator; if (StringUtils.hasText(operation.getKeyGenerator())) { operationKeyGenerator = getBean(operation.getKeyGenerator(), KeyGenerator.class); if (StringUtils.hasText(operation.getCacheResolver())) { operationCacheResolver = getBean(operation.getCacheResolver(), CacheResolver.class); else if (StringUtils.hasText(operation.getCacheManager())) { CacheManager cacheManager = getBean(operation.getCacheManager(), CacheManager.class); operationCacheResolver = new SimpleCacheResolver(cacheManager);
private void assertSharedConfig(CacheOperation actual, String keyGenerator, String cacheManager, String cacheResolver, String... cacheNames) { assertEquals("Wrong key manager", keyGenerator, actual.getKeyGenerator()); assertEquals("Wrong cache manager", cacheManager, actual.getCacheManager()); assertEquals("Wrong cache resolver", cacheResolver, actual.getCacheResolver()); assertEquals("Wrong number of cache names", cacheNames.length, actual.getCacheNames().size()); Arrays.stream(cacheNames).forEach(cacheName -> assertTrue("Cache '" + cacheName + "' not found in " + actual.getCacheNames(), actual.getCacheNames().contains(cacheName))); }
@Test public void singleComposedAnnotation() { Collection<CacheOperation> ops = getOps(AnnotatedClass.class, "singleComposed", 2); Iterator<CacheOperation> it = ops.iterator(); CacheOperation cacheOperation = it.next(); assertThat(cacheOperation, instanceOf(CacheableOperation.class)); assertThat(cacheOperation.getCacheNames(), equalTo(Collections.singleton("directly declared"))); assertThat(cacheOperation.getKey(), equalTo("")); cacheOperation = it.next(); assertThat(cacheOperation, instanceOf(CacheableOperation.class)); assertThat(cacheOperation.getCacheNames(), equalTo(Collections.singleton("composedCache"))); assertThat(cacheOperation.getKey(), equalTo("composedKey")); }
/** * Compute the key for the given caching operation. */ @Nullable protected Object generateKey(@Nullable Object result) { if (StringUtils.hasText(this.metadata.operation.getKey())) { EvaluationContext evaluationContext = createEvaluationContext(result); return evaluator.key(this.metadata.operation.getKey(), this.metadata.methodKey, evaluationContext); } return this.metadata.keyGenerator.generate(this.target, this.metadata.method, this.args); }
/** * This implementation returns {@code toString()}'s hash code. * @see #toString() */ @Override public int hashCode() { return toString().hashCode(); }
@Test public void customKeyGeneratorInherited() { Collection<CacheOperation> ops = getOps(AnnotatedClass.class, "customKeyGeneratorInherited", 1); CacheOperation cacheOperation = ops.iterator().next(); assertEquals("Custom key generator not set", "custom", cacheOperation.getKeyGenerator()); }
@Test public void customCacheManagerInherited() { Collection<CacheOperation> ops = getOps(AnnotatedClass.class, "customCacheManagerInherited", 1); CacheOperation cacheOperation = ops.iterator().next(); assertEquals("Custom cache manager not set", "custom", cacheOperation.getCacheManager()); }
@Test public void customCacheResolverInherited() { Collection<CacheOperation> ops = getOps(AnnotatedClass.class, "customCacheResolverInherited", 1); CacheOperation cacheOperation = ops.iterator().next(); assertEquals("Custom cache resolver not set", "custom", cacheOperation.getCacheResolver()); }
@Override public boolean equals(Object other) { if (this == other) { return true; } if (!(other instanceof CacheOperationCacheKey)) { return false; } CacheOperationCacheKey otherKey = (CacheOperationCacheKey) other; return (this.cacheOperation.equals(otherKey.cacheOperation) && this.methodCacheKey.equals(otherKey.methodCacheKey)); }
protected boolean isConditionPassing(@Nullable Object result) { if (this.conditionPassing == null) { if (StringUtils.hasText(this.metadata.operation.getCondition())) { EvaluationContext evaluationContext = createEvaluationContext(result); this.conditionPassing = evaluator.condition(this.metadata.operation.getCondition(), this.metadata.methodKey, evaluationContext); } else { this.conditionPassing = true; } } return this.conditionPassing; }
if (metadata == null) { KeyGenerator operationKeyGenerator; if (StringUtils.hasText(operation.getKeyGenerator())) { operationKeyGenerator = getBean(operation.getKeyGenerator(), KeyGenerator.class); if (StringUtils.hasText(operation.getCacheResolver())) { operationCacheResolver = getBean(operation.getCacheResolver(), CacheResolver.class); else if (StringUtils.hasText(operation.getCacheManager())) { CacheManager cacheManager = getBean(operation.getCacheManager(), CacheManager.class); operationCacheResolver = new SimpleCacheResolver(cacheManager);
@Test public void multipleComposedAnnotations() { Collection<CacheOperation> ops = getOps(AnnotatedClass.class, "multipleComposed", 4); Iterator<CacheOperation> it = ops.iterator(); CacheOperation cacheOperation = it.next(); assertThat(cacheOperation, instanceOf(CacheableOperation.class)); assertThat(cacheOperation.getCacheNames(), equalTo(Collections.singleton("directly declared"))); assertThat(cacheOperation.getKey(), equalTo("")); cacheOperation = it.next(); assertThat(cacheOperation, instanceOf(CacheableOperation.class)); assertThat(cacheOperation.getCacheNames(), equalTo(Collections.singleton("composedCache"))); assertThat(cacheOperation.getKey(), equalTo("composedKey")); cacheOperation = it.next(); assertThat(cacheOperation, instanceOf(CacheableOperation.class)); assertThat(cacheOperation.getCacheNames(), equalTo(Collections.singleton("foo"))); assertThat(cacheOperation.getKey(), equalTo("")); cacheOperation = it.next(); assertThat(cacheOperation, instanceOf(CacheEvictOperation.class)); assertThat(cacheOperation.getCacheNames(), equalTo(Collections.singleton("composedCacheEvict"))); assertThat(cacheOperation.getKey(), equalTo("composedEvictionKey")); }
/** * Compute the key for the given caching operation. */ @Nullable protected Object generateKey(@Nullable Object result) { if (StringUtils.hasText(this.metadata.operation.getKey())) { EvaluationContext evaluationContext = createEvaluationContext(result); return evaluator.key(this.metadata.operation.getKey(), this.metadata.methodKey, evaluationContext); } return this.metadata.keyGenerator.generate(this.target, this.metadata.method, this.args); }
/** * This implementation compares the {@code toString()} results. * @see #toString() */ @Override public boolean equals(Object other) { return (other instanceof CacheOperation && toString().equals(other.toString())); }
@Test public void customKeyGenerator() { Collection<CacheOperation> ops = getOps(AnnotatedClass.class, "customKeyGenerator", 1); CacheOperation cacheOperation = ops.iterator().next(); assertEquals("Custom key generator not set", "custom", cacheOperation.getKeyGenerator()); }
@Test public void customCacheManager() { Collection<CacheOperation> ops = getOps(AnnotatedClass.class, "customCacheManager", 1); CacheOperation cacheOperation = ops.iterator().next(); assertEquals("Custom cache manager not set", "custom", cacheOperation.getCacheManager()); }
@Test public void customCacheResolver() { Collection<CacheOperation> ops = getOps(AnnotatedClass.class, "customCacheResolver", 1); CacheOperation cacheOperation = ops.iterator().next(); assertEquals("Custom cache resolver not set", "custom", cacheOperation.getCacheResolver()); }