diff --git a/pom.xml b/pom.xml index aa45ebf..aa756a5 100644 --- a/pom.xml +++ b/pom.xml @@ -91,7 +91,7 @@ org.apache.openejb openejb-core - 4.7.1 + 4.7.4 test @@ -99,7 +99,7 @@ com.hazelcast hazelcast - 3.4.1 + 3.7.4 test diff --git a/src/main/java/org/tomitribe/jcache/cdi/DeclarativeCache.java b/src/main/java/org/tomitribe/jcache/cdi/DeclarativeCache.java new file mode 100644 index 0000000..2af005e --- /dev/null +++ b/src/main/java/org/tomitribe/jcache/cdi/DeclarativeCache.java @@ -0,0 +1,22 @@ +package org.tomitribe.jcache.cdi; + +import javax.enterprise.util.Nonbinding; +import javax.inject.Qualifier; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Qualifier +@Inherited +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD, ElementType.FIELD}) +public @interface DeclarativeCache +{ + @Nonbinding String value() default ""; + + @Nonbinding Class keyType() default Object.class; + + @Nonbinding Class valueType() default Object.class; +} diff --git a/src/main/java/org/tomitribe/jcache/cdi/ExtraJCacheExtension.java b/src/main/java/org/tomitribe/jcache/cdi/ExtraJCacheExtension.java index c403f74..3306788 100644 --- a/src/main/java/org/tomitribe/jcache/cdi/ExtraJCacheExtension.java +++ b/src/main/java/org/tomitribe/jcache/cdi/ExtraJCacheExtension.java @@ -18,27 +18,42 @@ */ package org.tomitribe.jcache.cdi; +import javax.cache.Cache; import javax.cache.CacheManager; import javax.cache.Caching; import javax.cache.spi.CachingProvider; +import javax.enterprise.context.Dependent; import javax.enterprise.event.Observes; +import javax.enterprise.inject.Produces; import javax.enterprise.inject.spi.AfterBeanDiscovery; +import javax.enterprise.inject.spi.AnnotatedType; import javax.enterprise.inject.spi.Bean; +import javax.enterprise.inject.spi.BeanManager; +import javax.enterprise.inject.spi.BeforeBeanDiscovery; import javax.enterprise.inject.spi.BeforeShutdown; import javax.enterprise.inject.spi.Extension; +import javax.enterprise.inject.spi.InjectionPoint; import javax.enterprise.inject.spi.ProcessBean; import java.util.Properties; // add default CacheProvider and CacheManager public class ExtraJCacheExtension implements Extension { - private static final boolean ACTIVATED = "true".equals(System.getProperty("org.apache.jcs.extra.cdi", "true")); + private static final String PROPERTY_LEGACY_ACTIVATION = "org.apache.jcs.extra.cdi"; + private static final String PROPERTY_ACTIVATION = "org.apache.jcache.extra.cdi"; + private static final boolean ACTIVATED = isExtensionActivated(); private boolean cacheManagerFound = false; private boolean cacheProviderFound = false; private CacheManager cacheManager; private CachingProvider cachingProvider; + public void addCacheProducer(final @Observes BeforeBeanDiscovery beforeBeanDiscovery, BeanManager beanManager) + { + AnnotatedType annotatedType = beanManager.createAnnotatedType(DeclarativeCacheProducer.class); + beforeBeanDiscovery.addAnnotatedType(annotatedType); + } + public void processBean(final @Observes ProcessBean processBeanEvent) { if (!ACTIVATED) @@ -104,4 +119,43 @@ public void destroyIfCreated(final @Observes BeforeShutdown beforeShutdown) cachingProvider.close(); } } + + private static boolean isExtensionActivated() { + String val = System.getProperty(PROPERTY_ACTIVATION); + if (val == null) + { + val = System.getProperty(PROPERTY_LEGACY_ACTIVATION); + } + if (val == null) + { + val = "true"; + } + return "true".equals(val); + } + + public static final class DeclarativeCacheProducer { + + @Produces + @Dependent + @DeclarativeCache + public Cache injectDeclarativeCache(final InjectionPoint injectionPoint, final CacheManager cacheManager) + { + DeclarativeCache annotation = injectionPoint.getAnnotated().getAnnotation(DeclarativeCache.class); + if (annotation == null) + { + return null; + } + + String cacheName = annotation.value(); + + Class keyType = annotation.keyType(); + Class valueType = annotation.valueType(); + + if (keyType == Object.class && valueType == Object.class) + { + return cacheManager.getCache(cacheName); + } + return cacheManager.getCache(cacheName, keyType, valueType); + } + } } diff --git a/src/test/java/org/tomitribe/jcache/cdi/ExtraJCacheExtensionTest.java b/src/test/java/org/tomitribe/jcache/cdi/ExtraJCacheExtensionTest.java index da56ff4..e7abb7f 100644 --- a/src/test/java/org/tomitribe/jcache/cdi/ExtraJCacheExtensionTest.java +++ b/src/test/java/org/tomitribe/jcache/cdi/ExtraJCacheExtensionTest.java @@ -22,13 +22,18 @@ import org.junit.Before; import org.junit.Test; +import javax.cache.Cache; import javax.cache.CacheManager; +import javax.cache.configuration.Configuration; import javax.cache.spi.CachingProvider; import javax.ejb.embeddable.EJBContainer; import javax.inject.Inject; +import javax.persistence.criteria.CriteriaBuilder; import java.util.Random; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertSame; public class ExtraJCacheExtensionTest { @@ -91,6 +96,31 @@ public void defaultCacheProvider() assertNotNull(bean.getProvider()); } + @Test + public void declarativeCacheCache1() { + Cache cache1 = bean.getCache1(); + assertNotNull(cache1); + Configuration configuration = cache1.getConfiguration(Configuration.class); + assertSame(String.class, configuration.getKeyType()); + assertSame(String.class, configuration.getValueType()); + } + + @Test + public void declarativeCacheCache2() { + Cache cache2 = bean.getCache2(); + assertNotNull(cache2); + Configuration configuration = cache2.getConfiguration(Configuration.class); + assertSame(Integer.class, configuration.getKeyType()); + assertSame(Integer.class, configuration.getValueType()); + } + + @Test + public void declarativeCachesNotSame() { + Cache cache1 = bean.getCache1(); + Cache cache2 = bean.getCache2(); + assertNotSame(cache1, cache2); + } + public static class BeanWithInjections { @Inject private CacheManager mgr; @@ -98,6 +128,18 @@ public static class BeanWithInjections { @Inject private CachingProvider provider; + @Inject + @DeclarativeCache(value = "test1", keyType = String.class, valueType = String.class) + private Cache cache1; + + @Inject + @DeclarativeCache(value = "test2", keyType = Integer.class, valueType = Integer.class) + private Cache cache2; + + @Inject + @DeclarativeCache(value = "test3") + private Cache cache3; + public CacheManager getMgr() { return mgr; @@ -107,6 +149,16 @@ public CachingProvider getProvider() { return provider; } + + public Cache getCache1() + { + return cache1; + } + + public Cache getCache2() + { + return cache2; + } } } diff --git a/src/test/resources/hazelcast-client.xml b/src/test/resources/hazelcast-client.xml index 6eae6be..de548c9 100644 --- a/src/test/resources/hazelcast-client.xml +++ b/src/test/resources/hazelcast-client.xml @@ -15,7 +15,7 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> - diff --git a/src/test/resources/hazelcast.xml b/src/test/resources/hazelcast.xml new file mode 100644 index 0000000..b2fba43 --- /dev/null +++ b/src/test/resources/hazelcast.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + \ No newline at end of file