Skip to content
Browse files

ISPN-2639 Initial JSR 107 implementation

* Basic operations and validation supported.
  • Loading branch information...
1 parent 2512668 commit b0636a7c06df5e81c2cfd79ac2bcd02cd69e4ab8 @vblagoje vblagoje committed with maniksurtani
Showing with 2,185 additions and 0 deletions.
  1. +98 −0 jsr107impl/pom.xml
  2. +88 −0 jsr107impl/src/main/java/org/infinispan/jsr107/cache/ConfigurationAdapter.java
  3. +398 −0 jsr107impl/src/main/java/org/infinispan/jsr107/cache/InfinispanCache.java
  4. +44 −0 jsr107impl/src/main/java/org/infinispan/jsr107/cache/InfinispanCacheEntry.java
  5. +139 −0 jsr107impl/src/main/java/org/infinispan/jsr107/cache/InfinispanCacheListenerAdapter.java
  6. +80 −0 jsr107impl/src/main/java/org/infinispan/jsr107/cache/InfinispanCacheLoaderAdapter.java
  7. +247 −0 jsr107impl/src/main/java/org/infinispan/jsr107/cache/InfinispanCacheManager.java
  8. +141 −0 jsr107impl/src/main/java/org/infinispan/jsr107/cache/InfinispanCacheManagerFactory.java
  9. +104 −0 jsr107impl/src/main/java/org/infinispan/jsr107/cache/InfinispanCacheWriterAdapter.java
  10. +54 −0 jsr107impl/src/main/java/org/infinispan/jsr107/cache/InfinispanCachingProvider.java
  11. +54 −0 jsr107impl/src/main/java/org/infinispan/jsr107/cache/InfinispanStatusConverter.java
  12. +118 −0 jsr107impl/src/main/java/org/infinispan/jsr107/cache/RICacheEntryEvent.java
  13. +64 −0 jsr107impl/src/main/java/org/infinispan/jsr107/cache/RICacheEntryEventFilteringIterable.java
  14. +114 −0 jsr107impl/src/main/java/org/infinispan/jsr107/cache/RICacheEntryEventFilteringIterator.java
  15. +141 −0 jsr107impl/src/main/java/org/infinispan/jsr107/cache/RICacheEntryListenerRegistration.java
  16. +300 −0 jsr107impl/src/main/java/org/infinispan/jsr107/cache/RICacheStatistics.java
  17. +1 −0 jsr107impl/src/main/resources/META-INF/services/javax.cache.spi.CachingProvider
