commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rmannibu...@apache.org
Subject svn commit: r1593138 [1/2] - in /commons/proper/jcs/trunk: ./ commons-jcs-jcache-extras/ commons-jcs-jcache-extras/src/ commons-jcs-jcache-extras/src/main/ commons-jcs-jcache-extras/src/main/java/ commons-jcs-jcache-extras/src/main/java/org/ commons-jc...
Date Wed, 07 May 2014 21:23:18 GMT
Author: rmannibucau
Date: Wed May  7 21:23:17 2014
New Revision: 1593138

URL: http://svn.apache.org/r1593138
Log:
cdi extra module + better eviction

Added:
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/pom.xml
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/cdi/
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/cdi/AnyLiteral.java
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/cdi/CacheManagerBean.java
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/cdi/CacheProviderBean.java
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/cdi/DefaultLiteral.java
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/cdi/ExtraJCacheExtension.java
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/resources/
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/resources/META-INF/
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/resources/META-INF/services/
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/test/
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/test/java/
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/test/java/org/
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/test/java/org/apache/
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/test/java/org/apache/commons/
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/test/java/org/apache/commons/jcs/
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/test/java/org/apache/commons/jcs/jcache/
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/test/java/org/apache/commons/jcs/jcache/extras/
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/test/java/org/apache/commons/jcs/jcache/extras/cdi/
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/test/java/org/apache/commons/jcs/jcache/extras/cdi/ExtraJCacheExtensionTest.java
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/test/resources/
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/test/resources/META-INF/
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/test/resources/META-INF/beans.xml
    commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/JCSKey.java
    commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/proxy/ClassLoaderAwareCache.java
      - copied, changed from r1593134, commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/proxy/ClassLoaderAwareHandler.java
    commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/serialization/
    commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/serialization/Serializations.java
    commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/thread/
    commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/thread/DaemonThreadFactory.java
Removed:
    commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/proxy/ClassLoaderAwareHandler.java
    commons/proper/jcs/trunk/commons-jcs-jcache/src/test/java/org/apache/commons/jcs/jcache/Speed.java
Modified:
    commons/proper/jcs/trunk/commons-jcs-jcache/pom.xml
    commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/JCSCache.java
    commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/JCSCachingManager.java
    commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/JCSElement.java
    commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/Times.java
    commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CDIJCacheHelper.java
    commons/proper/jcs/trunk/commons-jcs-tck-tests/pom.xml
    commons/proper/jcs/trunk/commons-jcs-tck-tests/run-tck.sh
    commons/proper/jcs/trunk/pom.xml

Added: commons/proper/jcs/trunk/commons-jcs-jcache-extras/pom.xml
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-jcache-extras/pom.xml?rev=1593138&view=auto
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-jcache-extras/pom.xml (added)
+++ commons/proper/jcs/trunk/commons-jcs-jcache-extras/pom.xml Wed May  7 21:23:17 2014
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.
+
+-->
+<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">
+  <parent>
+    <artifactId>commons-jcs</artifactId>
+    <groupId>org.apache.commons</groupId>
+    <version>2.0-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+
+  <artifactId>commons-jcs-jcache-extras</artifactId>
+  <name>Apache Commons JCS :: JCache Extras</name>
+
+  <dependencies>
+    <dependency>
+      <groupId>javax.cache</groupId>
+      <artifactId>cache-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.geronimo.specs</groupId>
+      <artifactId>geronimo-atinject_1.0_spec</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.geronimo.specs</groupId>
+      <artifactId>geronimo-jcdi_1.0_spec</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.geronimo.specs</groupId>
+      <artifactId>geronimo-interceptor_1.1_spec</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.openwebbeans</groupId>
+      <artifactId>openwebbeans-impl</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-jcs-jcache</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>

Added: commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/cdi/AnyLiteral.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/cdi/AnyLiteral.java?rev=1593138&view=auto
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/cdi/AnyLiteral.java (added)
+++ commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/cdi/AnyLiteral.java Wed May  7 21:23:17 2014
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.commons.jcs.jcache.extras.cdi;
+
+import javax.enterprise.inject.Any;
+import javax.enterprise.util.AnnotationLiteral;
+
+public class AnyLiteral extends AnnotationLiteral<Any> implements Any
+{
+    public static final AnyLiteral INSTANCE = new AnyLiteral();
+
+    @Override
+    public String toString()
+    {
+        return "@javax.enterprise.inject.Any()";
+    }
+}

Added: commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/cdi/CacheManagerBean.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/cdi/CacheManagerBean.java?rev=1593138&view=auto
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/cdi/CacheManagerBean.java (added)
+++ commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/cdi/CacheManagerBean.java Wed May  7 21:23:17 2014
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.commons.jcs.jcache.extras.cdi;
+
+import javax.cache.CacheManager;
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.enterprise.inject.spi.PassivationCapable;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.HashSet;
+import java.util.Set;
+
+import static java.util.Collections.emptySet;
+
+public class CacheManagerBean implements Bean<CacheManager>, PassivationCapable
+{
+    private final Set<Type> types;
+    private final Set<Annotation> qualifiers;
+    private final CacheManager manager;
+    private final String id;
+
+    public CacheManagerBean(final CacheManager cacheManager)
+    {
+        manager = cacheManager;
+        id = getClass().getName() + "-" + hashCode();
+
+        types = new HashSet<Type>();
+        types.add(CacheManager.class);
+        types.add(Object.class);
+
+        qualifiers = new HashSet<Annotation>();
+        qualifiers.add(DefaultLiteral.INSTANCE);
+        qualifiers.add(AnyLiteral.INSTANCE);
+    }
+
+    @Override
+    public Set<Type> getTypes()
+    {
+        return types;
+    }
+
+    @Override
+    public Set<Annotation> getQualifiers()
+    {
+        return qualifiers;
+    }
+
+    @Override
+    public Class<? extends Annotation> getScope()
+    {
+        return ApplicationScoped.class;
+    }
+
+    @Override
+    public String getName()
+    {
+        return null;
+    }
+
+    @Override
+    public boolean isNullable()
+    {
+        return false;
+    }
+
+    @Override
+    public Set<InjectionPoint> getInjectionPoints()
+    {
+        return emptySet();
+    }
+
+    @Override
+    public Class<?> getBeanClass()
+    {
+        return CacheManager.class;
+    }
+
+    @Override
+    public Set<Class<? extends Annotation>> getStereotypes()
+    {
+        return emptySet();
+    }
+
+    @Override
+    public boolean isAlternative()
+    {
+        return false;
+    }
+
+    @Override
+    public CacheManager create(CreationalContext<CacheManager> cacheManagerCreationalContext)
+    {
+        return manager;
+    }
+
+    @Override
+    public void destroy(CacheManager cacheManager, CreationalContext<CacheManager> cacheManagerCreationalContext)
+    {
+        manager.close();
+    }
+
+    @Override
+    public String getId()
+    {
+        return id;
+    }
+}

Added: commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/cdi/CacheProviderBean.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/cdi/CacheProviderBean.java?rev=1593138&view=auto
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/cdi/CacheProviderBean.java (added)
+++ commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/cdi/CacheProviderBean.java Wed May  7 21:23:17 2014
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.commons.jcs.jcache.extras.cdi;
+
+import javax.cache.spi.CachingProvider;
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.enterprise.inject.spi.PassivationCapable;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.HashSet;
+import java.util.Set;
+
+import static java.util.Collections.emptySet;
+
+public class CacheProviderBean implements Bean<CachingProvider>, PassivationCapable
+{
+    private final Set<Type> types;
+    private final Set<Annotation> qualifiers;
+    private final CachingProvider provider;
+    private final String id;
+
+    public CacheProviderBean(final CachingProvider cacheManager)
+    {
+        provider = cacheManager;
+        id = getClass().getName() + "-" + hashCode();
+
+        types = new HashSet<Type>();
+        types.add(CachingProvider.class);
+        types.add(Object.class);
+
+        qualifiers = new HashSet<Annotation>();
+        qualifiers.add(DefaultLiteral.INSTANCE);
+        qualifiers.add(AnyLiteral.INSTANCE);
+    }
+
+    @Override
+    public Set<Type> getTypes()
+    {
+        return types;
+    }
+
+    @Override
+    public Set<Annotation> getQualifiers()
+    {
+        return qualifiers;
+    }
+
+    @Override
+    public Class<? extends Annotation> getScope()
+    {
+        return ApplicationScoped.class;
+    }
+
+    @Override
+    public String getName()
+    {
+        return null;
+    }
+
+    @Override
+    public boolean isNullable()
+    {
+        return false;
+    }
+
+    @Override
+    public Set<InjectionPoint> getInjectionPoints()
+    {
+        return emptySet();
+    }
+
+    @Override
+    public Class<?> getBeanClass()
+    {
+        return CachingProvider.class;
+    }
+
+    @Override
+    public Set<Class<? extends Annotation>> getStereotypes()
+    {
+        return emptySet();
+    }
+
+    @Override
+    public boolean isAlternative()
+    {
+        return false;
+    }
+
+    @Override
+    public CachingProvider create(final CreationalContext<CachingProvider> cacheManagerCreationalContext)
+    {
+        return provider;
+    }
+
+    @Override
+    public void destroy(final CachingProvider cacheProvider, final CreationalContext<CachingProvider> cacheManagerCreationalContext)
+    {
+        provider.close();
+    }
+
+    @Override
+    public String getId()
+    {
+        return id;
+    }
+}

