Jon et al

How about a slightly different take? No explicit locking is needed. The
callback stays but is made more generic allowing for all kinds of cache
mutations, not just variant updates.

Can you live with this change?

Oleg
Index: httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheInvalidator.java
===================================================================
--- httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheInvalidator.java	(revision 960337)
+++ httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheInvalidator.java	(working copy)
@@ -46,7 +46,7 @@
     private static final ProtocolVersion HTTP_1_1 = new ProtocolVersion("HTTP", 1, 1);
 
     private CacheInvalidator impl;
-    private HttpCache<CacheEntry> mockCache;
+    private HttpCache<String, CacheEntry> mockCache;
     private HttpHost host;
     private URIExtractor extractor;
     private CacheEntry mockEntry;
Index: httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestProtocolRequirements.java
===================================================================
--- httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestProtocolRequirements.java	(revision 963495)
+++ httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestProtocolRequirements.java	(working copy)
@@ -82,7 +82,7 @@
     private HttpEntity body;
     private HttpEntity mockEntity;
     private HttpClient mockBackend;
-    private HttpCache<CacheEntry> mockCache;
+    private HttpCache<String, CacheEntry> mockCache;
     private HttpRequest request;
     private HttpResponse originResponse;
 
@@ -99,7 +99,7 @@
 
         originResponse = make200Response();
 
-        HttpCache<CacheEntry> cache = new BasicHttpCache(MAX_ENTRIES);
+        HttpCache<String, CacheEntry> cache = new BasicHttpCache(MAX_ENTRIES);
         mockBackend = EasyMock.createMock(HttpClient.class);
         mockEntity = EasyMock.createMock(HttpEntity.class);
         mockCache = EasyMock.createMock(HttpCache.class);
Index: httpclient-cache/src/test/java/org/apache/http/impl/client/cache/DoNotTestProtocolRequirements.java
===================================================================
--- httpclient-cache/src/test/java/org/apache/http/impl/client/cache/DoNotTestProtocolRequirements.java	(revision 954656)
+++ httpclient-cache/src/test/java/org/apache/http/impl/client/cache/DoNotTestProtocolRequirements.java	(working copy)
@@ -62,7 +62,7 @@
     private HttpHost host;
     private HttpEntity mockEntity;
     private HttpClient mockBackend;
-    private HttpCache<CacheEntry> mockCache;
+    private HttpCache<String, CacheEntry> mockCache;
     private HttpRequest request;
     private HttpResponse originResponse;
 
@@ -77,7 +77,7 @@
 
         originResponse = make200Response();
 
-        HttpCache<CacheEntry> cache = new BasicHttpCache(MAX_ENTRIES);
+        HttpCache<String, CacheEntry> cache = new BasicHttpCache(MAX_ENTRIES);
         mockBackend = EasyMock.createMock(HttpClient.class);
         mockEntity = EasyMock.createMock(HttpEntity.class);
         mockCache = EasyMock.createMock(HttpCache.class);
Index: httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestResponseCache.java
===================================================================
--- httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestResponseCache.java	(revision 954656)
+++ httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestResponseCache.java	(working copy)
@@ -26,18 +26,11 @@
  */
 package org.apache.http.impl.client.cache;
 
-import org.apache.http.client.cache.HttpCacheOperationException;
-import org.apache.http.client.cache.HttpCacheUpdateCallback;
-import org.apache.http.entity.ByteArrayEntity;
 import org.easymock.classextension.EasyMock;
 import org.junit.Assert;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-
 public class TestResponseCache {
 
     private BasicHttpCache cache;
@@ -135,45 +128,4 @@
         Assert.assertNull("This cache should not have anything in it!", gone);
     }
 
-    @Test
-    @Ignore
-    public void testCacheEntryCallbackUpdatesCacheEntry() throws HttpCacheOperationException, IOException {
-
-        final byte[] expectedArray = new byte[] { 1, 2, 3, 4, 5 };
-
-        CacheEntry entry = EasyMock.createMock(CacheEntry.class);
-        CacheEntry entry2 = EasyMock.createMock(CacheEntry.class);
-
-        cache.putEntry("foo", entry);
-        cache.putEntry("bar", entry2);
-
-        cache.updateCacheEntry("foo", new HttpCacheUpdateCallback<CacheEntry>() {
-
-            public CacheEntry getUpdatedEntry(CacheEntry existing) {
-                CacheEntry updated = new CacheEntry(
-                        existing.getRequestDate(),
-                        existing.getRequestDate(),
-                        existing.getProtocolVersion(),
-                        existing.getAllHeaders(),
-                        new ByteArrayEntity(expectedArray),
-                        existing.getStatusCode(),
-                        existing.getReasonPhrase());
-                cache.removeEntry("bar");
-                return updated;
-            }
-        });
-
-        CacheEntry afterUpdate = cache.getEntry("foo");
-        CacheEntry bar = cache.getEntry("bar");
-
-        Assert.assertNull(bar);
-
-        byte[] bytes;
-        ByteArrayOutputStream stream = new ByteArrayOutputStream();
-        afterUpdate.getBody().writeTo(stream);
-        bytes = stream.toByteArray();
-
-        Assert.assertArrayEquals(expectedArray,bytes);
-    }
-
 }
