JCS-183 reduce reflection at runtime in our jcache cdi integration
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/jcs/trunk@1806978 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CDIJCacheHelper.java b/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CDIJCacheHelper.java
index b7f8095..a86ca35 100644
--- a/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CDIJCacheHelper.java
+++ b/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CDIJCacheHelper.java
@@ -18,22 +18,13 @@
*/
package org.apache.commons.jcs.jcache.cdi;
-import javax.annotation.PreDestroy;
-import javax.cache.annotation.CacheDefaults;
-import javax.cache.annotation.CacheKey;
-import javax.cache.annotation.CacheKeyGenerator;
-import javax.cache.annotation.CacheResolverFactory;
-import javax.cache.annotation.CacheValue;
-import javax.enterprise.context.ApplicationScoped;
-import javax.enterprise.context.Dependent;
-import javax.enterprise.context.spi.CreationalContext;
-import javax.enterprise.inject.spi.Bean;
-import javax.enterprise.inject.spi.BeanManager;
-import javax.inject.Inject;
-import javax.interceptor.InvocationContext;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
@@ -41,6 +32,23 @@
import java.util.concurrent.ConcurrentMap;
import java.util.logging.Logger;
+import javax.annotation.PreDestroy;
+import javax.cache.annotation.CacheDefaults;
+import javax.cache.annotation.CacheKey;
+import javax.cache.annotation.CacheKeyGenerator;
+import javax.cache.annotation.CachePut;
+import javax.cache.annotation.CacheRemove;
+import javax.cache.annotation.CacheRemoveAll;
+import javax.cache.annotation.CacheResolverFactory;
+import javax.cache.annotation.CacheResult;
+import javax.cache.annotation.CacheValue;
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.inject.Inject;
+import javax.interceptor.InvocationContext;
+
@ApplicationScoped
public class CDIJCacheHelper
{
@@ -49,8 +57,9 @@
private volatile CacheResolverFactoryImpl defaultCacheResolverFactory = null; // lazy to not create any cache if not needed
private final CacheKeyGeneratorImpl defaultCacheKeyGenerator = new CacheKeyGeneratorImpl();
- private final ConcurrentMap<Method, String> generatedNames = new ConcurrentHashMap<Method, String>();
- private final ConcurrentMap<Method, Integer[]> parameterIndexes = new ConcurrentHashMap<Method, Integer[]>();
+
+ private final Collection<CreationalContext<?>> toRelease = new ArrayList<CreationalContext<?>>();
+ private final ConcurrentMap<MethodKey, MethodMeta> methods = new ConcurrentHashMap<MethodKey, MethodMeta>();
@Inject
private BeanManager beanManager;
@@ -61,9 +70,152 @@
{
defaultCacheResolverFactory.release();
}
+ for (final CreationalContext<?> cc : toRelease)
+ {
+ try
+ {
+ cc.release();
+ }
+ catch (final RuntimeException re)
+ {
+ LOGGER.warning(re.getMessage());
+ }
+ }
}
- public String defaultName(final Method method, final CacheDefaults defaults, final String cacheName)
+ public MethodMeta findMeta(final InvocationContext ic)
+ {
+ final Method mtd = ic.getMethod();
+ final MethodKey key = new MethodKey(mtd);
+ MethodMeta methodMeta = methods.get(key);
+ if (methodMeta == null)
+ {
+ synchronized (this)
+ {
+ methodMeta = methods.get(key);
+ if (methodMeta == null)
+ {
+ methodMeta = createMeta(ic);
+ }
+ }
+ }
+ return methodMeta;
+ }
+
+ // it is unlikely we have all annotations but for now we have a single meta model
+ private MethodMeta createMeta(final InvocationContext ic)
+ {
+ final CacheDefaults defaults = findDefaults(ic.getTarget() == null ? null : ic.getTarget()
+ .getClass(), ic.getMethod());
+
+ final Class<?>[] parameterTypes = ic.getMethod().getParameterTypes();
+ final Annotation[][] parameterAnnotations = ic.getMethod().getParameterAnnotations();
+ final List<Set<Annotation>> annotations = new ArrayList<Set<Annotation>>();
+ for (final Annotation[] parameterAnnotation : parameterAnnotations)
+ {
+ final Set<Annotation> set = new HashSet<Annotation>(parameterAnnotation.length);
+ set.addAll(Arrays.asList(parameterAnnotation));
+ annotations.add(set);
+ }
+
+ final Set<Annotation> mtdAnnotations = new HashSet<Annotation>();
+ mtdAnnotations.addAll(Arrays.asList(ic.getMethod().getAnnotations()));
+
+ final CacheResult cacheResult = ic.getMethod().getAnnotation(CacheResult.class);
+ final String cacheResultCacheResultName = cacheResult == null ? null : defaultName(ic.getMethod(), defaults, cacheResult.cacheName());
+ final CacheResolverFactory cacheResultCacheResolverFactory = cacheResult == null ?
+ null : cacheResolverFactoryFor(defaults, cacheResult.cacheResolverFactory());
+ final CacheKeyGenerator cacheResultCacheKeyGenerator = cacheResult == null ?
+ null : cacheKeyGeneratorFor(defaults, cacheResult.cacheKeyGenerator());
+
+ final CachePut cachePut = ic.getMethod().getAnnotation(CachePut.class);
+ final String cachePutCachePutName = cachePut == null ? null : defaultName(ic.getMethod(), defaults, cachePut.cacheName());
+ final CacheResolverFactory cachePutCacheResolverFactory = cachePut == null ?
+ null : cacheResolverFactoryFor(defaults, cachePut.cacheResolverFactory());
+ final CacheKeyGenerator cachePutCacheKeyGenerator = cachePut == null ?
+ null : cacheKeyGeneratorFor(defaults, cachePut.cacheKeyGenerator());
+
+ final CacheRemove cacheRemove = ic.getMethod().getAnnotation(CacheRemove.class);
+ final String cacheRemoveCacheRemoveName = cacheRemove == null ? null : defaultName(ic.getMethod(), defaults, cacheRemove.cacheName());
+ final CacheResolverFactory cacheRemoveCacheResolverFactory = cacheRemove == null ?
+ null : cacheResolverFactoryFor(defaults, cacheRemove.cacheResolverFactory());
+ final CacheKeyGenerator cacheRemoveCacheKeyGenerator = cacheRemove == null ?
+ null : cacheKeyGeneratorFor(defaults, cacheRemove.cacheKeyGenerator());
+
+ final CacheRemoveAll cacheRemoveAll = ic.getMethod().getAnnotation(CacheRemoveAll.class);
+ final String cacheRemoveAllCacheRemoveAllName = cacheRemoveAll == null ? null : defaultName(ic.getMethod(), defaults, cacheRemoveAll.cacheName());
+ final CacheResolverFactory cacheRemoveAllCacheResolverFactory = cacheRemoveAll == null ?
+ null : cacheResolverFactoryFor(defaults, cacheRemoveAll.cacheResolverFactory());
+
+ return new MethodMeta(
+ parameterTypes,
+ annotations,
+ mtdAnnotations,
+ keyParameterIndexes(ic.getMethod()),
+ getValueParameter(annotations),
+ getKeyParameters(annotations),
+ cacheResultCacheResultName,
+ cacheResultCacheResolverFactory,
+ cacheResultCacheKeyGenerator,
+ cacheResult,
+ cachePutCachePutName,
+ cachePutCacheResolverFactory,
+ cachePutCacheKeyGenerator,
+ cachePut != null && cachePut.afterInvocation(),
+ cachePut,
+ cacheRemoveCacheRemoveName,
+ cacheRemoveCacheResolverFactory,
+ cacheRemoveCacheKeyGenerator,
+ cacheRemove != null && cacheRemove.afterInvocation(),
+ cacheRemove,
+ cacheRemoveAllCacheRemoveAllName,
+ cacheRemoveAllCacheResolverFactory,
+ cacheRemoveAll != null && cacheRemoveAll.afterInvocation(),
+ cacheRemoveAll);
+ }
+
+ private Integer[] getKeyParameters(final List<Set<Annotation>> annotations)
+ {
+ final Collection<Integer> list = new ArrayList<Integer>();
+ int idx = 0;
+ for (final Set<Annotation> set : annotations)
+ {
+ for (final Annotation a : set)
+ {
+ if (a.annotationType() == CacheKey.class)
+ {
+ list.add(idx);
+ }
+ }
+ idx++;
+ }
+ if (list.isEmpty())
+ {
+ for (int i = 0; i < annotations.size(); i++)
+ {
+ list.add(i);
+ }
+ }
+ return list.toArray(new Integer[list.size()]);
+ }
+
+ private Integer getValueParameter(final List<Set<Annotation>> annotations)
+ {
+ int idx = 0;
+ for (final Set<Annotation> set : annotations)
+ {
+ for (final Annotation a : set)
+ {
+ if (a.annotationType() == CacheValue.class)
+ {
+ return idx;
+ }
+ }
+ }
+ return -1;
+ }
+
+ private String defaultName(final Method method, final CacheDefaults defaults, final String cacheName)
{
if (!cacheName.isEmpty())
{
@@ -78,35 +230,30 @@
}
}
- String computedName = generatedNames.get(method);
- if (computedName == null)
+ final StringBuilder name = new StringBuilder(method.getDeclaringClass().getName());
+ name.append(".");
+ name.append(method.getName());
+ name.append("(");
+ final Class<?>[] parameterTypes = method.getParameterTypes();
+ for (int pIdx = 0; pIdx < parameterTypes.length; pIdx++)
{
- final StringBuilder name = new StringBuilder(method.getDeclaringClass().getName());
- name.append(".");
- name.append(method.getName());
- name.append("(");
- final Class<?>[] parameterTypes = method.getParameterTypes();
- for (int pIdx = 0; pIdx < parameterTypes.length; pIdx++)
+ name.append(parameterTypes[pIdx].getName());
+ if ((pIdx + 1) < parameterTypes.length)
{
- name.append(parameterTypes[pIdx].getName());
- if ((pIdx + 1) < parameterTypes.length)
- {
- name.append(",");
- }
+ name.append(",");
}
- name.append(")");
- computedName = name.toString();
- generatedNames.putIfAbsent(method, computedName);
}
- return computedName;
+ name.append(")");
+ return name.toString();
}
- public CacheDefaults findDefaults(final InvocationContext ic)
+ private CacheDefaults findDefaults(final Class<?> targetType, final Method method)
{
- if (ic.getTarget() != null && Proxy.isProxyClass(ic.getTarget().getClass())) // target doesnt hold annotations
+ if (Proxy.isProxyClass(targetType)) // target doesnt hold annotations
{
- final Class<?> api = ic.getMethod().getDeclaringClass();
- for (final Class<?> type : ic.getTarget().getClass().getInterfaces())
+ final Class<?> api = method.getDeclaringClass();
+ for (final Class<?> type : targetType
+ .getInterfaces())
{
if (!api.isAssignableFrom(type))
{
@@ -115,7 +262,7 @@
return extractDefaults(type);
}
}
- return extractDefaults(ic.getTarget().getClass());
+ return extractDefaults(targetType);
}
private CacheDefaults extractDefaults(final Class<?> type)
@@ -157,7 +304,7 @@
return false;
}
- public CacheKeyGenerator cacheKeyGeneratorFor(final CacheDefaults defaults, final Class<? extends CacheKeyGenerator> cacheKeyGenerator)
+ private CacheKeyGenerator cacheKeyGeneratorFor(final CacheDefaults defaults, final Class<? extends CacheKeyGenerator> cacheKeyGenerator)
{
if (!CacheKeyGenerator.class.equals(cacheKeyGenerator))
{
@@ -174,7 +321,7 @@
return defaultCacheKeyGenerator;
}
- public CacheResolverFactory cacheResolverFactoryFor(final CacheDefaults defaults, final Class<? extends CacheResolverFactory> cacheResolverFactory)
+ private CacheResolverFactory cacheResolverFactoryFor(final CacheDefaults defaults, final Class<? extends CacheResolverFactory> cacheResolverFactory)
{
if (!CacheResolverFactory.class.equals(cacheResolverFactory))
{
@@ -191,7 +338,7 @@
return defaultCacheResolverFactory();
}
- public <T> T instance(final Class<T> type)
+ private <T> T instance(final Class<T> type)
{
final Set<Bean<?>> beans = beanManager.getBeans(type);
if (beans.isEmpty())
@@ -207,19 +354,20 @@
final Bean<?> bean = beanManager.resolve(beans);
final CreationalContext<?> context = beanManager.createCreationalContext(bean);
final Class<? extends Annotation> scope = bean.getScope();
- final boolean dependent = Dependent.class.equals(scope);
- if (!dependent && !beanManager.isNormalScope(scope))
- {
- LOGGER.warning("Not normal scope beans (" + type.getName() + ") can leak");
- }
+ final boolean normalScope = beanManager.isNormalScope(scope);
try
{
- return (T) beanManager.getReference(bean, bean.getBeanClass(), context);
+ final Object reference = beanManager.getReference(bean, bean.getBeanClass(), context);
+ if (!normalScope)
+ {
+ toRelease.add(context);
+ }
+ return (T) reference;
}
finally
{
- if (dependent)
- { // TODO: depent or pseudo scope?
+ if (normalScope)
+ { // TODO: release at the right moment, @PreDestroy? question is: do we assume it is thread safe?
context.release();
}
}
@@ -239,51 +387,271 @@
return defaultCacheResolverFactory;
}
- public Integer[] keyParameterIndexes(final Method method)
+ private Integer[] keyParameterIndexes(final Method method)
{
- Integer[] val = parameterIndexes.get(method);
- if (val == null)
+ final List<Integer> keys = new LinkedList<Integer>();
+ final Annotation[][] parameterAnnotations = method.getParameterAnnotations();
+
+ // first check if keys are specified explicitely
+ for (int i = 0; i < method.getParameterTypes().length; i++)
{
- final List<Integer> keys = new LinkedList<Integer>();
- final Annotation[][] parameterAnnotations = method.getParameterAnnotations();
-
- // first check if keys are specified explicitely
+ final Annotation[] annotations = parameterAnnotations[i];
+ for (final Annotation a : annotations)
+ {
+ if (a.annotationType().equals(CacheKey.class))
+ {
+ keys.add(i);
+ break;
+ }
+ }
+ }
+
+ // if not then use all parameters but value ones
+ if (keys.isEmpty())
+ {
for (int i = 0; i < method.getParameterTypes().length; i++)
{
final Annotation[] annotations = parameterAnnotations[i];
+ boolean value = false;
for (final Annotation a : annotations)
{
- if (a.annotationType().equals(CacheKey.class))
+ if (a.annotationType().equals(CacheValue.class))
{
- keys.add(i);
+ value = true;
break;
}
}
- }
-
- // if not then use all parameters but value ones
- if (keys.isEmpty())
- {
- for (int i = 0; i < method.getParameterTypes().length; i++)
- {
- final Annotation[] annotations = parameterAnnotations[i];
- boolean value = false;
- for (final Annotation a : annotations)
- {
- if (a.annotationType().equals(CacheValue.class))
- {
- value = true;
- break;
- }
- }
- if (!value) {
- keys.add(i);
- }
+ if (!value) {
+ keys.add(i);
}
}
- val = keys.toArray(new Integer[keys.size()]);
- parameterIndexes.putIfAbsent(method, val);
}
- return val;
+ return keys.toArray(new Integer[keys.size()]);
+ }
+
+ private static final class MethodKey
+ {
+ private final Method delegate;
+ private final int hash;
+
+ private MethodKey(final Method delegate)
+ {
+ this.delegate = delegate;
+ this.hash = delegate.hashCode();
+ }
+
+ @Override
+ public boolean equals(final Object o)
+ {
+ if (this == o)
+ {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass())
+ {
+ return false;
+ }
+ final MethodKey classKey = MethodKey.class.cast(o);
+ return delegate.equals(classKey.delegate);
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return hash;
+ }
+ }
+
+ // TODO: split it in 5?
+ public static class MethodMeta
+ {
+ private final Class<?>[] parameterTypes;
+ private final List<Set<Annotation>> parameterAnnotations;
+ private final Set<Annotation> annotations;
+ private final Integer[] keysIndices;
+ private final Integer valueIndex;
+ private final Integer[] parameterIndices;
+
+ private final String cacheResultCacheName;
+ private final CacheResolverFactory cacheResultResolverFactory;
+ private final CacheKeyGenerator cacheResultKeyGenerator;
+ private final CacheResult cacheResult;
+
+ private final String cachePutCacheName;
+ private final CacheResolverFactory cachePutResolverFactory;
+ private final CacheKeyGenerator cachePutKeyGenerator;
+ private final boolean cachePutAfter;
+ private final CachePut cachePut;
+
+ private final String cacheRemoveCacheName;
+ private final CacheResolverFactory cacheRemoveResolverFactory;
+ private final CacheKeyGenerator cacheRemoveKeyGenerator;
+ private final boolean cacheRemoveAfter;
+ private final CacheRemove cacheRemove;
+
+ private final String cacheRemoveAllCacheName;
+ private final CacheResolverFactory cacheRemoveAllResolverFactory;
+ private final boolean cacheRemoveAllAfter;
+ private final CacheRemoveAll cacheRemoveAll;
+
+ public MethodMeta(Class<?>[] parameterTypes, List<Set<Annotation>> parameterAnnotations, Set<Annotation>
+ annotations, Integer[] keysIndices, Integer valueIndex, Integer[] parameterIndices, String
+ cacheResultCacheName, CacheResolverFactory cacheResultResolverFactory, CacheKeyGenerator
+ cacheResultKeyGenerator, CacheResult cacheResult, String cachePutCacheName, CacheResolverFactory
+ cachePutResolverFactory, CacheKeyGenerator cachePutKeyGenerator, boolean cachePutAfter, CachePut cachePut, String
+ cacheRemoveCacheName, CacheResolverFactory cacheRemoveResolverFactory, CacheKeyGenerator
+ cacheRemoveKeyGenerator, boolean cacheRemoveAfter, CacheRemove cacheRemove, String cacheRemoveAllCacheName,
+ CacheResolverFactory cacheRemoveAllResolverFactory, boolean
+ cacheRemoveAllAfter, CacheRemoveAll cacheRemoveAll)
+ {
+ this.parameterTypes = parameterTypes;
+ this.parameterAnnotations = parameterAnnotations;
+ this.annotations = annotations;
+ this.keysIndices = keysIndices;
+ this.valueIndex = valueIndex;
+ this.parameterIndices = parameterIndices;
+ this.cacheResultCacheName = cacheResultCacheName;
+ this.cacheResultResolverFactory = cacheResultResolverFactory;
+ this.cacheResultKeyGenerator = cacheResultKeyGenerator;
+ this.cacheResult = cacheResult;
+ this.cachePutCacheName = cachePutCacheName;
+ this.cachePutResolverFactory = cachePutResolverFactory;
+ this.cachePutKeyGenerator = cachePutKeyGenerator;
+ this.cachePutAfter = cachePutAfter;
+ this.cachePut = cachePut;
+ this.cacheRemoveCacheName = cacheRemoveCacheName;
+ this.cacheRemoveResolverFactory = cacheRemoveResolverFactory;
+ this.cacheRemoveKeyGenerator = cacheRemoveKeyGenerator;
+ this.cacheRemoveAfter = cacheRemoveAfter;
+ this.cacheRemove = cacheRemove;
+ this.cacheRemoveAllCacheName = cacheRemoveAllCacheName;
+ this.cacheRemoveAllResolverFactory = cacheRemoveAllResolverFactory;
+ this.cacheRemoveAllAfter = cacheRemoveAllAfter;
+ this.cacheRemoveAll = cacheRemoveAll;
+ }
+
+ public boolean isCacheRemoveAfter()
+ {
+ return cacheRemoveAfter;
+ }
+
+ public boolean isCachePutAfter()
+ {
+ return cachePutAfter;
+ }
+
+ public Class<?>[] getParameterTypes()
+ {
+ return parameterTypes;
+ }
+
+ public List<Set<Annotation>> getParameterAnnotations()
+ {
+ return parameterAnnotations;
+ }
+
+ public String getCacheResultCacheName()
+ {
+ return cacheResultCacheName;
+ }
+
+ public CacheResolverFactory getCacheResultResolverFactory()
+ {
+ return cacheResultResolverFactory;
+ }
+
+ public CacheKeyGenerator getCacheResultKeyGenerator()
+ {
+ return cacheResultKeyGenerator;
+ }
+
+ public CacheResult getCacheResult() {
+ return cacheResult;
+ }
+
+ public Integer[] getParameterIndices()
+ {
+ return parameterIndices;
+ }
+
+ public Set<Annotation> getAnnotations()
+ {
+ return annotations;
+ }
+
+ public Integer[] getKeysIndices()
+ {
+ return keysIndices;
+ }
+
+ public Integer getValuesIndex()
+ {
+ return valueIndex;
+ }
+
+ public Integer getValueIndex()
+ {
+ return valueIndex;
+ }
+
+ public String getCachePutCacheName()
+ {
+ return cachePutCacheName;
+ }
+
+ public CacheResolverFactory getCachePutResolverFactory()
+ {
+ return cachePutResolverFactory;
+ }
+
+ public CacheKeyGenerator getCachePutKeyGenerator()
+ {
+ return cachePutKeyGenerator;
+ }
+
+ public CachePut getCachePut()
+ {
+ return cachePut;
+ }
+
+ public String getCacheRemoveCacheName()
+ {
+ return cacheRemoveCacheName;
+ }
+
+ public CacheResolverFactory getCacheRemoveResolverFactory()
+ {
+ return cacheRemoveResolverFactory;
+ }
+
+ public CacheKeyGenerator getCacheRemoveKeyGenerator()
+ {
+ return cacheRemoveKeyGenerator;
+ }
+
+ public CacheRemove getCacheRemove()
+ {
+ return cacheRemove;
+ }
+
+ public String getCacheRemoveAllCacheName()
+ {
+ return cacheRemoveAllCacheName;
+ }
+
+ public CacheResolverFactory getCacheRemoveAllResolverFactory()
+ {
+ return cacheRemoveAllResolverFactory;
+ }
+
+ public boolean isCacheRemoveAllAfter()
+ {
+ return cacheRemoveAllAfter;
+ }
+
+ public CacheRemoveAll getCacheRemoveAll()
+ {
+ return cacheRemoveAll;
+ }
}
}
diff --git a/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CacheInvocationContextImpl.java b/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CacheInvocationContextImpl.java
index 8cf4614..7f6a539 100644
--- a/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CacheInvocationContextImpl.java
+++ b/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CacheInvocationContextImpl.java
@@ -18,13 +18,13 @@
*/
package org.apache.commons.jcs.jcache.cdi;
+import java.lang.annotation.Annotation;
+import java.util.List;
+import java.util.Set;
+
import javax.cache.annotation.CacheInvocationContext;
import javax.cache.annotation.CacheInvocationParameter;
import javax.interceptor.InvocationContext;
-import java.lang.annotation.Annotation;
-import java.util.HashSet;
-
-import static java.util.Arrays.asList;
public class CacheInvocationContextImpl<A extends Annotation> extends CacheMethodDetailsImpl<A> implements CacheInvocationContext<A>
{
@@ -32,9 +32,10 @@
private CacheInvocationParameter[] parameters = null;
- public CacheInvocationContextImpl(final InvocationContext delegate, final A cacheAnnotation, final String cacheName)
+ public CacheInvocationContextImpl(final InvocationContext delegate, final A cacheAnnotation, final String cacheName,
+ final CDIJCacheHelper.MethodMeta meta)
{
- super(delegate, cacheAnnotation, cacheName);
+ super(delegate, cacheAnnotation, cacheName, meta);
}
@Override
@@ -67,15 +68,15 @@
{
final Object[] parameters = delegate.getParameters();
final Object[] args = parameters == null ? EMPTY_ARGS : parameters;
- final Class<?>[] parameterTypes = getMethod().getParameterTypes();
- final Annotation[][] parameterAnnotations = getMethod().getParameterAnnotations();
+ final Class<?>[] parameterTypes = meta.getParameterTypes();
+ final List<Set<Annotation>> parameterAnnotations = meta.getParameterAnnotations();
final CacheInvocationParameter[] parametersAsArray = new CacheInvocationParameter[indexes == null ? args.length : indexes.length];
if (indexes == null)
{
for (int i = 0; i < args.length; i++)
{
- parametersAsArray[i] = newCacheInvocationParameterImpl(parameterTypes[i], args[i], parameterAnnotations[i], i);
+ parametersAsArray[i] = newCacheInvocationParameterImpl(parameterTypes[i], args[i], parameterAnnotations.get(i), i);
}
}
else
@@ -83,14 +84,14 @@
for (int idx = 0; idx < indexes.length; idx++)
{
final int i = indexes[idx];
- parametersAsArray[i] = newCacheInvocationParameterImpl(parameterTypes[i], args[i], parameterAnnotations[i], i);
+ parametersAsArray[i] = newCacheInvocationParameterImpl(parameterTypes[i], args[i], parameterAnnotations.get(i), i);
}
}
return parametersAsArray;
}
private CacheInvocationParameterImpl newCacheInvocationParameterImpl(final Class<?> type, final Object arg,
- final Annotation[] annotations, final int i) {
- return new CacheInvocationParameterImpl(type, arg, new HashSet<Annotation>(asList(annotations)), i);
+ final Set<Annotation> annotations, final int i) {
+ return new CacheInvocationParameterImpl(type, arg, annotations, i);
}
}
diff --git a/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CacheKeyInvocationContextImpl.java b/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CacheKeyInvocationContextImpl.java
index a861152..6d87d26 100644
--- a/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CacheKeyInvocationContextImpl.java
+++ b/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CacheKeyInvocationContextImpl.java
@@ -18,26 +18,21 @@
*/
package org.apache.commons.jcs.jcache.cdi;
-import javax.cache.annotation.CacheInvocationParameter;
-import javax.cache.annotation.CacheKey;
-import javax.cache.annotation.CacheKeyInvocationContext;
-import javax.cache.annotation.CacheValue;
-import javax.interceptor.InvocationContext;
import java.lang.annotation.Annotation;
-import java.util.Collection;
-import java.util.LinkedList;
+
+import javax.cache.annotation.CacheInvocationParameter;
+import javax.cache.annotation.CacheKeyInvocationContext;
+import javax.interceptor.InvocationContext;
public class CacheKeyInvocationContextImpl<A extends Annotation> extends CacheInvocationContextImpl<A> implements CacheKeyInvocationContext<A>
{
- private final Integer[] keyIndexes;
private CacheInvocationParameter[] keyParams = null;
private CacheInvocationParameter valueParam = null;
public CacheKeyInvocationContextImpl(final InvocationContext delegate, final A annotation, final String name,
- final Integer[] keyIndexes)
+ final CDIJCacheHelper.MethodMeta methodMeta)
{
- super(delegate, annotation, name);
- this.keyIndexes = keyIndexes;
+ super(delegate, annotation, name, methodMeta);
}
@Override
@@ -45,25 +40,7 @@
{
if (keyParams == null)
{
- final Collection<CacheInvocationParameter> keys = new LinkedList<CacheInvocationParameter>();
- for (final CacheInvocationParameter param : getAllParameters())
- {
- for (final Annotation a : param.getAnnotations())
- {
- if (a.annotationType().equals(CacheKey.class))
- {
- keys.add(param);
- }
- }
- }
- if (keys.isEmpty())
- {
- keyParams = doGetAllParameters(keyIndexes);
- }
- else
- {
- keyParams = keys.toArray(new CacheInvocationParameter[keys.size()]);
- }
+ keyParams = doGetAllParameters(meta.getKeysIndices());
}
return keyParams;
}
@@ -73,17 +50,7 @@
{
if (valueParam == null)
{
- for (final CacheInvocationParameter param : getAllParameters())
- {
- for (final Annotation a : param.getAnnotations())
- {
- if (a.annotationType().equals(CacheValue.class))
- {
- valueParam = param;
- return valueParam;
- }
- }
- }
+ valueParam = meta.getValueIndex() >= 0 ? doGetAllParameters(new Integer[]{meta.getValueIndex()})[0] : null;
}
return valueParam;
}
diff --git a/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CacheMethodDetailsImpl.java b/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CacheMethodDetailsImpl.java
index 4f5ac5b..349b27b 100644
--- a/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CacheMethodDetailsImpl.java
+++ b/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CacheMethodDetailsImpl.java
@@ -33,13 +33,16 @@
private final Set<Annotation> annotations;
private final A cacheAnnotation;
private final String cacheName;
+ protected final CDIJCacheHelper.MethodMeta meta;
- public CacheMethodDetailsImpl(final InvocationContext delegate, final A cacheAnnotation, final String cacheName)
+ public CacheMethodDetailsImpl(final InvocationContext delegate, final A cacheAnnotation, final String cacheName,
+ final CDIJCacheHelper.MethodMeta meta)
{
this.delegate = delegate;
- this.annotations = new HashSet<Annotation>(asList(delegate.getMethod().getAnnotations()));
+ this.annotations = meta.getAnnotations();
this.cacheAnnotation = cacheAnnotation;
this.cacheName = cacheName;
+ this.meta = meta;
}
@Override
diff --git a/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CachePutInterceptor.java b/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CachePutInterceptor.java
index 60909f4..c226b06 100644
--- a/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CachePutInterceptor.java
+++ b/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CachePutInterceptor.java
@@ -19,12 +19,13 @@
package org.apache.commons.jcs.jcache.cdi;
import java.io.Serializable;
-import java.lang.reflect.Method;
+
import javax.annotation.Priority;
import javax.cache.Cache;
-import javax.cache.annotation.CacheDefaults;
import javax.cache.annotation.CacheKeyInvocationContext;
import javax.cache.annotation.CachePut;
+import javax.cache.annotation.CacheResolver;
+import javax.cache.annotation.CacheResolverFactory;
import javax.cache.annotation.GeneratedCacheKey;
import javax.inject.Inject;
import javax.interceptor.AroundInvoke;
@@ -42,18 +43,23 @@
@AroundInvoke
public Object cache(final InvocationContext ic) throws Throwable
{
- final CacheDefaults defaults = helper.findDefaults(ic);
+ final CDIJCacheHelper.MethodMeta methodMeta = helper.findMeta(ic);
- final Method method = ic.getMethod();
- final CachePut cachePut = method.getAnnotation(CachePut.class);
- final String cacheName = helper.defaultName(method, defaults, cachePut.cacheName());
- final boolean afterInvocation = cachePut.afterInvocation();
+ final String cacheName = methodMeta.getCacheResultCacheName();
+ final CacheResolverFactory cacheResolverFactory = methodMeta.getCacheResultResolverFactory();
final CacheKeyInvocationContext<CachePut> context = new CacheKeyInvocationContextImpl<CachePut>(
- ic, cachePut, cacheName, helper.keyParameterIndexes(method));
+ ic, methodMeta.getCachePut(), cacheName, methodMeta);
+ final CacheResolver cacheResolver = cacheResolverFactory.getCacheResolver(context);
+ final Cache<Object, Object> cache = cacheResolver.resolveCache(context);
+
+ final GeneratedCacheKey cacheKey = methodMeta.getCacheResultKeyGenerator().generateCacheKey(context);
+ final CachePut cachePut = methodMeta.getCachePut();
+ final boolean afterInvocation = methodMeta.isCachePutAfter();
+
if (!afterInvocation)
{
- doCache(context, defaults, cachePut);
+ cache.put(cacheKey, context.getValueParameter());
}
final Object result;
@@ -67,7 +73,7 @@
{
if (helper.isIncluded(t.getClass(), cachePut.cacheFor(), cachePut.noCacheFor()))
{
- doCache(context, defaults, cachePut);
+ cache.put(cacheKey, context.getValueParameter());
}
}
@@ -76,16 +82,9 @@
if (afterInvocation)
{
- doCache(context, defaults, cachePut);
+ cache.put(cacheKey, context.getValueParameter());
}
return result;
}
-
- private void doCache(final CacheKeyInvocationContext<CachePut> context, final CacheDefaults defaults, final CachePut cachePut)
- {
- final Cache<Object, Object> cache = helper.cacheResolverFactoryFor(defaults, cachePut.cacheResolverFactory()).getCacheResolver(context).resolveCache(context);
- final GeneratedCacheKey key = helper.cacheKeyGeneratorFor(defaults, cachePut.cacheKeyGenerator()).generateCacheKey(context);
- cache.put(key, context.getValueParameter().getValue());
- }
}
diff --git a/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CacheRemoveAllInterceptor.java b/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CacheRemoveAllInterceptor.java
index fe6bb50..cede78f 100644
--- a/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CacheRemoveAllInterceptor.java
+++ b/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CacheRemoveAllInterceptor.java
@@ -19,12 +19,13 @@
package org.apache.commons.jcs.jcache.cdi;
import java.io.Serializable;
-import java.lang.reflect.Method;
+
import javax.annotation.Priority;
import javax.cache.Cache;
-import javax.cache.annotation.CacheDefaults;
import javax.cache.annotation.CacheKeyInvocationContext;
import javax.cache.annotation.CacheRemoveAll;
+import javax.cache.annotation.CacheResolver;
+import javax.cache.annotation.CacheResolverFactory;
import javax.inject.Inject;
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
@@ -41,18 +42,20 @@
@AroundInvoke
public Object cache(final InvocationContext ic) throws Throwable
{
- final CacheDefaults defaults = helper.findDefaults(ic);
+ final CDIJCacheHelper.MethodMeta methodMeta = helper.findMeta(ic);
- final Method method = ic.getMethod();
- final CacheRemoveAll cacheRemoveAll = method.getAnnotation(CacheRemoveAll.class);
- final String cacheName = helper.defaultName(method, defaults, cacheRemoveAll.cacheName());
- final boolean afterInvocation = cacheRemoveAll.afterInvocation();
+ final String cacheName = methodMeta.getCacheResultCacheName();
+ final CacheResolverFactory cacheResolverFactory = methodMeta.getCacheResultResolverFactory();
final CacheKeyInvocationContext<CacheRemoveAll> context = new CacheKeyInvocationContextImpl<CacheRemoveAll>(
- ic, cacheRemoveAll, cacheName, helper.keyParameterIndexes(method));
+ ic, methodMeta.getCacheRemoveAll(), cacheName, methodMeta);
+ final CacheResolver cacheResolver = cacheResolverFactory.getCacheResolver(context);
+ final Cache<Object, Object> cache = cacheResolver.resolveCache(context);
+
+ final boolean afterInvocation = methodMeta.isCachePutAfter();
if (!afterInvocation)
{
- removeAll(context, defaults, cacheRemoveAll);
+ cache.removeAll();
}
final Object result;
@@ -64,9 +67,9 @@
{
if (afterInvocation)
{
- if (helper.isIncluded(t.getClass(), cacheRemoveAll.evictFor(), cacheRemoveAll.noEvictFor()))
+ if (helper.isIncluded(t.getClass(), methodMeta.getCacheRemoveAll().evictFor(), methodMeta.getCacheRemoveAll().noEvictFor()))
{
- removeAll(context, defaults, cacheRemoveAll);
+ cache.removeAll();
}
}
throw t;
@@ -74,15 +77,9 @@
if (afterInvocation)
{
- removeAll(context, defaults, cacheRemoveAll);
+ cache.removeAll();
}
return result;
}
-
- private void removeAll(final CacheKeyInvocationContext<CacheRemoveAll> context, final CacheDefaults defaults, final CacheRemoveAll cacheRemoveAll)
- {
- final Cache<Object, Object> cache = helper.cacheResolverFactoryFor(defaults, cacheRemoveAll.cacheResolverFactory()).getCacheResolver(context).resolveCache(context);
- cache.removeAll();
- }
}
diff --git a/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CacheRemoveInterceptor.java b/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CacheRemoveInterceptor.java
index 29f4965..f28a128 100644
--- a/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CacheRemoveInterceptor.java
+++ b/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CacheRemoveInterceptor.java
@@ -19,12 +19,13 @@
package org.apache.commons.jcs.jcache.cdi;
import java.io.Serializable;
-import java.lang.reflect.Method;
+
import javax.annotation.Priority;
import javax.cache.Cache;
-import javax.cache.annotation.CacheDefaults;
import javax.cache.annotation.CacheKeyInvocationContext;
import javax.cache.annotation.CacheRemove;
+import javax.cache.annotation.CacheResolver;
+import javax.cache.annotation.CacheResolverFactory;
import javax.cache.annotation.GeneratedCacheKey;
import javax.inject.Inject;
import javax.interceptor.AroundInvoke;
@@ -42,19 +43,23 @@
@AroundInvoke
public Object cache(final InvocationContext ic) throws Throwable
{
- final CacheDefaults defaults = helper.findDefaults(ic);
+ final CDIJCacheHelper.MethodMeta methodMeta = helper.findMeta(ic);
- final Method method = ic.getMethod();
- final CacheRemove cacheRemove = method.getAnnotation(CacheRemove.class);
- final String cacheName = helper.defaultName(method, defaults, cacheRemove.cacheName());
- final boolean afterInvocation = cacheRemove.afterInvocation();
+ final String cacheName = methodMeta.getCacheResultCacheName();
- final CacheKeyInvocationContext<CacheRemove> context =
- new CacheKeyInvocationContextImpl<CacheRemove>(ic, cacheRemove, cacheName, helper.keyParameterIndexes(method));
+ final CacheResolverFactory cacheResolverFactory = methodMeta.getCacheResultResolverFactory();
+ final CacheKeyInvocationContext<CacheRemove> context = new CacheKeyInvocationContextImpl<CacheRemove>(
+ ic, methodMeta.getCacheRemove(), cacheName, methodMeta);
+ final CacheResolver cacheResolver = cacheResolverFactory.getCacheResolver(context);
+ final Cache<Object, Object> cache = cacheResolver.resolveCache(context);
+
+ final GeneratedCacheKey cacheKey = methodMeta.getCacheResultKeyGenerator().generateCacheKey(context);
+ final CacheRemove cacheRemove = methodMeta.getCacheRemove();
+ final boolean afterInvocation = methodMeta.isCacheRemoveAfter();
if (!afterInvocation)
{
- doRemove(context, defaults, cacheRemove);
+ cache.remove(cacheKey);
}
final Object result;
@@ -68,7 +73,7 @@
{
if (helper.isIncluded(t.getClass(), cacheRemove.evictFor(), cacheRemove.noEvictFor()))
{
- doRemove(context, defaults, cacheRemove);
+ cache.remove(cacheKey);
}
}
@@ -77,16 +82,9 @@
if (afterInvocation)
{
- doRemove(context, defaults, cacheRemove);
+ cache.remove(cacheKey);
}
return result;
}
-
- private void doRemove(final CacheKeyInvocationContext<CacheRemove> context, final CacheDefaults defaults, final CacheRemove cacheRemove)
- {
- final Cache<Object, Object> cache = helper.cacheResolverFactoryFor(defaults, cacheRemove.cacheResolverFactory()).getCacheResolver(context).resolveCache(context);
- final GeneratedCacheKey key = helper.cacheKeyGeneratorFor(defaults, cacheRemove.cacheKeyGenerator()).generateCacheKey(context);
- cache.remove(key);
- }
}
diff --git a/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CacheResultInterceptor.java b/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CacheResultInterceptor.java
index 1b6a653..e58ad34 100644
--- a/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CacheResultInterceptor.java
+++ b/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CacheResultInterceptor.java
@@ -22,7 +22,6 @@
import java.lang.reflect.Method;
import javax.annotation.Priority;
import javax.cache.Cache;
-import javax.cache.annotation.CacheDefaults;
import javax.cache.annotation.CacheKeyInvocationContext;
import javax.cache.annotation.CacheResolver;
import javax.cache.annotation.CacheResolverFactory;
@@ -44,20 +43,19 @@
@AroundInvoke
public Object cache(final InvocationContext ic) throws Throwable
{
- final CacheDefaults defaults = helper.findDefaults(ic);
+ final CDIJCacheHelper.MethodMeta methodMeta = helper.findMeta(ic);
- final Method method = ic.getMethod();
- final CacheResult cacheResult = method.getAnnotation(CacheResult.class);
- final String cacheName = helper.defaultName(method, defaults, cacheResult.cacheName());
+ final String cacheName = methodMeta.getCacheResultCacheName();
+ final CacheResult cacheResult = methodMeta.getCacheResult();
final CacheKeyInvocationContext<CacheResult> context = new CacheKeyInvocationContextImpl<CacheResult>(
- ic, cacheResult, cacheName, helper.keyParameterIndexes(method));
+ ic, cacheResult, cacheName, methodMeta);
- final CacheResolverFactory cacheResolverFactory = helper.cacheResolverFactoryFor(defaults, cacheResult.cacheResolverFactory());
+ final CacheResolverFactory cacheResolverFactory = methodMeta.getCacheResultResolverFactory();
final CacheResolver cacheResolver = cacheResolverFactory.getCacheResolver(context);
final Cache<Object, Object> cache = cacheResolver.resolveCache(context);
- final GeneratedCacheKey cacheKey = helper.cacheKeyGeneratorFor(defaults, cacheResult.cacheKeyGenerator()).generateCacheKey(context);
+ final GeneratedCacheKey cacheKey = methodMeta.getCacheResultKeyGenerator().generateCacheKey(context);
Cache<Object, Object> exceptionCache = null; // lazily created