Added: commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/cdi/DefaultLiteral.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/cdi/DefaultLiteral.java?rev=1593138&view=auto
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/cdi/DefaultLiteral.java (added)
+++ commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/cdi/DefaultLiteral.java Wed May  7 21:23:17 2014
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.commons.jcs.jcache.extras.cdi;
+
+import javax.enterprise.inject.Default;
+import javax.enterprise.util.AnnotationLiteral;
+
+public class DefaultLiteral extends AnnotationLiteral<Default> implements Default
+{
+    public static final DefaultLiteral INSTANCE = new DefaultLiteral();
+
+    @Override
+    public String toString()
+    {
+        return "@javax.enterprise.inject.Default()";
+    }
+}

Added: commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/cdi/ExtraJCacheExtension.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/cdi/ExtraJCacheExtension.java?rev=1593138&view=auto
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/cdi/ExtraJCacheExtension.java (added)
+++ commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/cdi/ExtraJCacheExtension.java Wed May  7 21:23:17 2014
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.commons.jcs.jcache.extras.cdi;
+
+import javax.cache.CacheManager;
+import javax.cache.Caching;
+import javax.cache.spi.CachingProvider;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.AfterBeanDiscovery;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.ProcessBean;
+import java.util.Properties;
+
+// add default CacheProvider and CacheManager
+public class ExtraJCacheExtension implements Extension
+{
+    private boolean cacheManagerFound = false;
+    private boolean cacheProviderFound = false;
+
+    public <A> void processBean(final @Observes ProcessBean<A> processBeanEvent)
+    {
+        if (cacheManagerFound && cacheProviderFound)
+        {
+            return;
+        }
+
+        final Bean<A> bean = processBeanEvent.getBean();
+        if (CacheManagerBean.class.isInstance(bean) || CacheProviderBean.class.isInstance(bean))
+        {
+            return;
+        }
+
+        if (!cacheManagerFound)
+        {
+            cacheManagerFound = bean.getTypes().contains(CacheManager.class);
+        }
+        if (!cacheProviderFound)
+        {
+            cacheProviderFound = bean.getTypes().contains(CachingProvider.class);
+        }
+    }
+
+    public void addJCacheBeans(final @Observes AfterBeanDiscovery afterBeanDiscovery)
+    {
+        if (cacheManagerFound && cacheProviderFound) {
+            return;
+        }
+
+        final CachingProvider cachingProvider = Caching.getCachingProvider();
+        if (!cacheManagerFound)
+        {
+            final CacheManager cacheManager = cachingProvider.getCacheManager(
+                    cachingProvider.getDefaultURI(),
+                    cachingProvider.getDefaultClassLoader(),
+                    new Properties());
+            afterBeanDiscovery.addBean(new CacheManagerBean(cacheManager));
+        }
+        if (!cacheProviderFound)
+        {
+            afterBeanDiscovery.addBean(new CacheProviderBean(cachingProvider));
+        }
+    }
+}

Added: commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension?rev=1593138&view=auto
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension (added)
+++ commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension Wed May  7 21:23:17 2014
@@ -0,0 +1 @@
+org.apache.commons.jcs.jcache.extras.cdi.ExtraJCacheExtension

Added: commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/test/java/org/apache/commons/jcs/jcache/extras/cdi/ExtraJCacheExtensionTest.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/test/java/org/apache/commons/jcs/jcache/extras/cdi/ExtraJCacheExtensionTest.java?rev=1593138&view=auto
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/test/java/org/apache/commons/jcs/jcache/extras/cdi/ExtraJCacheExtensionTest.java (added)
+++ commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/test/java/org/apache/commons/jcs/jcache/extras/cdi/ExtraJCacheExtensionTest.java Wed May  7 21:23:17 2014
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.commons.jcs.jcache.extras.cdi;
+
+import org.apache.webbeans.config.WebBeansContext;
+import org.apache.webbeans.container.BeanManagerImpl;
+import org.apache.webbeans.inject.OWBInjector;
+import org.apache.webbeans.spi.ContainerLifecycle;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import javax.cache.CacheManager;
+import javax.cache.spi.CachingProvider;
+import javax.inject.Inject;
+
+import static org.junit.Assert.assertNotNull;
+
+public class ExtraJCacheExtensionTest
+{
+    private static BeanManagerImpl bm;
+    private static ContainerLifecycle lifecycle;
+
+    @BeforeClass
+    public static void startContainer()
+    {
+        final WebBeansContext webBeansContext = WebBeansContext.currentInstance();
+        lifecycle = webBeansContext.getService(ContainerLifecycle.class);
+        lifecycle.startApplication(null);
+        bm = webBeansContext.getBeanManagerImpl();
+    }
+
+    @AfterClass
+    public static void stopContainer()
+    {
+        lifecycle.stopApplication(null);
+    }
+
+    @Before
+    public void inject() throws Exception
+    {
+        OWBInjector.inject(bm, this, bm.createCreationalContext(null));
+    }
+
+    @Inject
+    private BeanWithInjections bean;
+
+    @Test
+    public void defaultCacheManager()
+    {
+        assertNotNull(bean.getMgr());
+    }
+
+    @Test
+    public void defaultCacheProvider()
+    {
+        assertNotNull(bean.getProvider());
+    }
+
+    public static class BeanWithInjections {
+        @Inject
+        private CacheManager mgr;
+
+        @Inject
+        private CachingProvider provider;
+
+        public CacheManager getMgr()
+        {
+            return mgr;
+        }
+
+        public CachingProvider getProvider()
+        {
+            return provider;
+        }
+    }
+}

Added: commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/test/resources/META-INF/beans.xml
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/test/resources/META-INF/beans.xml?rev=1593138&view=auto
==============================================================================
    (empty)

Modified: commons/proper/jcs/trunk/commons-jcs-jcache/pom.xml
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-jcache/pom.xml?rev=1593138&r1=1593137&r2=1593138&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-jcache/pom.xml (original)
+++ commons/proper/jcs/trunk/commons-jcs-jcache/pom.xml Wed May  7 21:23:17 2014
@@ -30,36 +30,24 @@
   </parent>
 
   <artifactId>commons-jcs-jcache</artifactId>
-
   <name>Apache Commons JCS :: JCache</name>
 
   <dependencies>
-
-    <dependency>
-      <groupId>${project.groupId}</groupId>
-      <artifactId>commons-jcs-core</artifactId>
-    </dependency>
-
     <dependency>
       <groupId>javax.cache</groupId>
       <artifactId>cache-api</artifactId>
-      <scope>provided</scope>
     </dependency>
     <dependency>
       <groupId>org.apache.geronimo.specs</groupId>
       <artifactId>geronimo-atinject_1.0_spec</artifactId>
-      <version>1.0</version>
-      <scope>provided</scope>
     </dependency>
     <dependency>
       <groupId>org.apache.geronimo.specs</groupId>
       <artifactId>geronimo-jcdi_1.0_spec</artifactId>
-      <scope>provided</scope>
     </dependency>
     <dependency>
       <groupId>org.apache.geronimo.specs</groupId>
       <artifactId>geronimo-interceptor_1.1_spec</artifactId>