Index: httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestDefaultCacheEntrySerializer.java
===================================================================
--- httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestDefaultCacheEntrySerializer.java	(revision 954656)
+++ httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestDefaultCacheEntrySerializer.java	(working copy)
@@ -1,123 +0,0 @@
-/*
- * ====================================================================
- * 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-package org.apache.http.impl.client.cache;
-
-import org.apache.http.Header;
-import org.apache.http.HttpVersion;
-import org.apache.http.ProtocolVersion;
-import org.apache.http.client.cache.HttpCacheEntrySerializer;
-import org.apache.http.message.BasicHeader;
-import org.apache.http.message.BasicHttpResponse;
-import org.junit.Assert;
-import org.junit.Test;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.util.Arrays;
-import java.util.Date;
-
-public class TestDefaultCacheEntrySerializer {
-
-    @Test
-    public void testSerialization() throws Exception {
-
-        HttpCacheEntrySerializer<CacheEntry> serializer = new DefaultCacheEntrySerializer();
-
-        // write the entry
-        CacheEntry writeEntry = newCacheEntry();
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        serializer.writeTo(writeEntry, out);
-
-        // read the entry
-        ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
-        CacheEntry readEntry = serializer.readFrom(in);
-
-        // compare
-        Assert.assertTrue(areEqual(readEntry, writeEntry));
-
-    }
-
-    private CacheEntry newCacheEntry() throws UnsupportedEncodingException {
-
-
-        Header[] headers = new Header[5];
-        for (int i = 0; i < headers.length; i++) {
-            headers[i] = new BasicHeader("header" + i, "value" + i);
-        }
-        ProtocolVersion version = new HttpVersion(1, 1);
-        String body = "Lorem ipsum dolor sit amet";
-        BasicHttpResponse response = new BasicHttpResponse(version, 200, "OK");
-
-        CacheEntry cacheEntry = new CacheEntry(new Date(), new Date(), version, headers,
-                new CacheEntity(body.getBytes("US-ASCII"), response), 200, "OK");
-
-        return cacheEntry;
-
-    }
-
-    private boolean areEqual(CacheEntry one, CacheEntry two) throws IOException {
-
-        if (!one.getRequestDate().equals(two.getRequestDate()))
-            return false;
-        if (!one.getResponseDate().equals(two.getResponseDate()))
-            return false;
-        if (!one.getProtocolVersion().equals(two.getProtocolVersion()))
-            return false;
-
-        byte[] bytesOne, bytesTwo;
-
-        ByteArrayOutputStream streamOne = new ByteArrayOutputStream();
-        one.getBody().writeTo(streamOne);
-        bytesOne = streamOne.toByteArray();
-
-        ByteArrayOutputStream streamTwo = new ByteArrayOutputStream();
-
-        two.getBody().writeTo(streamTwo);
-        bytesTwo = streamTwo.toByteArray();
-
-
-        if (!Arrays.equals(bytesOne, bytesTwo))
-            return false;
-
-        Header[] oneHeaders = one.getAllHeaders();
-        Header[] twoHeaders = one.getAllHeaders();
-        if (!(oneHeaders.length == twoHeaders.length))
-            return false;
-        for (int i = 0; i < oneHeaders.length; i++) {
-            if (!oneHeaders[i].getName().equals(twoHeaders[i].getName()))
-                return false;
-            if (!oneHeaders[i].getValue().equals(twoHeaders[i].getValue()))
-                return false;
-        }
-
-        return true;
-
-    }
-
-}
Index: httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestProtocolDeviations.java
===================================================================
--- httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestProtocolDeviations.java	(revision 954656)
+++ httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestProtocolDeviations.java	(working copy)
@@ -77,7 +77,7 @@
     private HttpEntity body;
     private HttpEntity mockEntity;
     private HttpClient mockBackend;
-    private HttpCache<CacheEntry> mockCache;
+    private HttpCache<String, CacheEntry> mockCache;
     private HttpRequest request;
     private HttpResponse originResponse;
 
@@ -94,7 +94,7 @@
 
         originResponse = make200Response();
 
-        HttpCache<CacheEntry> cache = new BasicHttpCache(MAX_ENTRIES);
+        HttpCache<String, CacheEntry> cache = new BasicHttpCache(MAX_ENTRIES);
         mockBackend = EasyMock.createMock(HttpClient.class);
         mockEntity = EasyMock.createMock(HttpEntity.class);
         mockCache = EasyMock.createMock(HttpCache.class);
Index: httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingHttpClient.java
===================================================================
--- httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingHttpClient.java	(revision 961424)
+++ httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingHttpClient.java	(working copy)
@@ -26,8 +26,6 @@
  */
 package org.apache.http.impl.client.cache;
 
