You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by rm...@apache.org on 2014/05/09 23:55:07 UTC

svn commit: r1593628 - in /commons/proper/jcs/trunk: commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/web/ commons-jcs-jcache-extras/src/test/java/org/apache/commons/jcs/jcache/extras/web/ commons-jcs-jcache/src/main/java/or...

Author: rmannibucau
Date: Fri May  9 21:55:07 2014
New Revision: 1593628

URL: http://svn.apache.org/r1593628
Log:
no more need of serializable constraint + JCacheFilter - maybe gzip support to add

Added:
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/web/
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/web/InMemoryResponse.java
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/web/JCacheFilter.java
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/test/java/org/apache/commons/jcs/jcache/extras/web/
    commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/test/java/org/apache/commons/jcs/jcache/extras/web/JCacheFilterTest.java
Modified:
    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/JCSCachingProvider.java
    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/JCSListener.java
    commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/TempStateCacheView.java
    commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CacheResolverFactoryImpl.java

Added: commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/web/InMemoryResponse.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/web/InMemoryResponse.java?rev=1593628&view=auto
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/web/InMemoryResponse.java (added)
+++ commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/web/InMemoryResponse.java Fri May  9 21:55:07 2014
@@ -0,0 +1,279 @@
+/*
+ * 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.web;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.concurrent.CopyOnWriteArraySet;
+
+public class InMemoryResponse extends HttpServletResponseWrapper implements Serializable
+{
+    private final ByteArrayOutputStream buffer;
+
+    private final Collection<Cookie> cookies = new CopyOnWriteArraySet<Cookie>();
+    private final Map<String, List<Serializable>> headers = new TreeMap<String, List<Serializable>>(String.CASE_INSENSITIVE_ORDER);
+    private int status = SC_OK;
+    private String contentType = null;
+    private PrintWriter writer;
+    private int contentLength;
+
+    public InMemoryResponse(final HttpServletResponse response, final ByteArrayOutputStream baos)
+    {
+        super(response);
+        this.buffer = baos;
+    }
+
+    private List<Serializable> ensureHeaderExists(final String s)
+    {
+        List<Serializable> values = headers.get(s);
+        if (values == null) {
+            values = new LinkedList<Serializable>();
+            headers.put(s, values);
+        }
+        return values;
+    }
+
+    @Override
+    public void addCookie(final Cookie cookie)
+    {
+        super.addCookie(cookie);
+        cookies.add(cookie);
+    }
+
+    @Override
+    public void addDateHeader(final String s, final long l)
+    {
+        super.addDateHeader(s, l);
+        ensureHeaderExists(s).add(l);
+    }
+
+    @Override
+    public void addHeader(final String s, final String s2)
+    {
+        super.addHeader(s, s2);
+        ensureHeaderExists(s).add(s2);
+    }
+
+    @Override
+    public void addIntHeader(final String s, final int i)
+    {
+        super.addIntHeader(s, i);
+        ensureHeaderExists(s).add(i);
+    }
+
+    @Override
+    public boolean containsHeader(final String s)
+    {
+        return headers.containsKey(s);
+    }
+
+    @Override
+    public String getHeader(final String s)
+    {
+        final List<Serializable> serializables = headers.get(s);
+        if (serializables.isEmpty())
+        {
+            return null;
+        }
+        return serializables.iterator().next().toString();
+    }
+
+    @Override
+    public Collection<String> getHeaderNames()
+    {
+        return headers.keySet();
+    }
+
+    @Override
+    public Collection<String> getHeaders(final String s)
+    {
+        final List<Serializable> serializables = headers.get(s);
+        final Collection<String> strings = new ArrayList<String>(serializables.size());
+        for (final Serializable ser : serializables)
+        {
+            strings.add(ser.toString());
+        }
+        return strings;
+    }
+
+    @Override
+    public int getStatus()
+    {
+        return status;
+    }
+
+    @Override
+    public void sendError(final int i) throws IOException
+    {
+        status = i;
+        super.sendError(i);
+    }
+
+    @Override
+    public void sendError(final int i, final String s) throws IOException
+    {
+        status = i;
+        super.sendError(i, s);
+    }
+
+    @Override
+    public void sendRedirect(final String s) throws IOException
+    {
+        status = SC_MOVED_TEMPORARILY;
+        super.sendRedirect(s);
+    }
+
+    @Override
+    public void setDateHeader(final String s, final long l)
+    {
+        super.setDateHeader(s, l);
+        final List<Serializable> serializables = ensureHeaderExists(s);
+        serializables.clear();
+        serializables.add(l);
+    }
+
+    @Override
+    public void setHeader(final String s, final String s2)
+    {
+        super.setHeader(s, s2);
+        final List<Serializable> serializables = ensureHeaderExists(s);
+        serializables.clear();
+        serializables.add(s2);
+    }
+
+    @Override
+    public void setIntHeader(final String s, final int i)
+    {
+        super.setIntHeader(s, i);
+        final List<Serializable> serializables = ensureHeaderExists(s);
+        serializables.clear();
+        serializables.add(i);
+    }
+
+    @Override
+    public void setStatus(int i)
+    {
+        status = i;
+        super.setStatus(i);
+    }
+
+    @Override
+    public void setStatus(final int i, final String s)
+    {
+        status = i;
+        super.setStatus(i, s);
+    }
+
+    @Override
+    public String getContentType()
+    {
+        return contentType;
+    }
+
+    @Override
+    public ServletOutputStream getOutputStream() throws IOException
+    {
+        return new ServletOutputStream()
+        {
+            @Override
+            public void write(final int b) throws IOException
+            {
+                buffer.write(b);
+            }
+        };
+    }
+
+    @Override
+    public PrintWriter getWriter() throws IOException
+    {
+        if (writer == null) {
+            writer = new PrintWriter(new OutputStreamWriter(buffer, getCharacterEncoding()), true);
+        }
+        return writer;
+    }
+
+    @Override
+    public void reset()
+    {
+        super.reset();
+        status = SC_OK;
+        headers.clear();
+        cookies.clear();
+        contentType = null;
+        contentLength = 0;
+    }
+
+    @Override
+    public void setContentLength(final int i)
+    {
+        super.setContentLength(i);
+        contentLength = i;
+    }
+
+    @Override
+    public void setContentType(final String s)
+    {
+        contentType = s;
+        super.setContentType(s);
+    }
+
+    @Override
+    public void flushBuffer() throws IOException
+    {
+        if (writer != null)
+        {
+            writer.flush();
+        }
+        super.flushBuffer();
+    }
+
+    public int getContentLength()
+    {
+        return contentLength;
+    }
+
+    public Collection<Cookie> getCookies()
+    {
+        return cookies;
+    }
+
+    public Map<String, List<Serializable>> getHeaders()
+    {
+        return headers;
+    }
+
+    public byte[] getOut()
+    {
+        return buffer.toByteArray();
+    }
+}

Added: commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/web/JCacheFilter.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/web/JCacheFilter.java?rev=1593628&view=auto
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/web/JCacheFilter.java (added)
+++ commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/main/java/org/apache/commons/jcs/jcache/extras/web/JCacheFilter.java Fri May  9 21:55:07 2014
@@ -0,0 +1,236 @@
+/*
+ * 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.web;
+
+import javax.cache.Cache;
+import javax.cache.CacheManager;
+import javax.cache.Caching;
+import javax.cache.configuration.FactoryBuilder;
+import javax.cache.configuration.MutableConfiguration;
+import javax.cache.expiry.ExpiryPolicy;
+import javax.cache.integration.CacheLoader;
+import javax.cache.integration.CacheWriter;
+import javax.cache.spi.CachingProvider;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.Serializable;
+import java.net.URI;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import static java.util.Collections.list;
+import static javax.servlet.http.HttpServletResponse.SC_OK;
+
+public class JCacheFilter implements Filter
+{
+    private Cache<String, Page> cache;
+    private CachingProvider provider;
+    private CacheManager manager;
+
+    @Override
+    public void init(final FilterConfig filterConfig) throws ServletException
+    {
+        final ClassLoader classLoader = filterConfig.getServletContext().getClassLoader();
+        provider = Caching.getCachingProvider(classLoader);
+
+        String uri = filterConfig.getInitParameter("configuration");
+        if (uri == null)
+        {
+            uri = provider.getDefaultURI().toString();
+        }
+        final Properties properties = new Properties();
+        for (final String key : list(filterConfig.getInitParameterNames()))
+        {
+            final String value = filterConfig.getInitParameter(key);
+            if (value != null)
+            {
+                properties.put(key, value);
+            }
+        }
+        manager = provider.getCacheManager(URI.create(uri), classLoader, properties);
+
+        String cacheName = filterConfig.getInitParameter("cache-name");
+        if (cacheName == null)
+        {
+            cacheName = JCacheFilter.class.getName();
+        }
+        cache = manager.getCache(cacheName);
+        if (cache == null)
+        {
+            final MutableConfiguration<String, Page> configuration = new MutableConfiguration<String, Page>()
+                    .setStoreByValue(false);
+            configuration.setReadThrough("true".equals(properties.getProperty("read-through", "false")));
+            configuration.setWriteThrough("true".equals(properties.getProperty("write-through", "false")));
+            if (configuration.isReadThrough())
+            {
+                configuration.setCacheLoaderFactory(new FactoryBuilder.ClassFactory<CacheLoader<String, Page>>(properties.getProperty("cache-loader-factory")));
+            }
+            if (configuration.isWriteThrough())
+            {
+                configuration.setCacheWriterFactory(new FactoryBuilder.ClassFactory<CacheWriter<? super String, ? super Page>>(properties.getProperty("cache-writer-factory")));
+            }
+            final String expirtyPolicy = properties.getProperty("expiry-policy-factory");
+            if (expirtyPolicy != null)
+            {
+                configuration.setExpiryPolicyFactory(new FactoryBuilder.ClassFactory<ExpiryPolicy>(expirtyPolicy));
+            }
+            configuration.setManagementEnabled("true".equals(properties.getProperty("management-enabled", "false")));
+            configuration.setStatisticsEnabled("true".equals(properties.getProperty("statistics-enabled", "false")));
+            cache = manager.createCache(cacheName, configuration);
+        }
+    }
+
+    @Override
+    public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, final FilterChain filterChain) throws IOException, ServletException
+    {
+        final HttpServletResponse httpServletResponse = HttpServletResponse.class.cast(servletResponse);
+        checkResponse(httpServletResponse);
+
+        final String key = key(servletRequest);
+        Page page = cache.get(key);
+        if (page == null)
+        {
+            final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            final InMemoryResponse response = new InMemoryResponse(httpServletResponse, baos);
+            filterChain.doFilter(servletRequest, response);
+            response.flushBuffer();
+
+            page = new Page(
+                    response.getStatus(),
+                    response.getContentType(),
+                    response.getContentLength(),
+                    response.getCookies(),
+                    response.getHeaders(),
+                    response.getOut());
+            cache.put(key, page);
+        }
+
+        if (page.status == SC_OK) {
+            checkResponse(httpServletResponse);
+
+            httpServletResponse.setStatus(page.status);
+            if (page.contentType != null)
+            {
+                httpServletResponse.setContentType(page.contentType);
+            }
+            if (page.contentLength > 0)
+            {
+                httpServletResponse.setContentLength(page.contentLength);
+            }
+            for (final Cookie c : page.cookies)
+            {
+                httpServletResponse.addCookie(c);
+            }
+            for (final Map.Entry<String, List<Serializable>> entry : page.headers.entrySet())
+            {
+                for (final Serializable value : entry.getValue())
+                {
+                    if (Integer.class.isInstance(value))
+                    {
+                        httpServletResponse.addIntHeader(entry.getKey(), Integer.class.cast(entry.getValue()));
+                    }
+                    else if (String.class.isInstance(value))
+                    {
+                        httpServletResponse.addHeader(entry.getKey(), String.class.cast(entry.getValue()));
+                    }
+                    else if (Long.class.isInstance(value))
+                    {
+                        httpServletResponse.addDateHeader(entry.getKey(), Long.class.cast(entry.getValue()));
+                    }
+                }
+            }
+            httpServletResponse.setContentLength(page.out.length);
+            final BufferedOutputStream bos = new BufferedOutputStream(httpServletResponse.getOutputStream());
+            if (page.out.length != 0)
+            {
+                bos.write(page.out);
+            }
+            else
+            {
+                bos.write(new byte[0]);
+            }
+            bos.flush();
+        }
+    }
+
+    protected String key(final ServletRequest servletRequest)
+    {
+        if (HttpServletRequest.class.isInstance(servletRequest))
+        {
+            final HttpServletRequest request = HttpServletRequest.class.cast(servletRequest);
+            return request.getMethod() + '_' + request.getRequestURI() + '_' + request.getQueryString();
+        }
+        return servletRequest.toString();
+    }
+
+    private void checkResponse(final ServletResponse servletResponse)
+    {
+        if (servletResponse.isCommitted()) {
+            throw new IllegalStateException("Response committed");
+        }
+    }
+
+    @Override
+    public void destroy()
+    {
+        if (!cache.isClosed())
+        {
+            cache.close();
+        }
+        if (!manager.isClosed())
+        {
+            manager.close();
+        }
+        provider.close();
+    }
+
+    protected static class Page implements Serializable {
+        private final int status;
+        private final String contentType;
+        private final int contentLength;
+        private final Collection<Cookie> cookies;
+        private final Map<String, List<Serializable>> headers;
+        private final byte[] out;
+
+        public Page(final int status,
+                    final String contentType, final int contentLength,
+                    final Collection<Cookie> cookies, final Map<String, List<Serializable>> headers,
+                    final byte[] out)
+        {
+            this.status = status;
+            this.contentType = contentType;
+            this.contentLength = contentLength;
+            this.cookies = cookies;
+            this.headers = headers;
+            this.out = out;
+        }
+    }
+}

Added: commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/test/java/org/apache/commons/jcs/jcache/extras/web/JCacheFilterTest.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/test/java/org/apache/commons/jcs/jcache/extras/web/JCacheFilterTest.java?rev=1593628&view=auto
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/test/java/org/apache/commons/jcs/jcache/extras/web/JCacheFilterTest.java (added)
+++ commons/proper/jcs/trunk/commons-jcs-jcache-extras/src/test/java/org/apache/commons/jcs/jcache/extras/web/JCacheFilterTest.java Fri May  9 21:55:07 2014
@@ -0,0 +1,190 @@
+/*
+ * 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.web;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static org.junit.Assert.assertEquals;
+
+public class JCacheFilterTest
+{
+    private final ThreadLocal<ByteArrayOutputStream> outputStreamAsBytes = new ThreadLocal<ByteArrayOutputStream>() {
+        @Override
+        protected ByteArrayOutputStream initialValue()
+        {
+            return new ByteArrayOutputStream();
+        }
+    };
+    private final ThreadLocal<ServletOutputStream> outputStream = new ThreadLocal<ServletOutputStream>() {
+        @Override
+        protected ServletOutputStream initialValue()
+        {
+            return new ServletOutputStream()
+            {
+                @Override
+                public void write(final int b) throws IOException
+                {
+                    outputStreamAsBytes.get().write(b);
+                }
+            };
+        }
+
+        @Override
+        public void remove()
+        {
+            super.remove();
+            outputStreamAsBytes.remove();
+        }
+    };
+
+    @Before
+    @After
+    public void cleanup() {
+        outputStream.remove();
+    }
+
+    @Test
+    public void testFilterNoOutput() throws ServletException, IOException
+    {
+        final Filter filter = initFilter();
+        final AtomicInteger counter = new AtomicInteger(0);
+        final FilterChain chain = new FilterChain()
+        {
+            @Override
+            public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException
+            {
+                counter.incrementAndGet();
+                response.getWriter().write("");
+            }
+        };
+        filter.doFilter(new HttpServletRequestWrapper(newProxy(HttpServletRequest.class)), new HttpServletResponseWrapper(newProxy(HttpServletResponse.class)), chain);
+        assertEquals(1, counter.get());
+        assertEquals("", new String(outputStreamAsBytes.get().toByteArray()));
+        outputStream.remove();
+        filter.doFilter(new HttpServletRequestWrapper(newProxy(HttpServletRequest.class)), new HttpServletResponseWrapper(newProxy(HttpServletResponse.class)), chain);
+        assertEquals(1, counter.get());
+        assertEquals("", new String(outputStreamAsBytes.get().toByteArray()));
+        filter.destroy();
+    }
+
+    @Test
+    public void testFilter() throws ServletException, IOException
+    {
+        final Filter filter = initFilter();
+        final AtomicInteger counter = new AtomicInteger(0);
+        final FilterChain chain = new FilterChain()
+        {
+            @Override
+            public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException
+            {
+                counter.incrementAndGet();
+                response.getWriter().write("Hello!");
+            }
+        };
+        filter.doFilter(new HttpServletRequestWrapper(newProxy(HttpServletRequest.class)), new HttpServletResponseWrapper(newProxy(HttpServletResponse.class)), chain);
+        assertEquals(1, counter.get());
+        assertEquals("Hello!", new String(outputStreamAsBytes.get().toByteArray()));
+        outputStream.remove();
+        filter.doFilter(new HttpServletRequestWrapper(newProxy(HttpServletRequest.class)), new HttpServletResponseWrapper(newProxy(HttpServletResponse.class)), chain);
+        assertEquals(1, counter.get());
+        assertEquals("Hello!", new String(outputStreamAsBytes.get().toByteArray()));
+        filter.destroy();
+    }
+
+    private JCacheFilter initFilter() throws ServletException
+    {
+        final JCacheFilter filter = new JCacheFilter();
+        filter.init(new FilterConfig()
+        {
+            @Override
+            public String getFilterName()
+            {
+                return null;
+            }
+
+            @Override
+            public ServletContext getServletContext()
+            {
+                return newProxy(ServletContext.class);
+            }
+
+            @Override
+            public String getInitParameter(String name)
+            {
+                return null;
+            }
+
+            @Override
+            public Enumeration<String> getInitParameterNames()
+            {
+                return Collections.emptyEnumeration();
+            }
+        });
+        return filter;
+    }
+
+    private <T> T newProxy(final Class<T> clazz)
+    {
+        return clazz.cast(Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class<?>[]{clazz}, new InvocationHandler()
+                        {
+                            @Override
+                            public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable
+                            {
+                                if (method.getReturnType().getName().equals("boolean"))
+                                {
+                                    return false;
+                                }
+                                if ("getCharacterEncoding".equals(method.getName()))
+                                {
+                                    return "UTF-8";
+                                }
+                                if ("getOutputStream".equals(method.getName()))
+                                {
+                                    return outputStream.get();
+                                }
+                                return null;
+                            }
+                        }
+                )
+        );
+    }
+}

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=1593628&r1=1593627&r2=1593628&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 Fri May  9 21:55:07 2014
@@ -23,7 +23,6 @@ import org.apache.commons.jcs.jcache.jmx
 import org.apache.commons.jcs.jcache.jmx.JMXs;
 import org.apache.commons.jcs.jcache.lang.Subsitutor;
 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;
@@ -63,8 +62,9 @@ import java.util.concurrent.ExecutorServ
 import java.util.concurrent.Executors;
 
 import static org.apache.commons.jcs.jcache.Asserts.assertNotNull;
+import static org.apache.commons.jcs.jcache.serialization.Serializations.copy;
 
-public class JCSCache<K extends Serializable, V extends Serializable, C extends CompleteConfiguration<K, V>> implements Cache<K, V>
+public class JCSCache<K, V, C extends CompleteConfiguration<K, V>> implements Cache<K, V>
 {
     private static final Subsitutor SUBSTITUTOR = Subsitutor.Helper.INSTANCE;
 
@@ -110,7 +110,7 @@ public class JCSCache<K extends Serializ
         final long evictionPause = Long.parseLong(properties.getProperty(cacheName + ".evictionPause", properties.getProperty("evictionPause", "30000")));
         if (evictionPause > 0)
         {
-            pool.submit(new EvictionThread<K, V>(this, evictionPause));
+            pool.submit(new EvictionThread<K>(this, evictionPause));
         }
 
         final Factory<CacheLoader<K, V>> cacheLoaderFactory = configuration.getCacheLoaderFactory();
@@ -227,7 +227,8 @@ public class JCSCache<K extends Serializ
     {
         if (config.isStoreByValue())
         {
-            delegate.put(new JCSKey<K>(Serializations.copy(manager.getClassLoader(), key.getKey())), elt);
+            final Serializable copy = copy(manager.getClassLoader(), Serializable.class.cast(key.getKey()));
+            delegate.put(new JCSKey<K>((K) copy), elt);
         }
     }
 
@@ -295,7 +296,7 @@ public class JCSCache<K extends Serializ
         final V old = oldElt != null ? oldElt.getElement() : null;
 
         final boolean storeByValue = config.isStoreByValue();
-        final V value = storeByValue ? Serializations.copy(manager.getClassLoader(), rawValue) : rawValue;
+        final V value = storeByValue ? (V) copy(manager.getClassLoader(), Serializable.class.cast(rawValue)) : rawValue;
 
         final boolean created = old == null;
         final JCSElement<V> element = new JCSElement<V>(value, created ? expiryPolicy.getExpiryForCreation()
@@ -310,7 +311,7 @@ public class JCSCache<K extends Serializ
         else
         {
             writer.write(new JCSEntry<K, V>(key, value));
-            final JCSKey<K> jcsKey = storeByValue ? new JCSKey<K>(Serializations.copy(manager.getClassLoader(), key)) : cacheKey;
+            final JCSKey<K> jcsKey = storeByValue ? new JCSKey<K>((K) copy(manager.getClassLoader(), Serializable.class.cast(key))) : cacheKey;
             jcsKey.access(start);
             delegate.put(jcsKey, element);
             for (final JCSListener<K, V> listener : listeners.values())
@@ -907,7 +908,7 @@ public class JCSCache<K extends Serializ
         JMXs.unregister(cacheStatsObjectName);
     }
 
-    private static class EvictionThread<K extends Serializable, V extends Serializable> implements Runnable
+    private static class EvictionThread<K> implements Runnable
     {
         private final long pause;
         private final JCSCache<K, ?, ?> cache;
@@ -959,7 +960,7 @@ public class JCSCache<K extends Serializ
             return;
         }
 
-        final ConcurrentMap<JCSKey<K>, ? extends JCSElement<? extends Serializable>> map = delegate;
+        final ConcurrentMap<JCSKey<K>, ? extends JCSElement<?>> map = delegate;
         try
         {
             final TreeSet<JCSKey<K>> treeSet = new TreeSet<JCSKey<K>>(new Comparator<JCSKey<K>>()
@@ -983,7 +984,7 @@ public class JCSCache<K extends Serializ
                 if (delete >= maxDelete) {
                     break;
                 }
-                final JCSElement<? extends Serializable> elt = map.get(key);
+                final JCSElement<?> elt = map.get(key);
                 if (elt != null) {
                     if (elt.isExpired())
                     {
@@ -1001,7 +1002,7 @@ public class JCSCache<K extends Serializ
                     if (delete >= maxDelete) {
                         break;
                     }
-                    final JCSElement<? extends Serializable> elt = map.get(key);
+                    final JCSElement<?> elt = map.get(key);
                     if (elt != null) {
                         map.remove(key);
                         statistics.increaseEvictions(1);

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=1593628&r1=1593627&r2=1593628&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 Fri May  9 21:55:07 2014
@@ -57,7 +57,7 @@ public class JCSCachingManager implement
         InputStream inStream = null;
         try
         {
-            if (JCSCachingProvider.DEFAULT_URI == uri || uri.toURL().getProtocol().equals("jcs"))
+            if (JCSCachingProvider.DEFAULT_URI.toString().equals(uri.toString()) || uri.toURL().getProtocol().equals("jcs"))
             {
                 inStream = loader.getResourceAsStream(uri.getPath());
             }

Modified: commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/JCSCachingProvider.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/JCSCachingProvider.java?rev=1593628&r1=1593627&r2=1593628&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/JCSCachingProvider.java (original)
+++ commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/JCSCachingProvider.java Fri May  9 21:55:07 2014
@@ -127,7 +127,7 @@ public class JCSCachingProvider implemen
     @Override
     public boolean isSupported(final OptionalFeature optionalFeature)
     {
-        return false;
+        return optionalFeature == OptionalFeature.STORE_BY_REFERENCE;
     }
 
     @Override

Modified: 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=1593628&r1=1593627&r2=1593628&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/JCSKey.java (original)
+++ commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/JCSKey.java Fri May  9 21:55:07 2014
@@ -20,7 +20,7 @@ package org.apache.commons.jcs.jcache;
 
 import java.io.Serializable;
 
-public class JCSKey<K extends Serializable> implements Serializable
+public class JCSKey<K> implements Serializable
 {
     private final K key;
     private volatile long lastAccess = 0;

Modified: commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/JCSListener.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/JCSListener.java?rev=1593628&r1=1593627&r2=1593628&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/JCSListener.java (original)
+++ commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/JCSListener.java Fri May  9 21:55:07 2014
@@ -29,11 +29,10 @@ import javax.cache.event.CacheEntryListe
 import javax.cache.event.CacheEntryRemovedListener;
 import javax.cache.event.CacheEntryUpdatedListener;
 import java.io.Closeable;
-import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
 
-public class JCSListener<K extends Serializable, V extends Serializable> implements Closeable
+public class JCSListener<K, V> implements Closeable
 {
     private final boolean oldValue;
     private final boolean synchronous;

Modified: commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/TempStateCacheView.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/TempStateCacheView.java?rev=1593628&r1=1593627&r2=1593628&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/TempStateCacheView.java (original)
+++ commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/TempStateCacheView.java Fri May  9 21:55:07 2014
@@ -27,7 +27,6 @@ import javax.cache.integration.Completio
 import javax.cache.processor.EntryProcessor;
 import javax.cache.processor.EntryProcessorException;
 import javax.cache.processor.EntryProcessorResult;
-import java.io.Serializable;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -39,7 +38,7 @@ import java.util.Set;
 import static org.apache.commons.jcs.jcache.Asserts.assertNotNull;
 
 // kind of transactional view for a Cache<K, V>, to use with EntryProcessor
-public class TempStateCacheView<K extends Serializable, V extends Serializable> implements Cache<K, V>
+public class TempStateCacheView<K, V> implements Cache<K, V>
 {
     private final JCSCache<K, V, ?> cache;
     private final Map<K, V> put = new HashMap<K, V>();
@@ -225,7 +224,7 @@ public class TempStateCacheView<K extend
         remove.addAll(keys);
         for (final K k : keys)
         {
-            put.remove(keys);
+            put.remove(k);
         }
     }
 

Modified: commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CacheResolverFactoryImpl.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CacheResolverFactoryImpl.java?rev=1593628&r1=1593627&r2=1593628&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CacheResolverFactoryImpl.java (original)
+++ commons/proper/jcs/trunk/commons-jcs-jcache/src/main/java/org/apache/commons/jcs/jcache/cdi/CacheResolverFactoryImpl.java Fri May  9 21:55:07 2014
@@ -68,7 +68,7 @@ public class CacheResolverFactoryImpl im
 
     private Cache<?, ?> createCache(final String exceptionCacheName)
     {
-        cacheManager.createCache(exceptionCacheName, new MutableConfiguration<Object, Object>());
+        cacheManager.createCache(exceptionCacheName, new MutableConfiguration<Object, Object>().setStoreByValue(false));
         return cacheManager.getCache(exceptionCacheName);
     }
 }