-      <scope>provided</scope>
     </dependency>
 
     <dependency>
@@ -67,18 +55,6 @@
       <artifactId>junit</artifactId>
       <scope>test</scope>
     </dependency>
-    <dependency>
-      <groupId>org.hamcrest</groupId>
-      <artifactId>hamcrest-library</artifactId>
-      <scope>test</scope>
-    </dependency>
-
-    <dependency>
-      <groupId>org.openjdk.jmh</groupId>
-      <artifactId>jmh-core</artifactId>
-      <version>0.4.2</version>
-      <scope>test</scope>
-    </dependency>
   </dependencies>
 
 </project>

Modified: commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/JCSCache.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/JCSCache.java?rev=1593138&r1=1593137&r2=1593138&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/JCSCache.java (original)
+++ commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/JCSCache.java Wed May  7 21:23:17 2014
@@ -18,20 +18,12 @@
  */
 package org.apache.commons.jcs.jcache;
 
-import static org.apache.commons.jcs.jcache.Asserts.assertNotNull;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.io.Serializable;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
+import org.apache.commons.jcs.jcache.jmx.JCSCacheMXBean;
+import org.apache.commons.jcs.jcache.jmx.JCSCacheStatisticsMXBean;
+import org.apache.commons.jcs.jcache.jmx.JMXs;
+import org.apache.commons.jcs.jcache.proxy.ExceptionWrapperHandler;
+import org.apache.commons.jcs.jcache.serialization.Serializations;
+import org.apache.commons.jcs.jcache.thread.DaemonThreadFactory;
 
 import javax.cache.Cache;
 import javax.cache.CacheManager;
@@ -40,7 +32,6 @@ import javax.cache.configuration.Complet
 import javax.cache.configuration.Configuration;
 import javax.cache.configuration.Factory;
 import javax.cache.event.CacheEntryEvent;
-import javax.cache.event.CacheEntryListener;
 import javax.cache.event.EventType;
 import javax.cache.expiry.Duration;
 import javax.cache.expiry.EternalExpiryPolicy;
@@ -54,30 +45,27 @@ import javax.cache.processor.EntryProces
 import javax.cache.processor.EntryProcessorException;
 import javax.cache.processor.EntryProcessorResult;
 import javax.management.ObjectName;
+import java.io.Closeable;
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
 
-import org.apache.commons.jcs.access.CacheAccess;
-import org.apache.commons.jcs.access.exception.CacheException;
-import org.apache.commons.jcs.engine.ElementAttributes;
-import org.apache.commons.jcs.engine.behavior.ICacheElement;
-import org.apache.commons.jcs.engine.behavior.ICompositeCacheAttributes;
-import org.apache.commons.jcs.engine.behavior.IElementSerializer;
-import org.apache.commons.jcs.engine.control.event.behavior.IElementEvent;
-import org.apache.commons.jcs.engine.control.event.behavior.IElementEventHandler;
-import org.apache.commons.jcs.engine.control.CompositeCache;
-import org.apache.commons.jcs.jcache.jmx.JCSCacheMXBean;
-import org.apache.commons.jcs.jcache.jmx.JCSCacheStatisticsMXBean;
-import org.apache.commons.jcs.jcache.jmx.JMXs;
-import org.apache.commons.jcs.jcache.proxy.ExceptionWrapperHandler;
-import org.apache.commons.jcs.utils.serialization.StandardSerializer;
-import org.apache.commons.jcs.utils.threadpool.DaemonThreadFactory;
-import org.apache.commons.jcs.utils.threadpool.ThreadPoolManager;
+import static org.apache.commons.jcs.jcache.Asserts.assertNotNull;
 
-// TODO: get statistics locally correct then correct even if distributed
 public class JCSCache<K extends Serializable, V extends Serializable, C extends CompleteConfiguration<K, V>> implements Cache<K, V>
 {
-    private static final String POOL_SIZE_PROPERTY = ThreadPoolManager.PROP_NAME_ROOT + ".size";
-
-    private final CacheAccess<K, JCSElement<V>> delegate;
+    private final ConcurrentMap<JCSKey<K>, JCSElement<V>> delegate;
     private final CacheManager manager;
     private final JCSConfiguration<K, V> config;
     private final CacheLoader<K, V> loader;
@@ -85,27 +73,42 @@ public class JCSCache<K extends Serializ
     private final ExpiryPolicy expiryPolicy;
     private final ObjectName cacheConfigObjectName;
     private final ObjectName cacheStatsObjectName;
+    private final String name;
+    private final long maxSize;
+    private final long maxDelete;
     private volatile boolean closed = false;
     private final Map<CacheEntryListenerConfiguration<K, V>, JCSListener<K, V>> listeners = new ConcurrentHashMap<CacheEntryListenerConfiguration<K, V>, JCSListener<K, V>>();
     private final Statistics statistics = new Statistics();
-    private final IElementSerializer serializer = new StandardSerializer();
     private final ExecutorService pool;
 
+
     public JCSCache(final ClassLoader classLoader, final CacheManager mgr,
                     final String cacheName,
                     final JCSConfiguration<K, V> configuration,
-                    final CompositeCache<K, JCSElement<V>> cache, final Properties properties)
+                    final Properties properties)
     {
         manager = mgr;
 
-        final ICompositeCacheAttributes cacheAttributes = cache.getCacheAttributes();
-        cacheAttributes.setCacheName(cacheName);
+        name = cacheName;
+
+        final int capacity = Integer.parseInt(property(properties, cacheName, "capacity", "1000"));
+        final float loadFactor = Float.parseFloat(property(properties, cacheName, "loadFactor", "0.75"));
+        final int concurrencyLevel = Integer.parseInt(property(properties, cacheName, "concurrencyLevel", "16"));
+        delegate = new ConcurrentHashMap<JCSKey<K>, JCSElement<V>>(capacity, loadFactor, concurrencyLevel);
 
-        delegate = new CacheAccess<K, JCSElement<V>>(cache);
         config = configuration;
-        DaemonThreadFactory threadFactory = new DaemonThreadFactory("JCS-JCache-");
-        pool = properties != null && properties.containsKey(POOL_SIZE_PROPERTY) ? Executors.newFixedThreadPool(
-                Integer.parseInt(properties.getProperty(POOL_SIZE_PROPERTY)), threadFactory) : Executors.newCachedThreadPool(threadFactory);
+
+        final int poolSize = Integer.parseInt(property(properties, cacheName, "pool.size", "3"));
+        final DaemonThreadFactory threadFactory = new DaemonThreadFactory("JCS-JCache-");
+        pool = poolSize > 0 ? Executors.newFixedThreadPool(poolSize, threadFactory) : Executors.newCachedThreadPool(threadFactory);
+
+        maxSize = Long.parseLong(property(properties, cacheName, "maxSize", "1000"));
+        maxDelete = Long.parseLong(property(properties, cacheName, "maxDeleteByEvictionRun", "100"));
+        final long evictionPause = Long.parseLong(properties.getProperty(cacheName + ".evictionPause", properties.getProperty("evictionPause", "30000")));
+        if (evictionPause > 0)
+        {
+            pool.submit(new EvictionThread<K, V>(this, evictionPause));
+        }
 
         final Factory<CacheLoader<K, V>> cacheLoaderFactory = configuration.getCacheLoaderFactory();
         if (cacheLoaderFactory == null)
@@ -149,10 +152,10 @@ public class JCSCache<K extends Serializ
         final String mgrStr = manager.getURI().toString().replaceAll(",|:|=|\n", ".");
         try
         {
-            cacheConfigObjectName = new ObjectName("javax.cache:type=CacheConfiguration," + "CacheManager=" + mgrStr + "," + "Cache="
-                    + cache.getCacheName());
-            cacheStatsObjectName = new ObjectName("javax.cache:type=CacheStatistics," + "CacheManager=" + mgrStr + "," + "Cache="
-                    + cache.getCacheName());
+            cacheConfigObjectName = new ObjectName("javax.cache:type=CacheConfiguration,"
+                    + "CacheManager=" + mgrStr + "," + "Cache=" + name);
+            cacheStatsObjectName = new ObjectName("javax.cache:type=CacheStatistics,"
+                    + "CacheManager=" + mgrStr + "," + "Cache=" + name);
         }
         catch (final Exception e)
         {
@@ -168,6 +171,11 @@ public class JCSCache<K extends Serializ
         }
     }
 