-import static junit.framework.Assert.assertTrue;
-
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -60,6 +58,7 @@
 import org.apache.http.entity.ByteArrayEntity;
 import org.apache.http.impl.client.DefaultHttpClient;
 import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
+import org.apache.http.message.BasicHeader;
 import org.apache.http.message.BasicHttpResponse;
 import org.apache.http.message.BasicStatusLine;
 import org.apache.http.params.HttpParams;
@@ -93,7 +92,7 @@
     private CacheInvalidator mockInvalidator;
     private CacheableRequestPolicy mockRequestPolicy;
     private HttpClient mockBackend;
-    private HttpCache<CacheEntry> mockCache;
+    private HttpCache<String, CacheEntry> cache;
     private CachedResponseSuitabilityChecker mockSuitabilityChecker;
     private ResponseCachingPolicy mockResponsePolicy;
     private HttpRequest mockRequest;
@@ -134,10 +133,10 @@
     @Before
     public void setUp() {
 
+        cache = new BasicHttpCache(10);
         mockInvalidator = EasyMock.createMock(CacheInvalidator.class);
         mockRequestPolicy = EasyMock.createMock(CacheableRequestPolicy.class);
         mockBackend = EasyMock.createMock(HttpClient.class);
-        mockCache = EasyMock.createMock(HttpCache.class);
         mockSuitabilityChecker = EasyMock.createMock(CachedResponseSuitabilityChecker.class);
         mockResponsePolicy = EasyMock.createMock(ResponseCachingPolicy.class);
         mockConnectionManager = EasyMock.createMock(ClientConnectionManager.class);
@@ -169,7 +168,7 @@
         responseDate = new Date();
         host = new HttpHost("foo.example.com");
         impl = new CachingHttpClient(mockBackend, mockResponsePolicy, mockEntryGenerator,
-                                     mockExtractor, mockCache, mockResponseGenerator, mockInvalidator,
+                                     mockExtractor, cache, mockResponseGenerator, mockInvalidator,
                                      mockRequestPolicy, mockSuitabilityChecker, mockConditionalRequestBuilder,
                                      mockCacheEntryUpdater, mockResponseProtocolCompliance,
                                      mockRequestProtocolCompliance);
@@ -187,7 +186,6 @@
         EasyMock.replay(mockResponseGenerator);
         EasyMock.replay(mockExtractor);
         EasyMock.replay(mockBackend);
-        EasyMock.replay(mockCache);
         EasyMock.replay(mockConnectionManager);
         EasyMock.replay(mockContext);
         EasyMock.replay(mockHandler);
@@ -221,7 +219,6 @@
         EasyMock.verify(mockResponseGenerator);
         EasyMock.verify(mockExtractor);
         EasyMock.verify(mockBackend);
-        EasyMock.verify(mockCache);
         EasyMock.verify(mockConnectionManager);
         EasyMock.verify(mockContext);
         EasyMock.verify(mockHandler);
@@ -317,22 +314,27 @@
 
     @Test
     public void testCacheUpdateAddsVariantURIToParentEntry() throws Exception {
-
-        final String variantURI = "variantURI";
-
         final CacheEntry entry = new CacheEntry(new Date(), new Date(), HTTP_1_1,
-                new Header[] {}, new ByteArrayEntity(new byte[] {}), 200, "OK");
+                new Header[] { new BasicHeader("Vary", "Accept-Encoding")},
+                new ByteArrayEntity(new byte[] {}), 200, "OK");
 
-        extractVariantURI(variantURI, entry);
-        putInCache(variantURI, entry);
+        Assert.assertTrue(entry.hasVariants());
 
+        extractTheURI("this");
+        extractVariantURI("that", entry);
+
         replayMocks();
 
-        CacheEntry updatedEntry = impl.doGetUpdatedParentEntry(null, host, mockRequest, entry);
+        impl.storeInCache(host, mockRequest, entry);
 
         verifyMocks();
 
-        assertTrue(updatedEntry.getVariantURIs().contains(variantURI));
+        Assert.assertEquals(2, cache.size());
+        CacheEntry parent = cache.getEntry("this");
+        CacheEntry child = cache.getEntry("that");
+        Assert.assertNotNull(parent);
+        Assert.assertNotNull(child);
+        Assert.assertTrue(parent.getVariantURIs().contains("that"));
     }
 
 
@@ -518,7 +520,6 @@
 
         final String theURI = "theURI";
         extractTheURI(theURI);
-        gotCacheMiss(theURI);
 
         replayMocks();
         CacheEntry result = impl.getCacheEntry(host, mockRequest);
@@ -531,7 +532,7 @@
 
         final String theURI = "theURI";
         extractTheURI(theURI);
-        gotCacheHit(theURI);
+        cache.putEntry(theURI, mockCacheEntry);
         cacheEntryHasVariants(false);
 
         replayMocks();
@@ -546,10 +547,9 @@
         final String theURI = "theURI";
         final String variantURI = "variantURI";
         extractTheURI(theURI);
-        gotCacheHit(theURI);
+        cache.putEntry(theURI, mockCacheEntry);
         cacheEntryHasVariants(true);
         extractVariantURI(variantURI);