View
98 jsr107impl/pom.xml
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- ~ JBoss, Home of Professional Open Source ~ Copyright 2012 Red Hat Inc.
+ and/or its affiliates and other ~ contributors as indicated by the @author
+ tags. All rights reserved. ~ See the copyright.txt in the distribution for
+ a full listing of ~ individual contributors. ~ ~ This is free software; you
+ can redistribute it and/or modify it ~ under the terms of the GNU Lesser
+ General Public License as ~ published by the Free Software Foundation; either
+ version 2.1 of ~ the License, or (at your option) any later version. ~ ~
+ This software is distributed in the hope that it will be useful, ~ but WITHOUT
+ ANY WARRANTY; without even the implied warranty of ~ MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU ~ Lesser General Public License for
+ more details. ~ ~ You should have received a copy of the GNU Lesser General
+ Public ~ License along with this software; if not, write to the Free ~ Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA ~ 02110-1301 USA,
+ or see the FSF site: http://www.fsf.org. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.infinispan</groupId>
+ <artifactId>infinispan-parent</artifactId>
+ <version>5.2.0-SNAPSHOT</version>
+ <relativePath>../parent/pom.xml</relativePath>
+ </parent>
+
+ <artifactId>infinispan-jsr107</artifactId>
+ <packaging>bundle</packaging>
+ <name>Infinispan JSR107 implementation</name>
+ <description>JSR107 implementation using Infinispan</description>
+
+ <!-- This module declares components that either has lifecycle (@Start or
+ @Stop) or uses @Inject to retrieve dependencies -->
+ <properties>
+ <module.skipComponentMetaDataProcessing>false</module.skipComponentMetaDataProcessing>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>infinispan-core</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.cache</groupId>
+ <artifactId>cache-api</artifactId>
+ <version>0.6-SNAPSHOT</version>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.cache.implementation</groupId>
+ <artifactId>cache-ri-common</artifactId>
+ <version>0.6-SNAPSHOT</version>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.enterprise</groupId>
+ <artifactId>cdi-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>infinispan-core</artifactId>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+ <repositories>
+ <repository>
+ <releases>
+ <enabled>true</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ <id>sonatype-snapshot-repository</id>
+ <name>Sonatype snapshot to be removed once everything becomes stable</name>
+ <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+ </repository>
+ </repositories>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <configuration>
+ <instructions>
+ <Export-Package>
+ ${project.groupId}.jsr107.*;version=${project.version};-split-package:=error
+ </Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
View
88 jsr107impl/src/main/java/org/infinispan/jsr107/cache/ConfigurationAdapter.java
@@ -0,0 +1,88 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tag. All rights reserved.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+package org.infinispan.jsr107.cache;
+
+import org.infinispan.configuration.cache.CacheMode;
+import org.infinispan.configuration.cache.ConfigurationBuilder;
+import org.infinispan.transaction.TransactionMode;
+
+/**
+ * ConfigurationAdapter takes {@link javax.cache.Configuration} and creates equivalent instance of
+ * {@link org.infinispan.configuration.cache.Configuration}
+ *
+ * @author Vladimir Blagojevic
+ * @since 5.3
+ */
+public class ConfigurationAdapter<K, V> {
+
+ private javax.cache.Configuration<K, V> c;
+ private ClassLoader classLoader;
+
+ public ConfigurationAdapter(javax.cache.Configuration<K, V> configuration,
+ ClassLoader classLoader) {
+ this.c = configuration;
+ this.classLoader = classLoader;
+ }
+
+ public org.infinispan.configuration.cache.Configuration build() {
+ ConfigurationBuilder cb = new ConfigurationBuilder();
+ cb.storeAsBinary().enabled(c.isStoreByValue());
+ cb.classLoader(classLoader);
+ cb.clustering().cacheMode(CacheMode.DIST_SYNC);
+
+ switch (c.getTransactionMode()) {
+ case NONE:
+ cb.transaction().transactionMode(TransactionMode.NON_TRANSACTIONAL);
+ break;
+ case LOCAL:
+ cb.transaction().transactionMode(TransactionMode.TRANSACTIONAL);
+ break;
+ case XA:
+ //TODO
+ break;
+ default:
+ break;
+ }
+ switch (c.getTransactionIsolationLevel()) {
+ case NONE:
+ cb.locking().isolationLevel(org.infinispan.util.concurrent.IsolationLevel.NONE);
+ break;
+ case READ_UNCOMMITTED:
+ cb.locking().isolationLevel(
+ org.infinispan.util.concurrent.IsolationLevel.READ_UNCOMMITTED);
+ break;
+ case READ_COMMITTED:
+ cb.locking().isolationLevel(
+ org.infinispan.util.concurrent.IsolationLevel.READ_COMMITTED);
+ break;
+ case REPEATABLE_READ:
+ cb.locking().isolationLevel(
+ org.infinispan.util.concurrent.IsolationLevel.REPEATABLE_READ);
+ break;
+ case SERIALIZABLE:
+ cb.locking().isolationLevel(org.infinispan.util.concurrent.IsolationLevel.SERIALIZABLE);
+ break;
+ default:
+ break;
+ }
+ //TODO
+ //whatever else is needed
+ return cb.build();
+ }
+}
View
398 jsr107impl/src/main/java/org/infinispan/jsr107/cache/InfinispanCache.java
@@ -0,0 +1,398 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tag. All rights reserved.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+package org.infinispan.jsr107.cache;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
+
+import javax.cache.Cache;
+import javax.cache.CacheLoader;
+import javax.cache.Configuration;
+import javax.cache.CacheManager;
+import javax.cache.CacheStatistics;
+import javax.cache.ExpiryPolicy;
+import javax.cache.SimpleConfiguration;
+import javax.cache.Status;
+import javax.cache.event.CacheEntryEventFilter;
+import javax.cache.event.CacheEntryListener;
+import javax.cache.event.CacheEntryListenerException;
+import javax.cache.event.CacheEntryListenerRegistration;
+import javax.cache.mbeans.CacheMXBean;
+
+import org.infinispan.util.InfinispanCollections;
+import org.jsr107.ri.DelegatingCacheMXBean;
+
+
+/**
+ * InfinispanCache is Infinispan's implementation of {@link javax.cache.Cache} interface.
+ *
+ * @author Vladimir Blagojevic
+ * @since 5.3
+ */
+public class InfinispanCache<K, V> implements Cache<K, V> {
+
+ private final InfinispanCacheManager cacheManager;
+ private final Configuration<K, V> configuration;
+ private final org.infinispan.Cache<K, V> delegateCache;
+ private final CacheStatistics stats;
+ private final CacheMXBean mxBean;
+ private final ConcurrentHashMap<CacheEntryListener<? super K, ? super V>, CacheEntryListenerRegistration<? super K, ? super V>> listeners = new ConcurrentHashMap<CacheEntryListener<? super K, ? super V>, CacheEntryListenerRegistration<? super K, ? super V>>();
+
+ private final ExpiryPolicy<? super K, ? super V> expiryPolicy;
+ private final ExecutorService executorService = Executors.newFixedThreadPool(1);
+
+ public InfinispanCache(org.infinispan.Cache<K, V> delegateCache,
+ InfinispanCacheManager cacheManager, ClassLoader classLoader, Configuration<K, V> c) {
+ super();
+ this.delegateCache = delegateCache;
+ this.cacheManager = cacheManager;
+ // a configuration copy as required by the spec
+ this.configuration = new SimpleConfiguration<K, V>(c);
+ this.mxBean = new DelegatingCacheMXBean<K, V>(this);
+ this.stats = new RICacheStatistics(this);
+ this.expiryPolicy = configuration.getExpiryPolicy();
+
+ for (CacheEntryListenerRegistration<? super K, ? super V> r : c
+ .getCacheEntryListenerRegistrations()) {
+
+ RICacheEntryListenerRegistration<K, V> lr = new RICacheEntryListenerRegistration<K, V>(
+ r.getCacheEntryListener(), r.getCacheEntryFilter(), r.isOldValueRequired(),
+ r.isSynchronous());
+
+ listeners.put(r.getCacheEntryListener(), lr);
+ }
+ }
+
+ public Map<CacheEntryListener<? super K, ? super V>, CacheEntryListenerRegistration<? super K, ? super V>> getListeners(){
+ return listeners;
+ }
+
+ @Override
+ public Status getStatus() {
+ return InfinispanStatusConverter.convert(delegateCache.getStatus());
+ }
+
+ @Override
+ public void start() {
+ // no op
+ //TOOD need to check state before start?
+ delegateCache.start();
+
+ //add listener as they were wiped out on stop
+ delegateCache.addListener(new InfinispanCacheListenerAdapter<K,V>(this));
+ }
+
+ @Override
+ public void stop() {
+ delegateCache.stop();
+ }
+
+ @Override
+ public void clear() {
+ delegateCache.clear();
+ }
+
+ @Override
+ public boolean containsKey(K key) {
+ checkStarted();
+ return delegateCache.containsKey(key);
+ }
+
+ @Override
+ public V get(K key) {
+ checkStarted();
+ V result = delegateCache.get(key);
+ return result;
+ }
+
+ @Override
+ public Map<K, V> getAll(Set<? extends K> keys) {
+ checkStarted();
+ verifyKeys(keys);
+ if (keys.isEmpty()) {
+ return InfinispanCollections.emptyMap();
+ }
+
+ /**
+ * TODO: Just an idea here to consider down the line: if keys.size() is big (TBD...), each of
+ * this get calls could maybe be swapped by getAsync() in order to paralelise the retrieval of
+ * entries. It'd be interesting to do a small performance test to see after which number of
+ * elements doing it in paralel becomes more efficient than sequential :)
+ */
+ Map<K, V> result = new HashMap<K, V>(keys.size());
+ for (K key : keys) {
+ V value = get(key);
+ if (value != null) {
+ result.put(key, value);
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public V getAndPut(K key, V value) {
+ checkStarted();
+ V prev = delegateCache.put(key, value);
+ return prev;
+ }
+
+ @Override
+ public V getAndRemove(K key) {
+ checkStarted();
+ V v = delegateCache.remove(key);
+ return v;
+
+ }
+
+ @Override
+ public V getAndReplace(K key, V value) {
+ checkStarted();
+ V prev = delegateCache.replace(key, value);
+ return prev;
+ }
+
+ @Override
+ public CacheManager getCacheManager() {
+ return cacheManager;
+ }
+
+ @Override
+ public Configuration<K, V> getConfiguration() {
+ return configuration;
+ }
+
+ @Override
+ public CacheMXBean getMBean() {
+ return mxBean;
+ }
+
+ @Override
+ public String getName() {
+ return delegateCache.getName();
+ }
+
+ @Override
+ public CacheStatistics getStatistics() {
+ checkStarted();
+ if (configuration.isStatisticsEnabled()) {
+ return stats;
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public <T> T invokeEntryProcessor(K key, EntryProcessor<K, V, T> entryProcessor) {
+ checkStarted();
+ // TODO
+ return null;
+ }
+
+ @Override
+ public Iterator<javax.cache.Cache.Entry<K, V>> iterator() {
+ checkStarted();
+ // TODO
+ return null;
+ }
+
+ @Override
+ public Future<V> load(final K key) {
+ checkStarted();
+
+ final CacheLoader<K, ? extends V> cacheLoader = configuration.getCacheLoader();
+
+ // spec required
+ if (cacheLoader == null || containsKey(key)) {
+ return null;
+ }
+
+ FutureTask<V> task = new FutureTask<V>(new Callable<V>() {
+
+ @Override
+ public V call() throws Exception {
+ Entry<K, ? extends V> entry = cacheLoader.load(key);
+ put(entry.getKey(), entry.getValue());
+ return entry.getValue();
+ }
+ });
+ executorService.submit(task);
+ return task;
+ }
+
+ @Override
+ public Future<Map<K, ? extends V>> loadAll(final Set<? extends K> keys) {
+ checkStarted();
+ verifyKeys(keys);
+ final CacheLoader<K, ? extends V> cacheLoader = configuration.getCacheLoader();
+
+ if (cacheLoader == null) {
+ return null;
+ }
+
+ FutureTask<Map<K, ? extends V>> task = new FutureTask<Map<K, ? extends V>>(
+ new Callable<Map<K, ? extends V>>() {
+
+ @Override
+ public Map<K, ? extends V> call() throws Exception {
+ ArrayList<K> keysNotInStore = new ArrayList<K>();
+ for (K key : keys) {
+ if (!containsKey(key)) {
+ keysNotInStore.add(key);
+ }
+ }
+ Map<K, ? extends V> value = cacheLoader.loadAll(keysNotInStore);
+ putAll(value);
+ return value;
+ }
+ });
+ executorService.submit(task);
+ return task;
+ }
+
+ @Override
+ public void put(K key, V value) {
+ checkStarted();
+ // TODO use ignore flag
+ delegateCache.put(key, value);
+ }
+
+ @Override
+ public void putAll(Map<? extends K, ? extends V> inputMap) {
+ checkStarted();
+ // spec required check
+ if (inputMap == null || inputMap.containsKey(null) || inputMap.containsValue(null)) {
+ throw new NullPointerException("inputMap is null or keys/values contain a null entry: "
+ + inputMap);
+ }
+ /**
+ * TODO Similar to mentioned before, it'd be interesting to see if multiple putAsync() calls
+ * could be executed in parallel to speed up.
+ *
+ */
+ for (java.util.Map.Entry<? extends K, ? extends V> e : inputMap.entrySet()) {
+ put(e.getKey(), e.getValue());
+ }
+
+ }
+
+ @Override
+ public boolean putIfAbsent(K key, V value) {
+ checkStarted();
+ return delegateCache.putIfAbsent(key, value) == null;
+ }
+
+ @Override
+ public boolean registerCacheEntryListener(
+ CacheEntryListener<? super K, ? super V> cacheEntryListener, boolean requireOldValue,
+ CacheEntryEventFilter<? super K, ? super V> cacheEntryFilter, boolean synchronous) {
+ if (cacheEntryListener == null) {
+ throw new CacheEntryListenerException("A listener may not be null");
+ }
+ RICacheEntryListenerRegistration<K, V> registration = new RICacheEntryListenerRegistration<K, V>(
+ cacheEntryListener, cacheEntryFilter, requireOldValue, synchronous);
+ return listeners.putIfAbsent(cacheEntryListener, registration) != null;
+ }
+
+ @Override
+ public boolean remove(K key) {
+ checkStarted();
+ V remove = delegateCache.remove(key);
+ return remove != null;
+ }
+
+ @Override
+ public boolean remove(K key, V oldValue) {
+ checkStarted();
+ return delegateCache.remove(key, oldValue);
+ }
+
+ @Override
+ public void removeAll() {
+ checkStarted();
+ // TODO like clear but have to notify listeners
+ delegateCache.clear();
+ }
+
+ @Override
+ public void removeAll(Set<? extends K> keys) {
+ checkStarted();
+ // TODO remove but notify listeners
+ verifyKeys(keys);
+ for (K k : keys) {
+ remove(k);
+ }
+ }
+
+ @Override
+ public boolean replace(K key, V value) {
+ checkStarted();
+ V replace = delegateCache.replace(key, value);
+ return replace != null;
+ }
+
+ @Override
+ public boolean replace(K key, V oldValue, V newValue) {
+ checkStarted();
+ return delegateCache.replace(key, oldValue, newValue);
+ }
+
+ @Override
+ public boolean unregisterCacheEntryListener(CacheEntryListener<?, ?> cacheEntryListener) {
+ if (cacheEntryListener == null) {
+ return false;
+ } else {
+ return listeners.remove(cacheEntryListener) != null;
+ }
+ }
+
+ @Override
+ public <T> T unwrap(Class<T> clazz) {
+ if (clazz.isAssignableFrom(this.getClass())) {
+ return clazz.cast(this);
+ } else {
+ throw new IllegalArgumentException("Unwrapping to type " + clazz + " failed ");
+ }
+ }
+
+ public long size() {
+ return delegateCache.size();
+ }
+
+ private void checkStarted() {
+ if (!getStatus().equals(Status.STARTED)) {
+ throw new IllegalStateException("Cache is in " + getStatus() + " state");
+ }
+ }
+
+ private void verifyKeys(Set<? extends K> keys) {
+ // spec required
+ if (keys == null || keys.contains(null)) {
+ throw new NullPointerException("keys is null or keys contains a null: " + keys);
+ }
+ }
+}
View
44 jsr107impl/src/main/java/org/infinispan/jsr107/cache/InfinispanCacheEntry.java
@@ -0,0 +1,44 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tag. All rights reserved.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+package org.infinispan.jsr107.cache;
+
+import javax.cache.Cache.Entry;
+
+import org.infinispan.container.entries.InternalCacheEntry;
+
+public class InfinispanCacheEntry<K, V> implements Entry<K, V> {
+
+ private final InternalCacheEntry ce;
+
+ public InfinispanCacheEntry(InternalCacheEntry ce) {
+ super();
+ this.ce = ce;
+ }
+
+ @Override
+ public K getKey() {
+ return (K) ce.getKey();
+ }
+
+ @Override
+ public V getValue() {
+ return (V) ce.getValue();
+ }
+
+}
View
139 jsr107impl/src/main/java/org/infinispan/jsr107/cache/InfinispanCacheListenerAdapter.java
@@ -0,0 +1,139 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tag. All rights reserved.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+package org.infinispan.jsr107.cache;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.cache.event.CacheEntryCreatedListener;
+import javax.cache.event.CacheEntryEvent;
+import javax.cache.event.CacheEntryEventFilter;
+import javax.cache.event.CacheEntryListener;
+import javax.cache.event.CacheEntryListenerRegistration;
+import javax.cache.event.CacheEntryReadListener;
+import javax.cache.event.CacheEntryRemovedListener;
+import javax.cache.event.CacheEntryUpdatedListener;
+
+import org.infinispan.notifications.Listener;
+import org.infinispan.notifications.cachelistener.annotation.CacheEntryCreated;
+import org.infinispan.notifications.cachelistener.annotation.CacheEntryModified;
+import org.infinispan.notifications.cachelistener.annotation.CacheEntryRemoved;
+import org.infinispan.notifications.cachelistener.annotation.CacheEntryVisited;
+import org.infinispan.notifications.cachelistener.event.CacheEntryCreatedEvent;
+import org.infinispan.notifications.cachelistener.event.CacheEntryModifiedEvent;
+import org.infinispan.notifications.cachelistener.event.CacheEntryRemovedEvent;
+import org.infinispan.notifications.cachelistener.event.CacheEntryVisitedEvent;
+
+/**
+ * InfinispanCacheListenerAdapter as its name implies adapts Infinispan notification mechanism to
+ * JSR 107 notification mechanism.
+ *
+ *
+ * @author Vladimir Blagojevic
+ * @since 5.3
+ */
+@Listener
+public class InfinispanCacheListenerAdapter<K, V> {
+ private final InfinispanCache<K, V> cache;
+
+ public InfinispanCacheListenerAdapter(InfinispanCache<K, V> infinispanCache) {
+ this.cache = infinispanCache;
+ }
+
+ @CacheEntryCreated
+ public void handleCacheEntryCreatedEvent(CacheEntryCreatedEvent<K, V> e) {
+ //TODO as CacheEntryEvent does not have value...it will cause NPE in listener invocation tck test
+ RICacheEntryEvent<K, V> jsrEvent = new RICacheEntryEvent<K, V>(cache, e.getKey(), null);
+ List<CacheEntryEvent<K, V>> events = new ArrayList<CacheEntryEvent<K, V>>();
+ events.add(jsrEvent);
+
+ for (CacheEntryListenerRegistration<? super K, ? super V> registration : cache.getListeners()
+ .values()) {
+ CacheEntryEventFilter<? super K, ? super V> filter = registration.getCacheEntryFilter();
+ Iterable<CacheEntryEvent<K, V>> iterable = filter == null ? events
+ : new RICacheEntryEventFilteringIterable<K, V>(events, filter);
+
+ CacheEntryListener<? super K, ? super V> listener = registration.getCacheEntryListener();
+ if (listener instanceof CacheEntryCreatedListener) {
+ ((CacheEntryCreatedListener) listener).onCreated(iterable);
+ }
+ }
+ }
+
+ @CacheEntryModified
+ public void handleCacheEntryModifiedEvent(CacheEntryModifiedEvent<K, V> e) {
+ RICacheEntryEvent<K, V> jsrEvent = new RICacheEntryEvent<K, V>(cache, e.getKey(),
+ e.getValue());
+ List<CacheEntryEvent<K, V>> events = new ArrayList<CacheEntryEvent<K, V>>();
+ events.add(jsrEvent);
+
+ for (CacheEntryListenerRegistration<? super K, ? super V> registration : cache.getListeners()
+ .values()) {
+ CacheEntryEventFilter<? super K, ? super V> filter = registration.getCacheEntryFilter();
+ Iterable<CacheEntryEvent<K, V>> iterable = filter == null ? events
+ : new RICacheEntryEventFilteringIterable<K, V>(events, filter);
+
+ CacheEntryListener<? super K, ? super V> listener = registration.getCacheEntryListener();
+ if (listener instanceof CacheEntryUpdatedListener) {
+ ((CacheEntryUpdatedListener) listener).onUpdated(iterable);
+ }
+ }
+ }
+
+ @CacheEntryRemoved
+ public void handleCacheEntryRemovedEvent(CacheEntryRemovedEvent<K, V> e) {
+ RICacheEntryEvent<K, V> jsrEvent = new RICacheEntryEvent<K, V>(cache, e.getKey(),
+ e.getValue());
+ List<CacheEntryEvent<K, V>> events = new ArrayList<CacheEntryEvent<K, V>>();
+ events.add(jsrEvent);
+
+ for (CacheEntryListenerRegistration<? super K, ? super V> registration : cache.getListeners()
+ .values()) {
+ CacheEntryEventFilter<? super K, ? super V> filter = registration.getCacheEntryFilter();
+ Iterable<CacheEntryEvent<K, V>> iterable = filter == null ? events
+ : new RICacheEntryEventFilteringIterable<K, V>(events, filter);
+
+ CacheEntryListener<? super K, ? super V> listener = registration.getCacheEntryListener();
+ if (listener instanceof CacheEntryRemovedListener) {
+ ((CacheEntryRemovedListener) listener).onRemoved(iterable);
+ }
+ }
+ }
+
+ @CacheEntryVisited
+ public void handleCacheEntryVisitedEvent(CacheEntryVisitedEvent<K, V> e) {
+ RICacheEntryEvent<K, V> jsrEvent = new RICacheEntryEvent<K, V>(cache, e.getKey(),
+ e.getValue());
+ List<CacheEntryEvent<K, V>> events = new ArrayList<CacheEntryEvent<K, V>>();
+ events.add(jsrEvent);
+
+ for (CacheEntryListenerRegistration<? super K, ? super V> registration : cache.getListeners()
+ .values()) {
+ CacheEntryEventFilter<? super K, ? super V> filter = registration.getCacheEntryFilter();
+ Iterable<CacheEntryEvent<K, V>> iterable = filter == null ? events
+ : new RICacheEntryEventFilteringIterable<K, V>(events, filter);
+
+ CacheEntryListener<? super K, ? super V> listener = registration.getCacheEntryListener();
+ if (listener instanceof CacheEntryReadListener) {
+ ((CacheEntryReadListener) listener).onRead(iterable);
+ }
+ }
+ }
+
+}
View
80 jsr107impl/src/main/java/org/infinispan/jsr107/cache/InfinispanCacheLoaderAdapter.java
@@ -0,0 +1,80 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tag. All rights reserved.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+package org.infinispan.jsr107.cache;
+
+import java.util.Collections;
+import java.util.Set;
+
+import javax.cache.Cache.Entry;
+import javax.cache.CacheLoader;
+
+import org.infinispan.container.entries.ImmortalCacheEntry;
+import org.infinispan.container.entries.InternalCacheEntry;
+import org.infinispan.loaders.AbstractCacheLoader;
+import org.infinispan.loaders.CacheLoaderConfig;
+import org.infinispan.loaders.CacheLoaderException;
+
+public class InfinispanCacheLoaderAdapter<K, V> extends AbstractCacheLoader {
+
+ private final CacheLoader<K, V> delegate;
+
+ public InfinispanCacheLoaderAdapter(CacheLoader<K, V> delegate) {
+ super();
+ this.delegate = delegate;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public InternalCacheEntry load(Object key) throws CacheLoaderException {
+ Entry<K, V> e = delegate.load((K) key);
+ // TODO or whatever type of entry is more appropriate?
+ return new ImmortalCacheEntry(e.getKey(), e.getValue());
+ }
+
+ @Override
+ public Set<InternalCacheEntry> loadAll() throws CacheLoaderException {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public Set<InternalCacheEntry> load(int numEntries) throws CacheLoaderException {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public Set<Object> loadAllKeys(Set<Object> keysToExclude) throws CacheLoaderException {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public void start() throws CacheLoaderException {
+ // TODO
+ }
+
+ @Override
+ public void stop() throws CacheLoaderException {
+ // TODO
+ }
+
+ @Override
+ public Class<? extends CacheLoaderConfig> getConfigurationClass() {
+ return null;
+ }
+
+}
View
247 jsr107impl/src/main/java/org/infinispan/jsr107/cache/InfinispanCacheManager.java
@@ -0,0 +1,247 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tag. All rights reserved.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+package org.infinispan.jsr107.cache;
+
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.cache.Cache;
+import javax.cache.CacheException;
+import javax.cache.CacheManager;
+import javax.cache.Caching;
+import javax.cache.Configuration;
+import javax.cache.OptionalFeature;
+import javax.cache.Status;
+import javax.cache.transaction.IsolationLevel;
+import javax.cache.transaction.Mode;
+import javax.transaction.UserTransaction;
+
+import org.infinispan.configuration.parsing.ConfigurationBuilderHolder;
+import org.infinispan.configuration.parsing.ParserRegistry;
+import org.infinispan.manager.DefaultCacheManager;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.util.FileLookupFactory;
+
+/**
+ * InfinispanCacheManager is Infinispan's implementation of {@link javax.cache.CacheManager}.
+ *
+ * @author Vladimir Blagojevic
+ * @since 5.3
+ */
+public class InfinispanCacheManager implements CacheManager {
+ private final HashMap<String, Cache<?, ?>> caches = new HashMap<String, Cache<?, ?>>();
+ private final String name;
+ private final ClassLoader classLoader;
+ private EmbeddedCacheManager cmDelegate;
+ private volatile Status status = Status.UNINITIALISED;
+
+ /**
+ * Create a new InfinispanCacheManager given a cache name and a {@link ClassLoader}. Cache name
+ * might refer to a file on classpath containing Infinispan configuration file.
+ *
+ * @param name
+ * @param classLoader
+ */
+ public InfinispanCacheManager(String name, ClassLoader classLoader) {
+ if (classLoader == null) {
+ throw new IllegalArgumentException("Classloader cannot be null");
+ }
+ if (name == null || name.length() == 0) {
+ throw new IllegalArgumentException("Invalid CacheManager name " + name);
+ }
+
+ this.name = name;
+ this.classLoader = classLoader;
+
+ ConfigurationBuilderHolder cbh = null;
+ try {
+ InputStream configurationStream = FileLookupFactory.newInstance().lookupFileStrict(name,
+ classLoader);
+ cbh = new ParserRegistry(classLoader).parse(configurationStream);
+ } catch (FileNotFoundException e) {
+ // no such file, lets use default CBH
+ cbh = new ConfigurationBuilderHolder(classLoader);
+ cbh.getGlobalConfigurationBuilder().transport().defaultTransport().build();
+ // TODO investigate this below as TCK fails if we disable duplicate domains
+ // org.jsr107.tck.CacheManagerFactoryTest fails
+ cbh.getGlobalConfigurationBuilder().globalJmxStatistics().allowDuplicateDomains(true);
+ }
+ cmDelegate = new DefaultCacheManager(cbh, true);
+
+ // TODO get predefined caches and register them
+ // TODO galderz find a better way to do this as spec allows predefined caches to be
+ // loaded (config file), instantiated and registered with CacheManager
+ Set<String> cacheNames = cmDelegate.getCacheNames();
+ for (String cacheName : cacheNames) {
+ caches.put(cacheName, new InfinispanCache<Object, Object>(cmDelegate.getCache(cacheName),
+ this, classLoader, null));
+ }
+
+ status = Status.STARTED;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public Status getStatus() {
+ return status;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <K, V> Cache<K, V> configureCache(String cacheName, Configuration<K, V> c) {
+ checkStartedStatus();
+
+ // spec required
+ if (cacheName == null || cacheName.length() == 0) {
+ throw new NullPointerException("cacheName specified is invalid " + cacheName);
+ }
+
+ // spec required
+ if (c == null) {
+ throw new NullPointerException("configuration specified is invalid " + c);
+ }
+
+ boolean noIsolationWithTx = c.getTransactionIsolationLevel() == IsolationLevel.NONE
+ && c.getTransactionMode() != Mode.NONE;
+ boolean isolationWithNoTx = c.getTransactionIsolationLevel() != IsolationLevel.NONE
+ && c.getTransactionMode() == Mode.NONE;
+
+ // spec required
+ if (noIsolationWithTx || isolationWithNoTx) {
+ throw new IllegalArgumentException("Incompatible IsolationLevel "
+ + c.getTransactionIsolationLevel() + " and tx mode " + c.getTransactionMode());
+ }
+
+ synchronized (caches) {
+ Cache<?, ?> cache = caches.get(cacheName);
+
+ if (cache == null) {
+ ConfigurationAdapter<K, V> adapter = new ConfigurationAdapter<K, V>(c, classLoader);
+ org.infinispan.configuration.cache.Configuration ic = adapter.build();
+ cmDelegate.defineConfiguration(cacheName, ic);
+ org.infinispan.Cache<K, V> delegateCache = cmDelegate.getCache(cacheName);
+ cache = new InfinispanCache<K, V>(delegateCache, this, classLoader, c);
+ cache.start();
+ caches.put(cache.getName(), cache);
+ } else {
+ // re-register attempt with different configuration
+ if (!cache.getConfiguration().equals(c)) {
+ throw new CacheException("Cache " + cacheName
+ + " already registered with configuration " + cache.getConfiguration()
+ + ", and can not be registered again with a new given configuration " + c);
+ }
+ }
+
+ return (Cache<K, V>) cache;
+ }
+ }
+
+ @Override
+ public <K, V> Cache<K, V> getCache(String cacheName) {
+ checkStartedStatus();
+ synchronized (caches) {
+ @SuppressWarnings("unchecked")
+ final Cache<K, V> cache = (Cache<K, V>) caches.get(cacheName);
+ return cache;
+ }
+ }
+
+ @Override
+ public Iterable<Cache<?, ?>> getCaches() {
+ synchronized (caches) {
+ HashSet<Cache<?, ?>> set = new HashSet<Cache<?, ?>>();
+ for (Cache<?, ?> cache : caches.values()) {
+ set.add(cache);
+ }
+ return Collections.unmodifiableSet(set);
+ }
+ }
+
+ @Override
+ public boolean removeCache(String cacheName) {
+ checkStartedStatus();
+ if (cacheName == null) {
+ throw new NullPointerException();
+ }
+ Cache<?, ?> oldCache;
+ synchronized (caches) {
+ oldCache = caches.remove(cacheName);
+ }
+ if (oldCache != null) {
+ oldCache.stop();
+ }
+
+ return oldCache != null;
+ }
+
+ @Override
+ public UserTransaction getUserTransaction() {
+ // TODO
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isSupported(OptionalFeature optionalFeature) {
+ return Caching.isSupported(optionalFeature);
+ }
+
+ @Override
+ public void shutdown() {
+ checkStartedStatus();
+ ArrayList<Cache<?, ?>> cacheList;
+ synchronized (caches) {
+ cacheList = new ArrayList<Cache<?, ?>>(caches.values());
+ caches.clear();
+ }
+ for (Cache<?, ?> cache : cacheList) {
+ try {
+ cache.stop();
+ } catch (Exception e) {
+ // log?
+ }
+ }
+ cmDelegate.stop();
+ status = Status.STOPPED;
+ }
+
+ @Override
+ public <T> T unwrap(java.lang.Class<T> cls) {
+ if (cls.isAssignableFrom(this.getClass())) {
+ return cls.cast(this);
+ }
+
+ throw new IllegalArgumentException("Unwapping to " + cls
+ + " is not a supported by this implementation");
+ }
+
+ private void checkStartedStatus() {
+ if (status != Status.STARTED) {
+ throw new IllegalStateException();
+ }
+ }
+}
View
141 jsr107impl/src/main/java/org/infinispan/jsr107/cache/InfinispanCacheManagerFactory.java
@@ -0,0 +1,141 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tag. All rights reserved.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+package org.infinispan.jsr107.cache;
+
+import java.util.HashMap;
+import java.util.IdentityHashMap;
+import java.util.Map;
+
+import javax.cache.CacheManager;
+import javax.cache.CacheManagerFactory;
+import javax.cache.CachingShutdownException;
+
+public class InfinispanCacheManagerFactory implements CacheManagerFactory {
+
+ private static final InfinispanCacheManagerFactory INSTANCE = new InfinispanCacheManagerFactory();
+
+ private final Map<ClassLoader, Map<String, CacheManager>> cacheManagers = new HashMap<ClassLoader, Map<String, CacheManager>>();
+
+ private InfinispanCacheManagerFactory() {
+ }
+
+ @Override
+ public CacheManager getCacheManager(String name) {
+ return getCacheManager(getDefaultClassLoader(), name);
+ }
+
+ @Override
+ public CacheManager getCacheManager(ClassLoader classLoader, String name) {
+ if (classLoader == null) {
+ throw new NullPointerException("Invalid classloader specified " + classLoader);
+ }
+ if (name == null) {
+ throw new NullPointerException("Invalid cache name specified " + name);
+ }
+ synchronized (cacheManagers) {
+ Map<String, CacheManager> map = cacheManagers.get(classLoader);
+ if (map == null) {
+ map = new HashMap<String, CacheManager>();
+ cacheManagers.put(classLoader, map);
+ }
+ CacheManager cacheManager = map.get(name);
+ if (cacheManager == null) {
+ cacheManager = createCacheManager(classLoader, name);
+ map.put(name, cacheManager);
+ }
+ return cacheManager;
+ }
+ }
+
+ @Override
+ public void close() throws CachingShutdownException {
+ synchronized (cacheManagers) {
+ IdentityHashMap<CacheManager, Exception> failures = new IdentityHashMap<CacheManager, Exception>();
+ for (Map<String, CacheManager> cacheManagerMap : cacheManagers.values()) {
+ try {
+ shutdown(cacheManagerMap);
+ } catch (CachingShutdownException e) {
+ failures.putAll(e.getFailures());
+ }
+ }
+ cacheManagers.clear();
+ if (!failures.isEmpty()) {
+ throw new CachingShutdownException(failures);
+ }
+ }
+ }
+
+ @Override
+ public boolean close(ClassLoader classLoader) throws CachingShutdownException {
+ Map<String, CacheManager> cacheManagerMap;
+ synchronized (cacheManagers) {
+ cacheManagerMap = cacheManagers.remove(classLoader);
+ }
+ if (cacheManagerMap == null) {
+ return false;
+ } else {
+ shutdown(cacheManagerMap);
+ return true;
+ }
+ }
+
+ @Override
+ public boolean close(ClassLoader classLoader, String name) throws CachingShutdownException {
+ CacheManager cacheManager;
+ synchronized (cacheManagers) {
+ Map<String, CacheManager> cacheManagerMap = cacheManagers.get(classLoader);
+ cacheManager = cacheManagerMap.remove(name);
+ if (cacheManagerMap.isEmpty()) {
+ cacheManagers.remove(classLoader);
+ }
+ }
+ if (cacheManager == null) {
+ return false;
+ } else {
+ cacheManager.shutdown();
+ return true;
+ }
+ }
+
+ public static InfinispanCacheManagerFactory getInstance() {
+ return INSTANCE;
+ }
+
+ private void shutdown(Map<String, CacheManager> cacheManagerMap) throws CachingShutdownException {
+ IdentityHashMap<CacheManager, Exception> failures = new IdentityHashMap<CacheManager, Exception>();
+ for (CacheManager cacheManager : cacheManagerMap.values()) {
+ try {
+ cacheManager.shutdown();
+ } catch (Exception e) {
+ failures.put(cacheManager, e);
+ }
+ }
+ if (!failures.isEmpty()) {
+ throw new CachingShutdownException(failures);
+ }
+ }
+
+ private CacheManager createCacheManager(ClassLoader classLoader, String name) {
+ return new InfinispanCacheManager(name, classLoader);
+ }
+
+ private ClassLoader getDefaultClassLoader() {
+ return Thread.currentThread().getContextClassLoader();
+ }
+}
View
104 jsr107impl/src/main/java/org/infinispan/jsr107/cache/InfinispanCacheWriterAdapter.java
@@ -0,0 +1,104 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tag. All rights reserved.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+package org.infinispan.jsr107.cache;
+
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Collections;
+import java.util.Set;
+
+import javax.cache.CacheWriter;
+
+import org.infinispan.container.entries.InternalCacheEntry;
+import org.infinispan.loaders.AbstractCacheStore;
+import org.infinispan.loaders.CacheLoaderConfig;
+import org.infinispan.loaders.CacheLoaderException;
+
+public class InfinispanCacheWriterAdapter<K, V> extends AbstractCacheStore {
+
+ private final CacheWriter<K, V> delegate;
+
+ public InfinispanCacheWriterAdapter(CacheWriter<K, V> delegate) {
+ super();
+ this.delegate = delegate;
+ }
+
+ @Override
+ public void store(InternalCacheEntry entry) throws CacheLoaderException {
+ delegate.write(new InfinispanCacheEntry(entry));
+ }
+
+ @Override
+ public void fromStream(ObjectInput inputStream) throws CacheLoaderException {
+ // TODO
+ }
+
+ @Override
+ public void toStream(ObjectOutput outputStream) throws CacheLoaderException {
+ // TODO
+ }
+
+ @Override
+ public void clear() throws CacheLoaderException {
+ // TODO
+ }
+
+ @Override
+ public boolean remove(Object key) throws CacheLoaderException {
+ // TODO
+ delegate.delete(key);
+ return false;
+ }
+
+ @Override
+ public InternalCacheEntry load(Object key) throws CacheLoaderException {
+ //TODO
+ return null;
+
+ }
+
+ @Override
+ public Set<InternalCacheEntry> loadAll() throws CacheLoaderException {
+ // TODO
+ return Collections.emptySet();
+ }
+
+ @Override
+ public Set<InternalCacheEntry> load(int numEntries) throws CacheLoaderException {
+ // TODO
+ return Collections.emptySet();
+ }
+
+ @Override
+ public Set<Object> loadAllKeys(Set<Object> keysToExclude) throws CacheLoaderException {
+ // TODO
+ return Collections.emptySet();
+ }
+
+ @Override
+ public Class<? extends CacheLoaderConfig> getConfigurationClass() {
+ // TODO
+ return null;
+ }
+
+ @Override
+ protected void purgeInternal() throws CacheLoaderException {
+ // TODO
+ }
+}
View
54 jsr107impl/src/main/java/org/infinispan/jsr107/cache/InfinispanCachingProvider.java
@@ -0,0 +1,54 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tag. All rights reserved.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+package org.infinispan.jsr107.cache;
+
+import javax.cache.CacheManagerFactory;
+import javax.cache.OptionalFeature;
+import javax.cache.spi.CachingProvider;
+
+/**
+ * InfinispanCachingProvider is Infinispan's SPI hook up to {@link javax.cache.spi.CachingProvider}.
+ *
+ * @author Vladimir Blagojevic
+ * @since 5.3
+ */
+public class InfinispanCachingProvider implements CachingProvider {
+
+ public InfinispanCachingProvider() {
+ // required no-op constructor by the spec
+ }
+
+ @Override
+ public CacheManagerFactory getCacheManagerFactory() {
+ return InfinispanCacheManagerFactory.getInstance();
+ }
+
+ @Override
+ public boolean isSupported(OptionalFeature optionalFeature) {
+ switch (optionalFeature) {
+ case TRANSACTIONS:
+ return true;
+ case STORE_BY_REFERENCE:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+}
View
54 jsr107impl/src/main/java/org/infinispan/jsr107/cache/InfinispanStatusConverter.java
@@ -0,0 +1,54 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tag. All rights reserved.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+package org.infinispan.jsr107.cache;
+
+import javax.cache.Status;
+
+import org.infinispan.lifecycle.ComponentStatus;
+
+/**
+ * InfinispanStatusConverter converts Infinispan cache status to {@link javax.cache.Status}.
+ *
+ * @author Vladimir Blagojevic
+ * @since 5.3
+ */
+public class InfinispanStatusConverter {
+
+ public static Status convert(ComponentStatus status) {
+ Status convertedStatus;
+ switch (status) {
+ case FAILED:
+ case TERMINATED:
+ case STOPPING:
+ convertedStatus = Status.STOPPED;
+ break;
+ case INITIALIZING:
+ case INSTANTIATED:
+ convertedStatus = Status.UNINITIALISED;
+ break;
+ case RUNNING:
+ convertedStatus = Status.STARTED;
+ break;
+ default:
+ convertedStatus = Status.UNINITIALISED;
+ break;
+ }
+ return convertedStatus;
+ }
+}
View
118 jsr107impl/src/main/java/org/infinispan/jsr107/cache/RICacheEntryEvent.java
@@ -0,0 +1,118 @@
+/**
+ * Copyright 2011 Terracotta, Inc.
+ * Copyright 2011 Oracle America Incorporated
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.infinispan.jsr107.cache;
+
+import javax.cache.Cache;
+import javax.cache.event.CacheEntryEvent;
+
+/**
+ * The reference implementation of the {@link CacheEntryEvent}.
+ *
+ * @param <K> the type of keys maintained by this cache
+ * @param <V> the type of cached values
+ * @author Greg Luck
+ * @since 1.0
+ */
+public class RICacheEntryEvent<K, V> extends CacheEntryEvent<K, V> {
+
+ /** The serialVersionUID */
+ private static final long serialVersionUID = 6515030413069752679L;
+
+ private K key;
+ private V value;
+ private V oldValue;
+ private boolean oldValueAvailable;
+
+ /**
+ * Constructs a cache entry event from a given cache as source
+ * (without an old value)
+ *
+ * @param source the cache that originated the event
+ * @param key the key
+ * @param value the value
+ */
+ public RICacheEntryEvent(Cache<K, V> source, K key, V value) {
+ super(source);
+ this.key = key;
+ this.value = value;
+ this.oldValue = null;
+ this.oldValueAvailable = false;
+ }
+
+ /**
+ * Constructs a cache entry event from a given cache as source
+ * (with an old value)
+ *
+ * @param source the cache that originated the event
+ * @param key the key
+ * @param value the value
+ * @param oldValue the oldValue
+ */
+ public RICacheEntryEvent(Cache<K, V> source, K key, V value, V oldValue) {
+ super(source);
+ this.key = key;
+ this.value = value;
+ this.oldValue = oldValue;
+ this.oldValueAvailable = true;
+ }
+
+ /**
+ * Returns the key of the cache entry with the event
+ *
+ * @return the key
+ */
+ @Override
+ public K getKey() {
+ return key;
+ }
+
+ /**
+ * Returns the value of the cache entry with the event
+ *
+ * @return the value
+ */
+ @Override
+ public V getValue() {
+ return value;
+ }
+
+ /**
+ * Returns the value of the cache entry with the event
+ *
+ * @return the value
+ * @throws UnsupportedOperationException if the old value is not available
+ */
+ @Override
+ public V getOldValue() throws UnsupportedOperationException {
+ if (isOldValueAvailable()) {
+ return oldValue;
+ } else {
+ throw new UnsupportedOperationException("Old value is not available for key");
+ }
+ }
+
+ /**
+ * Whether the old value is available
+ *
+ * @return true if the old value is populated
+ */
+ @Override
+ public boolean isOldValueAvailable() {
+ return oldValueAvailable;
+ }
+}
View
64 jsr107impl/src/main/java/org/infinispan/jsr107/cache/RICacheEntryEventFilteringIterable.java
@@ -0,0 +1,64 @@
+/**
+ * Copyright 2011 Terracotta, Inc.
+ * Copyright 2011 Oracle America Incorporated
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.infinispan.jsr107.cache;
+
+import java.util.Iterator;
+
+import javax.cache.event.CacheEntryEvent;
+import javax.cache.event.CacheEntryEventFilter;
+
+/**
+ * An adapter to provide {@link Iterable}s over Cache Entries, those of which
+ * are filtered using a {@link CacheEntryEventFilter}.
+ *
+ * @author Brian Oliver
+ *
+ * @param <K> the type of keys
+ * @param <V> the type of values
+ */
+public class RICacheEntryEventFilteringIterable<K, V> implements Iterable<CacheEntryEvent<K, V>> {
+
+ /**
+ * The underlying {@link Iterable} to filter.
+ */
+ private Iterable<CacheEntryEvent<K, V>> iterable;
+
+ /**
+ * The filter to apply to entries in the produced {@link Iterator}s.
+ */
+ private CacheEntryEventFilter<? super K, ? super V> filter;
+
+ /**
+ * Constructs an {@link RICacheEntryEventFilteringIterable}.
+ *
+ * @param iterable the underlying iterable to filter
+ * @param filter the filter to apply to entries in the iterable
+ */
+ public RICacheEntryEventFilteringIterable(Iterable<CacheEntryEvent<K, V>> iterable,
+ CacheEntryEventFilter<? super K, ? super V> filter) {
+ this.iterable = iterable;
+ this.filter = filter;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Iterator<CacheEntryEvent<K, V>> iterator() {
+ return new RICacheEntryEventFilteringIterator<K, V>(iterable.iterator(), filter);
+ }
+}
View
114 jsr107impl/src/main/java/org/infinispan/jsr107/cache/RICacheEntryEventFilteringIterator.java
@@ -0,0 +1,114 @@
+/**
+ * Copyright 2011 Terracotta, Inc.
+ * Copyright 2011 Oracle America Incorporated
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.infinispan.jsr107.cache;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import javax.cache.event.CacheEntryEvent;
+import javax.cache.event.CacheEntryEventFilter;
+
+/**
+ * A adapter to {@link Iterator}s to allow filtering of {@link CacheEntryEvent}s
+ *
+ * @author Brian Oliver
+ *
+ * @param <K> the type of keys
+ * @param <V> the type of value
+ */
+public class RICacheEntryEventFilteringIterator<K, V> implements Iterator<CacheEntryEvent<K, V>> {
+
+ /**
+ * The underlying iterator to filter.
+ */
+ private Iterator<CacheEntryEvent<K, V>> iterator;
+
+ /**
+ * The filter to apply to Cache Entry Events in the {@link Iterator}.
+ */
+ private CacheEntryEventFilter<? super K, ? super V> filter;
+
+ /**
+ * The next available Cache Entry Event that satisfies the filter.
+ * (when null we must seek to find the next event)
+ */
+ private CacheEntryEvent<K, V> nextEntry;
+
+ /**
+ * Constructs an {@link RICacheEntryEventFilteringIterator}.
+ *
+ * @param iterator the underlying iterator to filter
+ * @param filter the filter to apply to entries in the iterator
+ */
+ public RICacheEntryEventFilteringIterator(Iterator<CacheEntryEvent<K, V>> iterator,
+ CacheEntryEventFilter<? super K, ? super V> filter) {
+ this.iterator = iterator;
+ this.filter = filter;
+ this.nextEntry = null;
+ }
+
+ /**
+ * Fetches the next available, entry that satisfies the filter from
+ * the underlying iterator
+ */
+ private void fetch() {
+ while (nextEntry == null && iterator.hasNext()) {
+ CacheEntryEvent<K, V> entry = iterator.next();
+
+ if (filter.evaluate(entry)) {
+ nextEntry = entry;
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean hasNext() {
+ if (nextEntry == null) {
+ fetch();
+ }
+ return nextEntry != null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public CacheEntryEvent<K, V> next() {
+ if (hasNext()) {
+ CacheEntryEvent<K, V> entry = nextEntry;
+
+ //reset nextEntry to force fetching the next available entry
+ nextEntry = null;
+
+ return entry;
+ } else {
+ throw new NoSuchElementException();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void remove() {
+ iterator.remove();
+ nextEntry = null;
+ }
+}
View
141 jsr107impl/src/main/java/org/infinispan/jsr107/cache/RICacheEntryListenerRegistration.java
@@ -0,0 +1,141 @@
+/**
+ * Copyright 2011 Terracotta, Inc.
+ * Copyright 2011 Oracle America Incorporated
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.infinispan.jsr107.cache;
+
+import javax.cache.event.CacheEntryEventFilter;
+import javax.cache.event.CacheEntryListener;
+import javax.cache.event.CacheEntryListenerRegistration;
+
+/**
+ * The reference implementation of the {@link CacheEntryListenerRegistration}.
+ *
+ * @author Brian Oliver
+ *
+ * @param <K> the type of keys
+ * @param <V> the type of values
+ */
+public class RICacheEntryListenerRegistration<K, V> implements CacheEntryListenerRegistration<K, V> {
+
+ private CacheEntryListener<? super K, ? super V> listener;
+ private CacheEntryEventFilter<? super K, ? super V> filter;
+ private boolean isOldValueRequired;
+ private boolean isSynchronous;
+
+ /**
+ * Constructs an {@link RICacheEntryListenerRegistration}.
+ *
+ * @param listener the {@link CacheEntryListener}
+ * @param filter the optional {@link CacheEntryEventFilter}
+ * @param isOldValueRequired if the old value is required for events with this listener
+ * @param isSynchronous if the listener should block the thread causing the event
+ */
+ public RICacheEntryListenerRegistration(CacheEntryListener<? super K, ? super V> listener,
+ CacheEntryEventFilter<? super K, ? super V> filter,
+ boolean isOldValueRequired,
+ boolean isSynchronous) {
+ this.listener = listener;
+ this.filter = filter;
+ this.isOldValueRequired = isOldValueRequired;
+ this.isSynchronous = isSynchronous;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public CacheEntryEventFilter<? super K, ? super V> getCacheEntryFilter() {
+ return filter;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public CacheEntryListener<? super K, ? super V> getCacheEntryListener() {
+ return listener;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isOldValueRequired() {
+ return isOldValueRequired;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isSynchronous() {
+ return isSynchronous;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((filter == null) ? 0 : filter.hashCode());
+ result = prime * result + (isOldValueRequired ? 1231 : 1237);
+ result = prime * result + (isSynchronous ? 1231 : 1237);
+ result = prime * result
+ + ((listener == null) ? 0 : listener.hashCode());
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (object == null) {
+ return false;
+ }
+ if (!(object instanceof RICacheEntryListenerRegistration)) {
+ return false;
+ }
+ RICacheEntryListenerRegistration<?, ?> other = (RICacheEntryListenerRegistration<?, ?>) object;
+ if (filter == null) {
+ if (other.filter != null) {
+ return false;
+ }
+ } else if (!filter.equals(other.filter)) {
+ return false;
+ }
+ if (isOldValueRequired != other.isOldValueRequired) {
+ return false;
+ }
+ if (isSynchronous != other.isSynchronous) {
+ return false;
+ }
+ if (listener == null) {
+ if (other.listener != null) {
+ return false;
+ }
+ } else if (!listener.equals(other.listener)) {
+ return false;
+ }
+ return true;
+ }
+}
View
300 jsr107impl/src/main/java/org/infinispan/jsr107/cache/RICacheStatistics.java
@@ -0,0 +1,300 @@
+/**
+ * Copyright 2011 Terracotta, Inc.
+ * Copyright 2011 Oracle America Incorporated
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.infinispan.jsr107.cache;
+
+import javax.cache.Cache;
+import javax.cache.CacheStatistics;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.concurrent.atomic.AtomicLong;
+
+
+/**
+ * The reference implementation of {@link CacheStatistics}.
+ */
+public class RICacheStatistics implements CacheStatistics, Serializable {
+
+ private static final long serialVersionUID = -5589437411679003894L;
+ private static final long NANOSECONDS_IN_A_MILLISECOND = 1000000L;
+
+
+ private transient Cache<?, ?> cache;
+
+ private final AtomicLong cacheRemovals = new AtomicLong();
+ private final AtomicLong cacheExpiries = new AtomicLong();
+ private final AtomicLong cachePuts = new AtomicLong();
+ private final AtomicLong cacheHits = new AtomicLong();
+ private final AtomicLong cacheMisses = new AtomicLong();
+ private final AtomicLong cacheEvictions = new AtomicLong();
+ private final AtomicLong cachePutTimeTakenNanos = new AtomicLong();
+ private final AtomicLong cacheGetTimeTakenNanos = new AtomicLong();
+ private final AtomicLong cacheRemoveTimeTakenNanos = new AtomicLong();
+
+ private Date lastCollectionStartDate = new Date();
+
+ /**
+ * Constructs a cache statistics object
+ *
+ * @param cache the associated cache
+ */
+ public RICacheStatistics(Cache<?, ?> cache) {
+ this.cache = cache;
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * Statistics will also automatically be cleared if internal counters overflow.
+ */
+ @Override
+ public void clear() {
+ cachePuts.set(0);
+ cacheMisses.set(0);
+ cacheRemovals.set(0);
+ cacheExpiries.set(0);
+ cacheHits.set(0);
+ cacheEvictions.set(0);
+ cacheGetTimeTakenNanos.set(0);
+ cachePutTimeTakenNanos.set(0);
+ cacheRemoveTimeTakenNanos.set(0);
+ lastCollectionStartDate = new Date();
+ }
+
+ /**
+ * The date from which statistics have been accumulated. Because statistics can be cleared, this is not necessarily
+ * since the cache was started.
+ *
+ * @return the date statistics started being accumulated
+ */
+ @Override
+ public Date getStartAccumulationDate() {
+ return lastCollectionStartDate;
+ }
+
+ /**
+ * @return the entry count
+ */
+ public long getEntryCount() {
+ return ((InfinispanCache<?, ?>) cache).size();
+ }
+
+ /**
+ * @return the number of hits
+ */
+ @Override
+ public long getCacheHits() {
+ return cacheHits.longValue();
+ }
+
+ /**
+ * Returns cache hits as a percentage of total gets.
+ *
+ * @return the percentage of successful hits, as a decimal
+ */
+ @Override
+ public float getCacheHitPercentage() {
+ return getCacheHits() / getCacheGets();
+ }
+
+ /**
+ * @return the number of misses
+ */
+ @Override
+ public long getCacheMisses() {
+ return cacheMisses.longValue();
+ }
+
+ /**
+ * Returns cache misses as a percentage of total gets.
+ *
+ * @return the percentage of accesses that failed to find anything
+ */
+ @Override
+ public float getCacheMissPercentage() {
+ return getCacheMisses() / getCacheGets();
+ }
+
+ /**
+ * The total number of requests to the cache. This will be equal to the sum of the hits and misses.
+ * <p/>
+ * A "get" is an operation that returns the current or previous value.
+ *
+ * @return the number of hits
+ */
+ @Override
+ public long getCacheGets() {
+ return getCacheHits() + getCacheMisses();
+ }
+
+ /**
+ * The total number of puts to the cache.
+ * <p/>
+ * A put is counted even if it is immediately evicted. A replace includes a put and remove.
+ *
+ * @return the number of hits
+ */
+ @Override
+ public long getCachePuts() {
+ return cachePuts.longValue();
+ }
+
+ /**
+ * The total number of removals from the cache. This does not include evictions, where the cache itself
+ * initiates the removal to make space.
+ * <p/>
+ * A replace invcludes a put and remove.
+ *
+ * @return the number of hits
+ */
+ @Override
+ public long getCacheRemovals() {
+ return cacheRemovals.longValue();
+ }
+
+ /**
+ * @return the number of evictions from the cache
+ */
+ @Override
+ public long getCacheEvictions() {
+ return cacheEvictions.longValue();
+ }
+
+ /**
+ * The mean time to execute gets.
+ *
+ * @return the time in milliseconds
+ */
+ @Override
+ public float getAverageGetMillis() {
+ return (cacheGetTimeTakenNanos.longValue() / getCacheGets()) / NANOSECONDS_IN_A_MILLISECOND;
+ }
+
+ /**
+ * The mean time to execute puts.
+ *
+ * @return the time in milliseconds
+ */
+ @Override
+ public float getAveragePutMillis() {
+ return (cachePutTimeTakenNanos.longValue() / getCacheGets()) / NANOSECONDS_IN_A_MILLISECOND;
+ }
+
+ /**
+ * The mean time to execute removes.
+ *
+ * @return the time in milliseconds
+ */
+ @Override
+ public float getAverageRemoveMillis() {
+ return (cacheRemoveTimeTakenNanos.longValue() / getCacheGets()) / NANOSECONDS_IN_A_MILLISECOND;
+ }
+
+ //package local incrementers
+
+ /**
+ * Increases the counter by the number specified.
+ * @param number the number to increase the counter by
+ */
+ void increaseCacheRemovals(long number) {
+ cacheRemovals.getAndAdd(number);
+ }
+
+ /**
+ * Increases the counter by the number specified.
+ * @param number the number to increase the counter by
+ */
+ void increaseCacheExpiries(long number) {
+ cacheExpiries.getAndAdd(number);
+ }
+
+ /**
+ * Increases the counter by the number specified.
+ * @param number the number to increase the counter by
+ */
+ void increaseCachePuts(long number) {
+ cachePuts.getAndAdd(number);
+ }
+
+ /**
+ * Increases the counter by the number specified.
+ * @param number the number to increase the counter by
+ */
+ void increaseCacheHits(long number) {
+ cacheHits.getAndAdd(number);
+ }
+
+ /**
+ * Increases the counter by the number specified.
+ * @param number the number to increase the counter by
+ */
+ void increaseCacheMisses(long number) {
+ cacheMisses.getAndAdd(number);
+ }
+
+ /**
+ * Increases the counter by the number specified.
+ * @param number the number to increase the counter by
+ */
+ void increaseCacheEvictions(long number) {
+ cacheEvictions.getAndAdd(number);
+ }
+
+ /**
+ * Increments the get time accumulator
+ * @param duration the time taken in nanoseconds
+ */
+ public void addGetTimeNano(long duration) {
+ if (cacheGetTimeTakenNanos.get() <= Long.MAX_VALUE - duration) {
+ cacheGetTimeTakenNanos.addAndGet(duration);
+ } else {
+ //counter full. Just reset.
+ clear();
+ cacheGetTimeTakenNanos.set(duration);
+ }
+ }
+
+
+ /**
+ * Increments the put time accumulator
+ * @param duration the time taken in nanoseconds
+ */
+ public void addPutTimeNano(long duration) {
+ if (cachePutTimeTakenNanos.get() <= Long.MAX_VALUE - duration) {
+ cachePutTimeTakenNanos.addAndGet(duration);
+ } else {
+ //counter full. Just reset.
+ clear();
+ cachePutTimeTakenNanos.set(duration);
+ }
+ }
+
+ /**
+ * Increments the remove time accumulator
+ * @param duration the time taken in nanoseconds
+ */
+ public void addRemoveTimeNano(long duration) {
+ if (cacheRemoveTimeTakenNanos.get() <= Long.MAX_VALUE - duration) {
+ cacheRemoveTimeTakenNanos.addAndGet(duration);
+ } else {
+ //counter full. Just reset.
+ clear();
+ cacheRemoveTimeTakenNanos.set(duration);
+ }
+ }
+
+}
View
1 jsr107impl/src/main/resources/META-INF/services/javax.cache.spi.CachingProvider
@@ -0,0 +1 @@
+org.infinispan.jsr107.cache.InfinispanCachingProvider

0 comments on commit b0636a7

Please sign in to comment.
Something went wrong with that request. Please try again.