+    private static String property(final Properties properties, final String cacheName, final String name, final String defaultValue)
+    {
+        return properties.getProperty(cacheName + "." + name, properties.getProperty(name, defaultValue));
+    }
+
     private void assertNotClosed()
     {
         if (isClosed())
@@ -181,7 +189,7 @@ public class JCSCache<K extends Serializ
     {
         assertNotClosed();
         assertNotNull(key, "key");
-        return doGetControllingExpiry(key, true, false, false, true);
+        return doGetControllingExpiry(new JCSKey<K>(key), true, false, false, true);
     }
 
     private V doLoad(final K key, final boolean update, final boolean propagateLoadException)
@@ -200,31 +208,23 @@ public class JCSCache<K extends Serializ
         }
         if (v != null)
         {
-            try
+            final Duration duration = update ? expiryPolicy.getExpiryForUpdate() : expiryPolicy.getExpiryForCreation();
+            if (duration == null || !duration.isZero())
             {
-                final Duration duration = update ? expiryPolicy.getExpiryForUpdate() : expiryPolicy.getExpiryForCreation();
-                if (duration == null || !duration.isZero())
-                {
-                    delegate.put(key, new JCSElement<V>(v, duration));
-                }
-            }
-            catch (final CacheException e)
-            {
-                throw new IllegalStateException(e);
+                final JCSKey<K> jcsKey = new JCSKey<K>(key);
+                jcsKey.access(Times.now(false));
+                delegate.put(jcsKey, new JCSElement<V>(v, duration));
+                evictIfMaxSize();
             }
         }
         return v;
     }
 
-    private void touch(final K key, final JCSElement<V> elt)
+    private void touch(final JCSKey<K> key, final JCSElement<V> elt)
     {
-        try
+        if (config.isStoreByValue())
         {
-            delegate.put(key, elt);
-        }
-        catch (final CacheException e)
-        {
-            // no-op
+            delegate.put(new JCSKey<K>(Serializations.copy(manager.getClassLoader(), key.getKey())), elt);
         }
     }
 
@@ -237,14 +237,12 @@ public class JCSCache<K extends Serializ
             assertNotNull(k, "key");
         }
 
-        final Set<K> names = (Set<K>) keys;
         final Map<K, V> result = new HashMap<K, V>();
-        for (final Map.Entry<K, ICacheElement<K, JCSElement<V>>> k : delegate.getCacheElements(names).entrySet())
-        {
-            final K key = k.getKey();
+        for (final K key : keys) {
             assertNotNull(key, "key");
 
-            final JCSElement<V> elt = k.getValue() != null ? k.getValue().getVal() : null;
+            final JCSKey<K> cacheKey = new JCSKey<K>(key);
+            final JCSElement<V> elt = delegate.get(cacheKey);
             V val = elt != null ? elt.getElement() : null;
             if (val == null && config.isReadThrough())
             {
@@ -257,21 +255,14 @@ public class JCSCache<K extends Serializ
             else if (elt != null)
             {
                 elt.update(expiryPolicy.getExpiryForAccess());
-                touch(key, elt);
-            }
-            result.put(key, val);
-        }
-        if (config.isReadThrough() && result.size() != keys.size())
-        {
-            for (final K k : keys)
-            {
-                if (!result.containsKey(k))
+                if (elt.isExpired())
                 {
-                    final V v = doLoad(k, false, false);
-                    if (v != null)
-                    {
-                        result.put(k, v);
-                    }
+                    delegate.remove(cacheKey);
+                }
+                else
+                {
+                    touch(cacheKey, elt);
+                    result.put(key, val);
                 }
             }
         }
@@ -283,7 +274,7 @@ public class JCSCache<K extends Serializ
     {
         assertNotClosed();
         assertNotNull(key, "key");
-        return delegate.get(key) != null;
+        return delegate.get(new JCSKey<K>(key)) != null;
     }
 
     @Override
@@ -294,73 +285,60 @@ public class JCSCache<K extends Serializ
         assertNotNull(rawValue, "value");
 
         final boolean statisticsEnabled = config.isStatisticsEnabled();
-        final long start = statisticsEnabled ? Times.now() : 0;
+        final long start = Times.now(false); // needed for access (eviction)
 
-        try
-        {
-            final JCSElement<V> oldElt = delegate.get(key);
-            final V old = oldElt != null ? oldElt.getElement() : null;
+        final JCSKey<K> cacheKey = new JCSKey<K>(key);
+        final JCSElement<V> oldElt = delegate.get(cacheKey);
+        final V old = oldElt != null ? oldElt.getElement() : null;
 
-            final boolean storeByValue = config.isStoreByValue();
-            final V value = storeByValue ? copy(rawValue) : rawValue;
+        final boolean storeByValue = config.isStoreByValue();
+        final V value = storeByValue ? Serializations.copy(manager.getClassLoader(), rawValue) : rawValue;
 
-            final boolean created = old == null;
-            final JCSElement<V> element = new JCSElement<V>(value, created ? expiryPolicy.getExpiryForCreation()
-                    : expiryPolicy.getExpiryForUpdate());
-            if (element.isExpired())
+        final boolean created = old == null;
+        final JCSElement<V> element = new JCSElement<V>(value, created ? expiryPolicy.getExpiryForCreation()
+                : expiryPolicy.getExpiryForUpdate());
+        if (element.isExpired())
+        {
+            if (!created)
             {
-                if (!created)
-                {
-                    delegate.remove(key);
-                }
+                delegate.remove(cacheKey);
             }
-            else
+        }
+        else
+        {
+            writer.write(new JCSEntry<K, V>(key, value));
+            final JCSKey<K> jcsKey = storeByValue ? new JCSKey<K>(Serializations.copy(manager.getClassLoader(), key)) : cacheKey;
+            jcsKey.access(start);
+            delegate.put(jcsKey, element);
+            for (final JCSListener<K, V> listener : listeners.values())
             {
-                writer.write(new JCSEntry<K, V>(key, value));
-                delegate.put(storeByValue ? copy(key) : key, element);
-                for (final JCSListener<K, V> listener : listeners.values())
+                if (created)
                 {
-                    if (created)
-                    {
-                        listener.onCreated(Arrays.<CacheEntryEvent<? extends K, ? extends V>> asList(new JCSCacheEntryEvent<K, V>(this,
-                                EventType.CREATED, null, key, value)));
-                    }
-                    else
-                    {
-                        listener.onUpdated(Arrays.<CacheEntryEvent<? extends K, ? extends V>> asList(new JCSCacheEntryEvent<K, V>(this,
-                                EventType.UPDATED, old, key, value)));
-                    }
+                    listener.onCreated(Arrays.<CacheEntryEvent<? extends K, ? extends V>> asList(new JCSCacheEntryEvent<K, V>(this,
+                            EventType.CREATED, null, key, value)));
                 }
-
-                if (statisticsEnabled)
+                else
                 {
-                    statistics.increasePuts(1);
-                    statistics.addPutTime(System.currentTimeMillis() - start);
+                    listener.onUpdated(Arrays.<CacheEntryEvent<? extends K, ? extends V>> asList(new JCSCacheEntryEvent<K, V>(this,
+                            EventType.UPDATED, old, key, value)));
                 }
             }
-        }
-        catch (final CacheException e)
-        {
-            throw new IllegalStateException(e);
-        }
-    }
 
-    private <T extends Serializable> T copy(final T value)
-    {
-        try
-        {
-            return serializer.deSerialize(serializer.serialize(value));
-        }
-        catch (final Exception ioe)
-        {
-            throw new IllegalStateException(ioe.getMessage(), ioe);
+            if (statisticsEnabled)
+            {
+                statistics.increasePuts(1);
+                statistics.addPutTime(System.currentTimeMillis() - start);
+            }
+
+            evictIfMaxSize();
         }
     }
 
     @Override
     public V getAndPut(final K key, final V value)
     {
-        final V v = doGetControllingExpiry(key, false, false, true, false);
+        assertNotClosed();
+        final V v = doGetControllingExpiry(new JCSKey<K>(key), false, false, true, false);
         put(key, value);
         return v;
     }
@@ -395,12 +373,13 @@ public class JCSCache<K extends Serializ
         assertNotNull(key, "key");
 
         final boolean statisticsEnabled = config.isStatisticsEnabled();
-        final long start = statisticsEnabled ? Times.now() : 0;
+        final long start = Times.now(!statisticsEnabled);
 
-        final JCSElement<V> v = delegate.get(key);
-        final V value = v != null && v.getElement() != null ? v.getElement() : null;
         writer.delete(key);
-        boolean remove = delegate.getCacheControl().remove(key);
+        final JCSKey<K> cacheKey = new JCSKey<K>(key);
+        final JCSElement<V> v = delegate.remove(cacheKey);
+        final V value = v != null && v.getElement() != null ? v.getElement() : null;
+        boolean remove = v != null;
         if (v != null && v.isExpired())
         {
             remove = false;
@@ -413,7 +392,7 @@ public class JCSCache<K extends Serializ
         if (remove && statisticsEnabled)
         {
             statistics.increaseRemovals(1);
-            statistics.addRemoveTime(Times.now() - start);
+            statistics.addRemoveTime(Times.now(false) - start);
         }
         return remove;
     }
@@ -424,7 +403,8 @@ public class JCSCache<K extends Serializ
         assertNotClosed();
         assertNotNull(key, "key");
         assertNotNull(oldValue, "oldValue");
-        final V v = doGetControllingExpiry(key, false, false, false, false);
+        final JCSKey<K> cacheKey = new JCSKey<K>(key);
+        final V v = doGetControllingExpiry(cacheKey, false, false, false, false);
         final boolean found = v != null;
         if (found)
         {
@@ -433,7 +413,7 @@ public class JCSCache<K extends Serializ
                 remove(key);
                 return true;
             }
-            delegate.get(key).update(expiryPolicy.getExpiryForAccess());
+            delegate.get(new JCSKey<K>(key)).update(expiryPolicy.getExpiryForAccess());
         }
         return false;
     }