-        gotCacheMiss(variantURI);
 
         replayMocks();
         CacheEntry result = impl.getCacheEntry(host, mockRequest);
@@ -563,10 +563,10 @@
         final String theURI = "theURI";
         final String variantURI = "variantURI";
         extractTheURI(theURI);
-        gotCacheHit(theURI, mockCacheEntry);
+        cache.putEntry(theURI, mockCacheEntry);
         cacheEntryHasVariants(true);
         extractVariantURI(variantURI);
-        gotCacheHit(variantURI, mockVariantCacheEntry);
+        cache.putEntry(variantURI, mockVariantCacheEntry);
 
         replayMocks();
         CacheEntry result = impl.getCacheEntry(host, mockRequest);
@@ -628,7 +628,7 @@
         final HttpRequest theRequest = mockRequest;
         final HttpResponse theResponse = mockBackendResponse;
         impl = new CachingHttpClient(mockBackend, mockResponsePolicy, mockEntryGenerator,
-                                     mockExtractor, mockCache, mockResponseGenerator, mockInvalidator,
+                                     mockExtractor, cache, mockResponseGenerator, mockInvalidator,
                                      mockRequestPolicy, mockSuitabilityChecker, mockConditionalRequestBuilder,
                                      mockCacheEntryUpdater, mockResponseProtocolCompliance,
                                      mockRequestProtocolCompliance) {
@@ -660,7 +660,7 @@
         final ResponseHandler<Object> theHandler = mockHandler;
         final Object value = new Object();
         impl = new CachingHttpClient(mockBackend, mockResponsePolicy, mockEntryGenerator,
-                                     mockExtractor, mockCache, mockResponseGenerator, mockInvalidator,
+                                     mockExtractor, cache, mockResponseGenerator, mockInvalidator,
                                      mockRequestPolicy, mockSuitabilityChecker, mockConditionalRequestBuilder,
                                      mockCacheEntryUpdater, mockResponseProtocolCompliance,
                                      mockRequestProtocolCompliance) {
@@ -700,7 +700,7 @@
         final HttpResponse theResponse = mockBackendResponse;
         final HttpContext theContext = mockContext;
         impl = new CachingHttpClient(mockBackend, mockResponsePolicy, mockEntryGenerator,
-                                     mockExtractor, mockCache, mockResponseGenerator, mockInvalidator,
+                                     mockExtractor, cache, mockResponseGenerator, mockInvalidator,
                                      mockRequestPolicy, mockSuitabilityChecker, mockConditionalRequestBuilder,
                                      mockCacheEntryUpdater, mockResponseProtocolCompliance,
                                      mockRequestProtocolCompliance) {
@@ -732,7 +732,7 @@
         final HttpUriRequest theRequest = mockUriRequest;
         final HttpResponse theResponse = mockBackendResponse;
         impl = new CachingHttpClient(mockBackend, mockResponsePolicy, mockEntryGenerator,
-                                     mockExtractor, mockCache, mockResponseGenerator, mockInvalidator,
+                                     mockExtractor, cache, mockResponseGenerator, mockInvalidator,
                                      mockRequestPolicy, mockSuitabilityChecker, mockConditionalRequestBuilder,
                                      mockCacheEntryUpdater, mockResponseProtocolCompliance,
                                      mockRequestProtocolCompliance) {
@@ -762,7 +762,7 @@
         final HttpContext theContext = mockContext;
         final HttpResponse theResponse = mockBackendResponse;
         impl = new CachingHttpClient(mockBackend, mockResponsePolicy, mockEntryGenerator,
-                                     mockExtractor, mockCache, mockResponseGenerator, mockInvalidator,
+                                     mockExtractor, cache, mockResponseGenerator, mockInvalidator,
                                      mockRequestPolicy, mockSuitabilityChecker, mockConditionalRequestBuilder,
                                      mockCacheEntryUpdater, mockResponseProtocolCompliance,
                                      mockRequestProtocolCompliance) {
@@ -795,7 +795,7 @@
         final HttpResponse theResponse = mockBackendResponse;
         final Object theValue = new Object();
         impl = new CachingHttpClient(mockBackend, mockResponsePolicy, mockEntryGenerator,
-                                     mockExtractor, mockCache, mockResponseGenerator, mockInvalidator,
+                                     mockExtractor, cache, mockResponseGenerator, mockInvalidator,
                                      mockRequestPolicy, mockSuitabilityChecker, mockConditionalRequestBuilder,
                                      mockCacheEntryUpdater, mockResponseProtocolCompliance,
                                      mockRequestProtocolCompliance) {
@@ -830,7 +830,7 @@
         final HttpResponse theResponse = mockBackendResponse;
         final Object theValue = new Object();
         impl = new CachingHttpClient(mockBackend, mockResponsePolicy, mockEntryGenerator,
-                                     mockExtractor, mockCache, mockResponseGenerator, mockInvalidator,
+                                     mockExtractor, cache, mockResponseGenerator, mockInvalidator,
                                      mockRequestPolicy, mockSuitabilityChecker, mockConditionalRequestBuilder,
                                      mockCacheEntryUpdater, mockResponseProtocolCompliance,
                                      mockRequestProtocolCompliance) {
@@ -884,7 +884,7 @@
         ClientConnectionManager cm = new ThreadSafeClientConnManager(schemeRegistry);
         HttpClient httpClient = new DefaultHttpClient(cm);
 
-        HttpCache<CacheEntry> cacheImpl = new BasicHttpCache(100);
+        HttpCache<String, CacheEntry> cacheImpl = new BasicHttpCache(100);
 
         CachingHttpClient cachingClient = new CachingHttpClient(httpClient, cacheImpl, 8192);
 
@@ -913,7 +913,7 @@
         requestPolicyAllowsCaching(true);
         cacheEntrySuitable(true);
         extractTheURI(theURI);
-        gotCacheHit(theURI);
+        cache.putEntry(theURI, mockCacheEntry);
         responseIsGeneratedFromCache();
         cacheEntryHasVariants(false);
 
@@ -1121,7 +1121,7 @@
     }
 
     private void removeFromCache(String theURI) throws Exception {
-        mockCache.removeEntry(theURI);
+        cache.removeEntry(theURI);
     }
 
     private void requestPolicyAllowsCaching(boolean allow) {
@@ -1160,24 +1160,12 @@
                 .andReturn(allow);
     }
 
-    private void gotCacheMiss(String theURI) throws Exception {
-        org.easymock.EasyMock.expect(mockCache.getEntry(theURI)).andReturn(null);
-    }
-
     private void cacheEntrySuitable(boolean suitable) {
         org.easymock.EasyMock.expect(
                 mockSuitabilityChecker.canCachedResponseBeUsed(host, mockRequest, mockCacheEntry))
                 .andReturn(suitable);
     }
 
-    private void gotCacheHit(String theURI) throws Exception {
-        org.easymock.EasyMock.expect(mockCache.getEntry(theURI)).andReturn(mockCacheEntry);
-    }
-
-    private void gotCacheHit(String theURI, CacheEntry entry) throws Exception {
-        org.easymock.EasyMock.expect(mockCache.getEntry(theURI)).andReturn(entry);
-    }
-
     private void cacheEntryHasVariants(boolean b) {
         org.easymock.EasyMock.expect(mockCacheEntry.hasVariants()).andReturn(b);
     }
@@ -1217,11 +1205,11 @@
     }
 
     private void putInCache(String theURI) throws Exception {
-        mockCache.putEntry(theURI, mockCacheEntry);
+        cache.putEntry(theURI, mockCacheEntry);
     }
 
     private void putInCache(String theURI, CacheEntry entry) throws Exception {
-        mockCache.putEntry(theURI, entry);
+        cache.putEntry(theURI, entry);
     }
 
     private void generateCacheEntry(Date requestDate, Date responseDate, byte[] bytes) {
@@ -1264,7 +1252,7 @@
     private void mockImplMethods(String... methods) {
         mockedImpl = true;
         impl = EasyMock.createMockBuilder(CachingHttpClient.class).withConstructor(mockBackend,
-                                                                                   mockResponsePolicy, mockEntryGenerator, mockExtractor, mockCache,
+                                                                                   mockResponsePolicy, mockEntryGenerator, mockExtractor, cache,
                                                                                    mockResponseGenerator, mockInvalidator, mockRequestPolicy, mockSuitabilityChecker,
                                                                                    mockConditionalRequestBuilder, mockCacheEntryUpdater,
                                                                                    mockResponseProtocolCompliance, mockRequestProtocolCompliance).addMockedMethods(
Index: httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CacheInvalidator.java
===================================================================
--- httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CacheInvalidator.java	(revision 960337)
+++ httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CacheInvalidator.java	(working copy)
@@ -48,7 +48,7 @@
 @ThreadSafe // so long as the cache implementation is thread-safe
 public class CacheInvalidator {
 
-    private final HttpCache<CacheEntry> cache;
+    private final HttpCache<String, CacheEntry> cache;
     private final URIExtractor uriExtractor;
 
     private final Log log = LogFactory.getLog(getClass());
@@ -60,7 +60,7 @@
      * @param uriExtractor Provides identifiers for the keys to store cache entries
      * @param cache the cache to store items away in
      */
-    public CacheInvalidator(URIExtractor uriExtractor, HttpCache<CacheEntry> cache) {
+    public CacheInvalidator(URIExtractor uriExtractor, HttpCache<String, CacheEntry> cache) {
         this.uriExtractor = uriExtractor;
         this.cache = cache;
     }
Index: httpclient-cache/src/main/java/org/apache/http/impl/client/cache/BasicHttpCache.java
===================================================================
--- httpclient-cache/src/main/java/org/apache/http/impl/client/cache/BasicHttpCache.java	(revision 954656)
+++ httpclient-cache/src/main/java/org/apache/http/impl/client/cache/BasicHttpCache.java	(working copy)
@@ -26,7 +26,6 @@
  */
 package org.apache.http.impl.client.cache;
 
-import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.Map;
 
@@ -41,7 +40,7 @@
  * @since 4.1
  */
 @ThreadSafe
-public class BasicHttpCache implements HttpCache<CacheEntry> {
+public class BasicHttpCache implements HttpCache<String, CacheEntry> {
 
     private final LinkedHashMap<String, CacheEntry> baseMap = new LinkedHashMap<String, CacheEntry>(20,
             0.75f, true) {
@@ -54,13 +53,10 @@
         }
     };
 
-    private final Map<String, CacheEntry> syncMap;
-
     private final int maxEntries;
 
     public BasicHttpCache(int maxEntries) {
         this.maxEntries = maxEntries;
-        syncMap = Collections.synchronizedMap(baseMap);
     }
 
     /**
@@ -71,8 +67,8 @@
      * @param entry
      *            CacheEntry to place in the cache
      */
-    public void putEntry(String url, CacheEntry entry) {
-        syncMap.put(url, entry);
+    public synchronized void putEntry(String url, CacheEntry entry) {
+        baseMap.put(url, entry);
     }
 
     /**
@@ -82,8 +78,8 @@
      *            Url that is the cache key
      * @return CacheEntry if one exists, or null for cache miss
      */
-    public CacheEntry getEntry(String url) {
-        return syncMap.get(url);
+    public synchronized CacheEntry getEntry(String url) {
+        return baseMap.get(url);
     }
 
     /**
@@ -92,15 +88,17 @@
      * @param url
      *            Url that is the cache key
      */
-    public void removeEntry(String url) {
-        syncMap.remove(url);
+    public synchronized void removeEntry(String url) {
+        baseMap.remove(url);
     }
 
-    public synchronized void updateCacheEntry(
-            String url,
-            HttpCacheUpdateCallback<CacheEntry> callback) throws HttpCacheOperationException {
-        CacheEntry existingEntry = syncMap.get(url);
-        CacheEntry updated = callback.getUpdatedEntry(existingEntry);
-        syncMap.put(url, updated);
+    public synchronized int size() {
+        return baseMap.size();
     }
+
+    public synchronized void update(
+            HttpCacheUpdateCallback<String, CacheEntry> callback) throws HttpCacheOperationException {
+        callback.execute(this);
+    }
+
 }
Index: httpclient-cache/src/main/java/org/apache/http/impl/client/cache/DefaultCacheEntrySerializer.java
===================================================================
--- httpclient-cache/src/main/java/org/apache/http/impl/client/cache/DefaultCacheEntrySerializer.java	(revision 954656)
+++ httpclient-cache/src/main/java/org/apache/http/impl/client/cache/DefaultCacheEntrySerializer.java	(working copy)
@@ -1,129 +0,0 @@
-/*
- * ====================================================================
- * 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-package org.apache.http.impl.client.cache;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.OutputStream;
-
-import org.apache.http.annotation.Immutable;
-import org.apache.http.client.cache.HttpCacheEntrySerializer;
-
-/**
- * {...@link HttpCacheEntrySerializer} implementation that uses the default (native)
- * serialization.
- *
- * @see java.io.Serializable
- *
- * @since 4.1
- */
-...@immutable
-public class DefaultCacheEntrySerializer implements HttpCacheEntrySerializer<CacheEntry> {
-
-    /**
-     * Write a {...@link CacheEntry} to an {...@link OutputStream}.
-     *
-     * @param cacheEntry the entry to write
-     * @param os the output stream to write to
-     * @throws IOException if problems occur writing the entry
-     */
-    public void writeTo(CacheEntry cacheEntry, OutputStream os) throws IOException {
-
-        ObjectOutputStream oos = null;
-        try {
-            oos = new ObjectOutputStream(os);
-            // write CacheEntry
-            oos.writeObject(cacheEntry);
-            // write headers as a String [][]
-            // Header [] headers = cacheEntry.getAllHeaders();
-            // if(null == headers || headers.length < 1) return;
-            // String [][] sheaders = new String[headers.length][2];
-            // for(int i=0; i < headers.length; i++) {
-            // sheaders[i][0] = headers[i].getName();
-            // sheaders[i][1] = headers[i].getValue();
-            // }
-            // oos.writeObject(sheaders);
-        } finally {
-            try {
-                if (oos != null) {
-                    oos.close();
-                }
-            } catch (Exception ignore) {
-            }
-            try {
-                os.close();
-            } catch (Exception ignore) {
-            }
-        }
-
-    }
-
-    /**
-     * Read a {...@link CacheEntry} from an {...@link InputStream}
-     *
-     * @param is the input stream to read from
-     * @return the cache entry
-     * @throws IOException
-     */
-    public CacheEntry readFrom(InputStream is) throws IOException {
-
-        ObjectInputStream ois = null;
-        try {
-            ois = new ObjectInputStream(is);
-            // read CacheEntry
-            CacheEntry cacheEntry = (CacheEntry) ois.readObject();
-            // read headers as a String [][]
-            // String [][] sheaders = (String[][])ois.readObject();
-            // if(null == sheaders || sheaders.length < 1) return cacheEntry;
-            // BasicHeader [] headers = new BasicHeader[sheaders.length];
-            // for(int i=0; i < sheaders.length; i++) {
-            // String [] sheader = sheaders[i];
-            // headers[i] = new BasicHeader(sheader[0], sheader[1]);
-            // }
-            // cacheEntry.setResponseHeaders(headers);
-            return cacheEntry;
-        } catch (ClassNotFoundException cnfe) {
-            // CacheEntry should be known, it not we have a runtime issue
-            throw new RuntimeException(cnfe);
-        } finally {
-            try {
-                if (ois != null) {
-                    ois.close();
-                }
-            } catch (Exception ignore) {
-            }
-            try {
-                is.close();
-            } catch (Exception ignore) {
-            }
-        }
-
-    }
-
-}
Index: httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingHttpClient.java
===================================================================
--- httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingHttpClient.java	(revision 961424)
+++ httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingHttpClient.java	(working copy)
@@ -48,6 +48,7 @@
 import org.apache.http.client.HttpClient;
 import org.apache.http.client.ResponseHandler;
 import org.apache.http.client.cache.HttpCache;
+import org.apache.http.client.cache.HttpCacheMap;
 import org.apache.http.client.cache.HttpCacheOperationException;
 import org.apache.http.client.cache.HttpCacheUpdateCallback;
 import org.apache.http.client.methods.HttpUriRequest;
@@ -76,7 +77,7 @@
     private final ResponseCachingPolicy responseCachingPolicy;
     private final CacheEntryGenerator cacheEntryGenerator;
     private final URIExtractor uriExtractor;
-    private final HttpCache<CacheEntry> responseCache;
+    private final HttpCache<String, CacheEntry> responseCache;
     private final CachedHttpResponseGenerator responseGenerator;
     private final CacheInvalidator cacheInvalidator;
     private final CacheableRequestPolicy cacheableRequestPolicy;
@@ -112,7 +113,7 @@
         this.requestCompliance = new RequestProtocolCompliance();
     }
 
-    public CachingHttpClient(HttpCache<CacheEntry> cache, int maxObjectSizeBytes) {
+    public CachingHttpClient(HttpCache<String, CacheEntry> cache, int maxObjectSizeBytes) {
         this.responseCache = cache;
 
         this.backend = new DefaultHttpClient();
@@ -130,7 +131,7 @@
         this.requestCompliance = new RequestProtocolCompliance();
     }
 
-    public CachingHttpClient(HttpClient client, HttpCache<CacheEntry> cache, int maxObjectSizeBytes) {
+    public CachingHttpClient(HttpClient client, HttpCache<String, CacheEntry> cache, int maxObjectSizeBytes) {
         this.responseCache = cache;
 
         this.backend = client;
@@ -150,7 +151,7 @@
 
     public CachingHttpClient(HttpClient backend, ResponseCachingPolicy responseCachingPolicy,
                              CacheEntryGenerator cacheEntryGenerator, URIExtractor uriExtractor,
-                             HttpCache<CacheEntry> responseCache, CachedHttpResponseGenerator responseGenerator,
+                             HttpCache<String, CacheEntry> responseCache, CachedHttpResponseGenerator responseGenerator,
                              CacheInvalidator cacheInvalidator, CacheableRequestPolicy cacheableRequestPolicy,
                              CachedResponseSuitabilityChecker suitabilityChecker,
                              ConditionalRequestBuilder conditionalRequestBuilder, CacheEntryUpdater entryUpdater,
@@ -487,57 +488,45 @@
     }
 
     protected void storeInCache(HttpHost target, HttpRequest request, CacheEntry entry) {
-        if (entry.hasVariants()) {
-            try {
-                String uri = uriExtractor.getURI(target, request);
-                HttpCacheUpdateCallback<CacheEntry> callback = storeVariantEntry(
-                        target, request, entry);
-                responseCache.updateCacheEntry(uri, callback);
-            } catch (HttpCacheOperationException ex) {
-                log.debug("Was unable to PUT/UPDATE an entry into the cache based on the uri provided",
-                        ex);
+        try {
+            if (entry.hasVariants()) {
+                storeVariantEntry(target, request, entry);
+            } else {
+                storeNonVariantEntry(target, request, entry);
             }
-        } else {
-            storeNonVariantEntry(target, request, entry);
+        } catch (HttpCacheOperationException ex) {
+            log.debug("Was unable to put/update an entry into the cache based on the uri provided", ex);
         }
     }
 
-    private void storeNonVariantEntry(HttpHost target, HttpRequest req, CacheEntry entry) {
+    private void storeNonVariantEntry(
+            final HttpHost target,
+            final HttpRequest req,
+            final CacheEntry entry) throws HttpCacheOperationException {
         String uri = uriExtractor.getURI(target, req);
-        try {
-            responseCache.putEntry(uri, entry);
-        } catch (HttpCacheOperationException ex) {
-            log.debug("Was unable to PUT an entry into the cache based on the uri provided", ex);
-        }
+        responseCache.putEntry(uri, entry);
     }
 
-    protected HttpCacheUpdateCallback<CacheEntry> storeVariantEntry(
+    private void storeVariantEntry(
             final HttpHost target,
             final HttpRequest req,
-            final CacheEntry entry) {
+            final CacheEntry entry) throws HttpCacheOperationException {
+        responseCache.update(new  HttpCacheUpdateCallback<String, CacheEntry>() {
 
-        return new HttpCacheUpdateCallback<CacheEntry>() {
-            public CacheEntry getUpdatedEntry(CacheEntry existing) throws HttpCacheOperationException {
-
-                return doGetUpdatedParentEntry(existing, target, req, entry);
+            public void execute(
+                    final HttpCacheMap<String, CacheEntry> cache) throws HttpCacheOperationException {
+                String uri = uriExtractor.getURI(target, req);
+                String variantURI = uriExtractor.getVariantURI(target, req, entry);
+                cache.putEntry(variantURI, entry);
+                CacheEntry existing = cache.getEntry(uri);
+                if (existing == null) {
+                    existing = entry;
+                }
+                CacheEntry updated = existing.addVariantURI(variantURI);
+                cache.putEntry(uri, updated);
             }
-        };
-    }
 
-    protected CacheEntry doGetUpdatedParentEntry(
-            CacheEntry existing,
-            HttpHost target,
-            HttpRequest req,
-            CacheEntry entry) throws HttpCacheOperationException {
-
-        String variantURI = uriExtractor.getVariantURI(target, req, entry);
-        responseCache.putEntry(variantURI, entry);
-
-        if (existing != null) {
-            return existing.addVariantURI(variantURI);
-        } else {
-            return entry.addVariantURI(variantURI);
-        }
+        });
     }
 
     protected HttpResponse correctIncompleteResponse(HttpResponse resp,
Index: httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheEntrySerializer.java
===================================================================
--- httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheEntrySerializer.java	(revision 954656)
+++ httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheEntrySerializer.java	(working copy)
@@ -1,44 +0,0 @@
-/*
- * ====================================================================
- * 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-package org.apache.http.client.cache;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-/**
- * Common operations for cache entry serialization and deserialization.
- *
- * @since 4.1
- */
-public interface HttpCacheEntrySerializer<E> {
-
-    public void writeTo(E entry, OutputStream os) throws IOException;
-
-    public E readFrom(InputStream is) throws IOException;
-
-}
\ No newline at end of file
Index: httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheMap.java
===================================================================
--- httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheMap.java	(revision 0)
+++ httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheMap.java	(revision 0)
@@ -0,0 +1,42 @@
+/*
+ * ====================================================================
+ * 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.http.client.cache;
+
+/**
+ * @since 4.1
+ */
+public interface HttpCacheMap<K, E> {
+
+    void putEntry(K key, E entry) throws HttpCacheOperationException;
+
+    E getEntry(K key) throws HttpCacheOperationException;
+
+    void removeEntry(K key) throws HttpCacheOperationException;
+
+    int size();
+
+}
Index: httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCache.java
===================================================================
--- httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCache.java	(revision 954656)
+++ httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCache.java	(working copy)
@@ -29,15 +29,8 @@
 /**
  * @since 4.1
  */
-public interface HttpCache<E> {
+public interface HttpCache<K, E> extends HttpCacheMap<K, E> {
 
-    void putEntry(String url, E entry) throws HttpCacheOperationException;
+    void update(HttpCacheUpdateCallback<K, E> callback) throws HttpCacheOperationException;
 
-    E getEntry(String url) throws HttpCacheOperationException;
-
-    void removeEntry(String url) throws HttpCacheOperationException;
-
-    void updateCacheEntry(
-            String url, HttpCacheUpdateCallback<E> callback) throws HttpCacheOperationException;
-
 }
Index: httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheUpdateCallback.java
===================================================================
--- httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheUpdateCallback.java	(revision 954656)
+++ httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheUpdateCallback.java	(working copy)
@@ -26,21 +26,8 @@
  */
 package org.apache.http.client.cache;
 
-public interface HttpCacheUpdateCallback<E> {
+public interface HttpCacheUpdateCallback<K, E> {
 
-    /**
-     * Returns the new cache entry that should replace an existing one.
-     *
-     * @param existing
-     *            the cache entry current in-place in the cache, possibly
-     *            <code>null</code> if nonexistent
-     * @return CacheEntry the cache entry that should replace it, again,
-     *         possible <code>null</code>
-     * @throws HttpCacheOperationException
-     *             exception containing information about a failure in the cache
-     *
-     * @since 4.1
-     */
-    E getUpdatedEntry(E existing) throws HttpCacheOperationException;
+    void execute(HttpCacheMap<K, E> cache) throws HttpCacheOperationException;
 
 }
\ No newline at end of file

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@hc.apache.org
For additional commands, e-mail: dev-h...@hc.apache.org

Reply via email to