@@ -441,23 +421,24 @@ public class JCSCache<K extends Serializ
     @Override
     public V getAndRemove(final K key)
     {
-        final V v = doGetControllingExpiry(key, false, false, true, false);
+        assertNotClosed();
+        final V v = doGetControllingExpiry(new JCSKey<K>(key), false, false, true, false);
         remove(key);
         return v;
     }
 
-    private V doGetControllingExpiry(final K key, final boolean updateAcess, final boolean forceDoLoad, final boolean skipLoad,
+    private V doGetControllingExpiry(final JCSKey<K> key, final boolean updateAcess, final boolean forceDoLoad, final boolean skipLoad,
             final boolean propagateLoadException)
     {
         final boolean statisticsEnabled = config.isStatisticsEnabled();
-        final long getStart = Times.now();
+        final long getStart = Times.now(false);
         final JCSElement<V> elt = delegate.get(key);
         V v = elt != null ? elt.getElement() : null;
         if (v == null && (config.isReadThrough() || forceDoLoad))
         {
             if (!skipLoad)
             {
-                v = doLoad(key, false, propagateLoadException);
+                v = doLoad(key.getKey(), false, propagateLoadException);
             }
         }
         else if (statisticsEnabled)
@@ -474,19 +455,20 @@ public class JCSCache<K extends Serializ
 
         if (updateAcess && elt != null)
         {
+            key.access(getStart);
             elt.update(expiryPolicy.getExpiryForAccess());
             if (elt.isExpired())
             {
-                delegate.getCacheControl().remove(key);
+                delegate.remove(key);
             }
             else
             {
                 touch(key, elt);
             }
         }
-        if (v != null)
+        if (statisticsEnabled && v != null)
         {
-            statistics.addGetTime(Times.now() - getStart);
+            statistics.addGetTime(Times.now(!statisticsEnabled) - getStart);
         }
         return v;
     }
@@ -499,7 +481,8 @@ public class JCSCache<K extends Serializ
         assertNotNull(oldValue, "oldValue");
         assertNotNull(newValue, "newValue");
         final boolean statisticsEnabled = config.isStatisticsEnabled();
-        final JCSElement<V> elt = delegate.get(key);
+        final JCSKey<K> cacheKey = new JCSKey<K>(key);
+        final JCSElement<V> elt = delegate.get(cacheKey);
         if (elt != null)
         {
             V value = elt.getElement();
@@ -523,7 +506,7 @@ public class JCSCache<K extends Serializ
             else if (value != null)
             {
                 elt.update(expiryPolicy.getExpiryForAccess());
-                touch(key, elt);
+                touch(cacheKey, elt);
             }
         }
         else if (statisticsEnabled)
@@ -565,7 +548,8 @@ public class JCSCache<K extends Serializ
 
         final boolean statisticsEnabled = config.isStatisticsEnabled();
 
-        final JCSElement<V> elt = delegate.get(key);
+        final JCSKey<K> cacheKey = new JCSKey<K>(key);
+        final JCSElement<V> elt = delegate.get(cacheKey);
         if (elt != null)
         {
             V oldValue = elt.getElement();
@@ -601,21 +585,18 @@ public class JCSCache<K extends Serializ
     @Override
     public void removeAll()
     {
-        removeAll(delegate.getCacheControl().getKeySet());
+        assertNotClosed();
+        for (final JCSKey<K> k : delegate.keySet())
+        {
+            remove(k.getKey());
+        }
     }
 
     @Override
     public void clear()
     {
         assertNotClosed();
-        try
-        {
-            delegate.clear();
-        }
-        catch (final CacheException e)
-        {
-            throw new IllegalStateException(e);
-        }
+        delegate.clear();
     }
 
     @Override
@@ -659,7 +640,7 @@ public class JCSCache<K extends Serializ
                 {
                     continue;
                 }
-                doGetControllingExpiry(k, true, true, false, completionListener != null);
+                doGetControllingExpiry(new JCSKey<K>(k), true, true, false, completionListener != null);
             }
         }
         catch (final RuntimeException e)
@@ -784,7 +765,7 @@ public class JCSCache<K extends Serializ
     public Iterator<Entry<K, V>> iterator()
     {
         assertNotClosed();
-        final Iterator<K> keys = delegate.getCacheControl().getKeySet().iterator();
+        final Iterator<JCSKey<K>> keys = new HashSet<JCSKey<K>>(delegate.keySet()).iterator();
         return new Iterator<Entry<K, V>>()
         {
             private K lastKey = null;
@@ -798,7 +779,8 @@ public class JCSCache<K extends Serializ
             @Override
             public Entry<K, V> next()
             {
-                lastKey = keys.next();
+                final JCSKey<K> next = keys.next();
+                lastKey = next.getKey();
                 return new JCSEntry<K, V>(lastKey, get(lastKey));
             }
 
@@ -818,7 +800,7 @@ public class JCSCache<K extends Serializ
     public String getName()
     {
         assertNotClosed();
-        return delegate.getCacheControl().getCacheName();
+        return name;
     }
 
     @Override
@@ -836,8 +818,9 @@ public class JCSCache<K extends Serializ
             return;
         }
 
-        delegate.dispose();
         manager.destroyCache(getName());
+        closed = true;
+        delegate.clear();
         close(loader);
         close(writer);
         close(expiryPolicy);
@@ -845,8 +828,8 @@ public class JCSCache<K extends Serializ
         {
             close(listener);
         }
-        closed = true;
         listeners.clear();
+        pool.shutdownNow();
         JMXs.unregister(cacheConfigObjectName);
         JMXs.unregister(cacheStatsObjectName);
     }
@@ -873,6 +856,10 @@ public class JCSCache<K extends Serializ
         {
             return clazz.cast(this);
         }
+        if (clazz.isAssignableFrom(Map.class) || clazz.isAssignableFrom(ConcurrentMap.class))
+        {
+            return clazz.cast(delegate);
+        }
         throw new IllegalArgumentException(clazz.getName() + " not supported in unwrap");
     }
 
@@ -906,4 +893,113 @@ public class JCSCache<K extends Serializ
         statistics.setActive(false);
         JMXs.unregister(cacheStatsObjectName);
     }
+
+    private static class EvictionThread<K extends Serializable, V extends Serializable> implements Runnable
+    {
+        private final long pause;
+        private final JCSCache<K, ?, ?> cache;
+
+        public EvictionThread(final JCSCache<K, ?, ?> cache, final long evictionPause)
+        {
+            this.cache = cache;
+            this.pause = evictionPause;
+        }
+
+        @Override
+        public void run()
+        {
+            while (!cache.isClosed())
+            {
+                cache.evict();
+                try
+                {
+                    Thread.sleep(pause);
+                }
+                catch (final InterruptedException e)
+                {
+                    Thread.interrupted();
+                    break;
+                }
+            }
+        }
+    }
+
+    private void evictIfMaxSize()
+    {
+        if (delegate.size() > maxSize)
+        {
+            pool.submit(new Runnable()
+            {
+                @Override
+                public void run()
+                {
+                    evict();
+                }
+            });
+        }
+    }
+
+    private void evict()
+    {
+        if (isClosed())
+        {
+            return;
+        }
+
+        final ConcurrentMap<JCSKey<K>, ? extends JCSElement<? extends Serializable>> map = delegate;
+        try
+        {
+            final TreeSet<JCSKey<K>> treeSet = new TreeSet<JCSKey<K>>(new Comparator<JCSKey<K>>()
+            {
+                @Override
+                public int compare(final JCSKey<K> o1, final JCSKey<K> o2)
+                {
+                    final long l = o2.lastAccess() - o1.lastAccess(); // inverse
+                    if (l == 0)
+                    {
+                        return o1.hashCode() - o2.hashCode();
+                    }
+                    return (int) l;
+                }
+            });
+            treeSet.addAll(map.keySet());
+
+            int delete = 0;
+            for (final JCSKey<K> key : treeSet)
+            {
+                if (delete >= maxDelete) {
+                    break;
+                }
+                final JCSElement<? extends Serializable> elt = map.get(key);
+                if (elt != null) {
+                    if (elt.isExpired())
+                    {
+                        map.remove(key);
+                        statistics.increaseEvictions(1);
+                        delete++;
+                    }
+                }
+            }
+
+            if (delete >= maxDelete && maxSize > 0 && map.size() > maxSize)
+            {
+                for (final JCSKey<K> key : treeSet)
+                {
+                    if (delete >= maxDelete) {
+                        break;
+                    }
+                    final JCSElement<? extends Serializable> elt = map.get(key);
+                    if (elt != null) {
+                        map.remove(key);
+                        statistics.increaseEvictions(1);
+                        delete++;
+                    }
+                }
+            }
+        }
+        catch (final Exception e)
+        {
+            // no-op
+        }
+    }
 }

Modified: commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/JCSCachingManager.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/JCSCachingManager.java?rev=1593138&r1=1593137&r2=1593138&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/JCSCachingManager.java (original)
+++ commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/JCSCachingManager.java Wed May  7 21:23:17 2014
@@ -18,23 +18,20 @@
  */
 package org.apache.commons.jcs.jcache;
 
-import static org.apache.commons.jcs.jcache.Asserts.assertNotNull;
+import org.apache.commons.jcs.jcache.proxy.ClassLoaderAwareCache;
 
+import javax.cache.Cache;
+import javax.cache.CacheManager;
+import javax.cache.configuration.Configuration;
+import javax.cache.spi.CachingProvider;
 import java.io.IOException;
 import java.io.InputStream;
-import java.lang.reflect.Proxy;
 import java.net.URI;
 import java.util.Properties;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
-import javax.cache.Cache;
-import javax.cache.CacheManager;
-import javax.cache.configuration.Configuration;
-import javax.cache.spi.CachingProvider;
-
-import org.apache.commons.jcs.engine.control.CompositeCacheManager;
-import org.apache.commons.jcs.jcache.proxy.ClassLoaderAwareHandler;
+import static org.apache.commons.jcs.jcache.Asserts.assertNotNull;
 
 public class JCSCachingManager implements CacheManager
 {
@@ -43,7 +40,7 @@ public class JCSCachingManager implement
     private final ClassLoader loader;
     private final Properties properties;
     private final ConcurrentMap<String, Cache<?, ?>> caches = new ConcurrentHashMap<String, Cache<?, ?>>();
-    private final CompositeCacheManager instance;
+    private final Properties configProperties;
     private volatile boolean closed = false;
 
     public JCSCachingManager(final CachingProvider provider, final URI uri, final ClassLoader loader, final Properties properties)
@@ -51,9 +48,11 @@ public class JCSCachingManager implement
         this.provider = provider;
         this.uri = uri;
         this.loader = loader;
-        this.properties = properties;
+        this.properties = readConfig(uri, loader, properties);
+        this.configProperties = properties;
+    }
 
-        instance = CompositeCacheManager.getUnconfiguredInstance();
+    private Properties readConfig(final URI uri, final ClassLoader loader, final Properties properties) {
         final Properties props = new Properties();
         InputStream inStream = null;
         try
@@ -90,7 +89,7 @@ public class JCSCachingManager implement
         {
             props.putAll(properties);
         }
-        instance.configure(props);
+        return props;
     }
 
     private void assertNotClosed()
@@ -113,11 +112,7 @@ public class JCSCachingManager implement
         final Class<?> valueType = configuration == null ? Object.class : configuration.getValueType();
         if (!caches.containsKey(cacheName))
         {
-            final Cache<K, V> cache = ClassLoaderAwareHandler.newProxy(
-                    loader, new JCSCache(loader, this, cacheName,
-                                        new JCSConfiguration(configuration, keyType, valueType),
-                                        instance.getCache(cacheName),
-                                        instance.getConfigurationProperties()), Cache.class);
+            final Cache<K, V> cache = ClassLoaderAwareCache.wrap(loader, new JCSCache(loader, this, cacheName, new JCSConfiguration(configuration, keyType, valueType), properties));
             caches.putIfAbsent(cacheName, cache);
         }
         else
@@ -133,14 +128,11 @@ public class JCSCachingManager implement
         assertNotClosed();
         assertNotNull(cacheName, "cacheName");
         final Cache<?, ?> cache = caches.remove(cacheName);
-        instance.freeCache(cacheName, true);
         if (cache != null && !cache.isClosed())
         {
             cache.clear();
             cache.close();
-            instance.freeCache(cacheName, true);
         }
-        instance.shutDown();
     }
 
     @Override
@@ -165,7 +157,7 @@ public class JCSCachingManager implement
     private JCSCache<?, ?, ?> getJCSCache(final String cacheName)
     {
         final Cache<?, ?> cache = caches.get(cacheName);
-        return JCSCache.class.cast(ClassLoaderAwareHandler.class.cast(Proxy.getInvocationHandler(cache)).getDelegate());
+        return JCSCache.class.cast(ClassLoaderAwareCache.getDelegate(cache));
     }
 
     @Override
@@ -206,7 +198,6 @@ public class JCSCachingManager implement
         {
             JCSCachingProvider.class.cast(provider).remove(this);
         }
-        instance.shutDown();
     }
 
     @Override
@@ -295,6 +286,6 @@ public class JCSCachingManager implement
     @Override
     public Properties getProperties()
     {
-        return properties;
+        return configProperties;
     }
 }

Modified: commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/JCSElement.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/JCSElement.java?rev=1593138&r1=1593137&r2=1593138&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/JCSElement.java (original)
+++ commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/JCSElement.java Wed May  7 21:23:17 2014
@@ -34,7 +34,7 @@ public class JCSElement<V> implements Se
 
     public boolean isExpired()
     {
-        return end != -1 && (end == 0 || Times.now() > end);
+        return end != -1 && (end == 0 || Times.now(false) > end);
     }
 
     public V getElement()
@@ -54,7 +54,7 @@ public class JCSElement<V> implements Se
         }
         else
         {
-            end = duration.getAdjustedTime(Times.now());
+            end = duration.getAdjustedTime(Times.now(false));
         }
     }
 }

Added: commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/JCSKey.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/JCSKey.java?rev=1593138&view=auto
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/JCSKey.java (added)
+++ commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/JCSKey.java Wed May  7 21:23:17 2014
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.commons.jcs.jcache;
+
+import java.io.Serializable;
+
+public class JCSKey<K extends Serializable> implements Serializable
+{
+    private final K key;
+    private volatile long lastAccess = 0;
+
+    public JCSKey(final K key) {
+        this.key = key;
+    }
+
+    public void access(final long time)
+    {
+        lastAccess = time;
+    }
+
+    public long lastAccess()
+    {
+        return lastAccess;
+    }
+
+    public K getKey()
+    {
+        return key;
+    }
+
+    @Override
+    public boolean equals(final Object o)
+    {
+        if (this == o) return true;
+        // if (o == null || getClass() != o.getClass()) return false; // not needed normally
+        final JCSKey jcsKey = JCSKey.class.cast(o);
+        return key.equals(jcsKey.key);
+
+    }
+
+    @Override
+    public int hashCode()
+    {
+        return key.hashCode();
+    }
+}

Modified: commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/Times.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/Times.java?rev=1593138&r1=1593137&r2=1593138&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/Times.java (original)
+++ commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/Times.java Wed May  7 21:23:17 2014
@@ -21,9 +21,13 @@ package org.apache.commons.jcs.jcache;
 
 public class Times
 {
-    public static long now()
+    public static long now(final boolean ignore)
     {
-        return System.currentTimeMillis();
+        if (ignore)
+        {
+            return -1;
+        }
+        return System.nanoTime() / 1000;
     }
 
     private Times()

Modified: commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CDIJCacheHelper.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CDIJCacheHelper.java?rev=1593138&r1=1593137&r2=1593138&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CDIJCacheHelper.java (original)
+++ commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CDIJCacheHelper.java Wed May  7 21:23:17 2014
@@ -18,9 +18,6 @@
  */
 package org.apache.commons.jcs.jcache.cdi;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
 import javax.cache.annotation.CacheDefaults;
 import javax.cache.annotation.CacheKeyGenerator;
 import javax.cache.annotation.CacheResolverFactory;
@@ -36,11 +33,12 @@ import java.lang.reflect.Method;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
+import java.util.logging.Logger;
 
 @ApplicationScoped
 public class CDIJCacheHelper
 {
-    private static final Log LOGGER = LogFactory.getLog(CDIJCacheHelper.class);
+    private static final Logger LOGGER = Logger.getLogger(CDIJCacheHelper.class.getName());
 
     private final CacheResolverFactory defaultCacheResolverFactory = new CacheResolverFactoryImpl();
     private final CacheKeyGeneratorImpl defaultCacheKeyGenerator = new CacheKeyGeneratorImpl();
@@ -173,7 +171,7 @@ public class CDIJCacheHelper
         final boolean dependent = Dependent.class.equals(scope);
         if (!dependent && !beanManager.isNormalScope(scope))
         {
-            LOGGER.warn("Not normal scope beans (" + type.getName() + ") can leak");
+            LOGGER.warning("Not normal scope beans (" + type.getName() + ") can leak");
         }
         try
         {

Copied: commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/proxy/ClassLoaderAwareCache.java (from r1593134, commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/proxy/ClassLoaderAwareHandler.java)
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/proxy/ClassLoaderAwareCache.java?p2=commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/proxy/ClassLoaderAwareCache.java&p1=commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/proxy/ClassLoaderAwareHandler.java&r1=1593134&r2=1593138&rev=1593138&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/proxy/ClassLoaderAwareHandler.java (original)
+++ commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/proxy/ClassLoaderAwareCache.java Wed May  7 21:23:17 2014
@@ -18,78 +18,476 @@
  */
 package org.apache.commons.jcs.jcache.proxy;
 
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
+import org.apache.commons.jcs.jcache.JCSCache;
 
-public class ClassLoaderAwareHandler implements InvocationHandler
+import javax.cache.Cache;
+import javax.cache.CacheManager;
+import javax.cache.configuration.CacheEntryListenerConfiguration;
+import javax.cache.configuration.Configuration;
+import javax.cache.integration.CompletionListener;
+import javax.cache.processor.EntryProcessor;
+import javax.cache.processor.EntryProcessorException;
+import javax.cache.processor.EntryProcessorResult;
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+// don't use a proxy, reflection is too slow here :(
+public class ClassLoaderAwareCache<K extends Serializable, V extends Serializable> implements Cache<K, V>
 {
     private final ClassLoader loader;
-    private final Object delegate;
+    private final JCSCache<K, V, ?> delegate;
 
-    public ClassLoaderAwareHandler(final ClassLoader loader, final Object delegate)
+    public ClassLoaderAwareCache(final ClassLoader loader, final JCSCache<K, V, ?> delegate)
     {
         this.loader = loader;
         this.delegate = delegate;
     }
 
+    private ClassLoader before(final Thread thread)
+    {
+        final ClassLoader tccl = thread.getContextClassLoader();
+        thread.setContextClassLoader(loader);
+        return tccl;
+    }
+
+    public V get(final K key)
+    {
+        final Thread thread = Thread.currentThread();
+        final ClassLoader loader = before(thread);
+        try
+        {
+            return delegate.get(key);
+        }
+        finally
+        {
+            thread.setContextClassLoader(loader);
+        }
+    }
+
+    public Map<K, V> getAll(final Set<? extends K> keys)
+    {
+        final Thread thread = Thread.currentThread();
+        final ClassLoader loader = before(thread);
+        try
+        {
+            return delegate.getAll(keys);
+        }
+        finally
+        {
+            thread.setContextClassLoader(loader);
+        }
+    }
+
+    public boolean containsKey(final K key)
+    {
+        final Thread thread = Thread.currentThread();
+        final ClassLoader loader = before(thread);
+        try
+        {
+            return delegate.containsKey(key);
+        }
+        finally
+        {
+            thread.setContextClassLoader(loader);
+        }
+    }
+
+    public void loadAll(final Set<? extends K> keys, boolean replaceExistingValues, final CompletionListener completionListener)
+    {
+        final Thread thread = Thread.currentThread();
+        final ClassLoader loader = before(thread);
+        try
+        {
+            delegate.loadAll(keys, replaceExistingValues, completionListener);
+        }
+        finally
+        {
+            thread.setContextClassLoader(loader);
+        }
+    }
+
+    public void put(final K key, final V value)
+    {
+        final Thread thread = Thread.currentThread();
+        final ClassLoader loader = before(thread);
+        try
+        {
+            delegate.put(key, value);
+        }
+        finally
+        {
+            thread.setContextClassLoader(loader);
+        }
+    }
+
+    public V getAndPut(final K key, final V value)
+    {
+        final Thread thread = Thread.currentThread();
+        final ClassLoader loader = before(thread);
+        try
+        {
+            return delegate.getAndPut(key, value);
+        }
+        finally
+        {
+            thread.setContextClassLoader(loader);
+        }
+    }
+
+    public void putAll(final Map<? extends K, ? extends V> map)
+    {
+        final Thread thread = Thread.currentThread();
+        final ClassLoader loader = before(thread);
+        try
+        {
+            delegate.putAll(map);
+        }
+        finally
+        {
+            thread.setContextClassLoader(loader);
+        }
+    }
+
+    public boolean putIfAbsent(final K key, final V value)
+    {
+        final Thread thread = Thread.currentThread();
+        final ClassLoader loader = before(thread);
+        try
+        {
+            return delegate.putIfAbsent(key, value);
+        }
+        finally
+        {
+            thread.setContextClassLoader(loader);
+        }
+    }
+
+    public boolean remove(final K key)
+    {
+        final Thread thread = Thread.currentThread();
+        final ClassLoader loader = before(thread);
+        try
+        {
+            return delegate.remove(key);
+        }
+        finally
+        {
+            thread.setContextClassLoader(loader);
+        }
+    }
+
+    public boolean remove(final K key, final V oldValue)
+    {
+        final Thread thread = Thread.currentThread();
+        final ClassLoader loader = before(thread);
+        try
+        {
+            return delegate.remove(key, oldValue);
+        }
+        finally
+        {
+            thread.setContextClassLoader(loader);
+        }
+    }
+
+    public V getAndRemove(final K key)
+    {
+        final Thread thread = Thread.currentThread();
+        final ClassLoader loader = before(thread);
+        try
+        {
+            return delegate.getAndRemove(key);
+        }
+        finally
+        {
+            thread.setContextClassLoader(loader);
+        }
+    }
+
+    public boolean replace(final K key, final V oldValue, final V newValue)
+    {
+        final Thread thread = Thread.currentThread();
+        final ClassLoader loader = before(thread);
+        try
+        {
+            return delegate.replace(key, oldValue, newValue);
+        }
+        finally
+        {
+            thread.setContextClassLoader(loader);
+        }
+    }
+
+    public boolean replace(final K key, final V value)
+    {
+        final Thread thread = Thread.currentThread();
+        final ClassLoader loader = before(thread);
+        try
+        {
+            return delegate.replace(key, value);
+        }
+        finally
+        {
+            thread.setContextClassLoader(loader);
+        }
+    }
+
+    public V getAndReplace(final K key, final V value)
+    {
+        final Thread thread = Thread.currentThread();
+        final ClassLoader loader = before(thread);
+        try
+        {
+            return delegate.getAndReplace(key, value);
+        }
+        finally
+        {
+            thread.setContextClassLoader(loader);
+        }
+    }
+
+    public void removeAll(final Set<? extends K> keys)
+    {
+        final Thread thread = Thread.currentThread();
+        final ClassLoader loader = before(thread);
+        try
+        {
+            delegate.removeAll(keys);
+        }
+        finally
+        {
+            thread.setContextClassLoader(loader);
+        }
+    }
+
     @Override
-    public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable
+    public void removeAll()
     {
-        final Thread th = Thread.currentThread();
-        final ClassLoader old = th.getContextClassLoader();
-        th.setContextClassLoader(loader);
+        final Thread thread = Thread.currentThread();
+        final ClassLoader loader = before(thread);
         try
         {
-            if (Object.class == method.getDeclaringClass())
-            {
-                if (isEquals(method, args))
-                {
-                    return doEquals(method, args);
-                }
-            }
-            return method.invoke(delegate, args);
+            delegate.removeAll();
         }
-        catch (final InvocationTargetException ite)
+        finally
         {
-            throw ite.getCause();
+            thread.setContextClassLoader(loader);
+        }
+    }
+
+    @Override
+    public void clear()
+    {
+        final Thread thread = Thread.currentThread();
+        final ClassLoader loader = before(thread);
+        try
+        {
+            delegate.clear();
         }
         finally
         {
-            th.setContextClassLoader(old);
+            thread.setContextClassLoader(loader);
         }
     }
 
-    private Object doEquals(final Method method, final Object[] args) throws IllegalAccessException, InvocationTargetException
+    public <C extends Configuration<K, V>> C getConfiguration(final Class<C> clazz)
     {
-        if (args[0] == null)
+        final Thread thread = Thread.currentThread();
+        final ClassLoader loader = before(thread);
+        try
         {
-            return false;
+            return delegate.getConfiguration(clazz);
         }
-        if (Proxy.isProxyClass(args[0].getClass()))
+        finally
         {
-            final InvocationHandler handler = Proxy.getInvocationHandler(args[0]);
-            if (ClassLoaderAwareHandler.class.isInstance(handler))
-            {
-                return delegate.equals(ClassLoaderAwareHandler.class.cast(handler).delegate);
-            }
+            thread.setContextClassLoader(loader);
+        }
+    }
+
+    public <T> T invoke(final K key, final EntryProcessor<K, V, T> entryProcessor, final Object... arguments) throws EntryProcessorException
+    {
+        final Thread thread = Thread.currentThread();
+        final ClassLoader loader = before(thread);
+        try
+        {
+            return delegate.invoke(key, entryProcessor, arguments);
+        }
+        finally
+        {
+            thread.setContextClassLoader(loader);
+        }
+    }
+
+    public <T> Map<K, EntryProcessorResult<T>> invokeAll(Set<? extends K> keys, EntryProcessor<K, V, T> entryProcessor, Object... arguments)
+    {
+        final Thread thread = Thread.currentThread();
+        final ClassLoader loader = before(thread);
+        try
+        {
+            return delegate.invokeAll(keys, entryProcessor, arguments);
+        }
+        finally
+        {
+            thread.setContextClassLoader(loader);
+        }
+    }
+
+    @Override
+    public String getName()
+    {
+        final Thread thread = Thread.currentThread();
+        final ClassLoader loader = before(thread);
+        try
+        {
+            return delegate.getName();
+        }
+        finally
+        {
+            thread.setContextClassLoader(loader);
+        }
+    }
+
+    @Override
+    public CacheManager getCacheManager()
+    {
+        final Thread thread = Thread.currentThread();
+        final ClassLoader loader = before(thread);
+        try
+        {
+            return delegate.getCacheManager();
+        }
+        finally
+        {
+            thread.setContextClassLoader(loader);
+        }
+    }
+
+    @Override
+    public void close()
+    {
+        final Thread thread = Thread.currentThread();
+        final ClassLoader loader = before(thread);
+        try
+        {
+            delegate.close();
+        }
+        finally
+        {
+            thread.setContextClassLoader(loader);
         }
-        return method.invoke(delegate, args);
     }
 
-    private boolean isEquals(final Method method, final Object[] args)
+    @Override
+    public boolean isClosed()
     {
-        return "equals".equals(method.getName()) && args != null && args.length == 1;
+        final Thread thread = Thread.currentThread();
+        final ClassLoader loader = before(thread);
+        try
+        {
+            return delegate.isClosed();
+        }
+        finally
+        {
+            thread.setContextClassLoader(loader);
+        }
     }
 
-    public static <T> T newProxy(final ClassLoader loader, final Object delegate, final Class<?>... apis)
+    @Override
+    public <T> T unwrap(final Class<T> clazz)
     {
-        return (T) Proxy.newProxyInstance(loader, apis, new ClassLoaderAwareHandler(loader, delegate));
+        final Thread thread = Thread.currentThread();
+        final ClassLoader loader = before(thread);
+        try
+        {
+            return delegate.unwrap(clazz);
+        }
+        finally
+        {
+            thread.setContextClassLoader(loader);
+        }
+    }
+
+    public void registerCacheEntryListener(final CacheEntryListenerConfiguration<K, V> cacheEntryListenerConfiguration)
+    {
+        final Thread thread = Thread.currentThread();
+        final ClassLoader loader = before(thread);
+        try
+        {
+            delegate.registerCacheEntryListener(cacheEntryListenerConfiguration);
+        }
+        finally
+        {
+            thread.setContextClassLoader(loader);
+        }
     }
 
-    public Object getDelegate()
+    public void deregisterCacheEntryListener(final CacheEntryListenerConfiguration<K, V> cacheEntryListenerConfiguration)
     {
-        return delegate;
+        final Thread thread = Thread.currentThread();
+        final ClassLoader loader = before(thread);
+        try
+        {
+            delegate.deregisterCacheEntryListener(cacheEntryListenerConfiguration);
+        }
+        finally
+        {
+            thread.setContextClassLoader(loader);
+        }
+    }
+
+    @Override
+    public Iterator<Entry<K, V>> iterator()
+    {
+        final Thread thread = Thread.currentThread();
+        final ClassLoader loader = before(thread);
+        try
+        {
+            return delegate.iterator();
+        }
+        finally
+        {
+            thread.setContextClassLoader(loader);
+        }
+    }
+
+    @Override
+    public boolean equals(final Object obj)
+    {
+        if (ClassLoaderAwareCache.class.isInstance(obj))
+        {
+            return delegate.equals(ClassLoaderAwareCache.class.cast(obj).delegate);
+        }
+        return super.equals(obj);
+    }
+
+    @Override
+    public int hashCode()
+    {
+        return delegate.hashCode();
+    }
+
+    public static <K extends Serializable, V extends Serializable> Cache<K, V> wrap(final ClassLoader loader, final JCSCache<K, V, ?> delegate)
+    {
+        ClassLoader dontWrapLoader = ClassLoaderAwareCache.class.getClassLoader();
+        while (dontWrapLoader != null)
+        {
+            if (loader == dontWrapLoader)
+            {
+                return delegate;
+            }
+            dontWrapLoader = dontWrapLoader.getParent();
+        }// TODO: maybe use normal wrapping since reflection takes too much time for a cache
+        return new ClassLoaderAwareCache<K, V>(loader, delegate);
+    }
+
+    public static <K extends Serializable, V extends Serializable> JCSCache<K, V, ?> getDelegate(final Cache<?, ?> cache)
+    {
+        if (JCSCache.class.isInstance(cache))
+        {
+            return (JCSCache<K, V, ?>) cache;
+        }
+        return ((ClassLoaderAwareCache<K, V>) cache).delegate;
     }
 }



Mime
View raw message