View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  package org.apache.http.impl.client.cache;
28  
29  import static org.junit.Assert.assertTrue;
30  
31  import java.io.ByteArrayInputStream;
32  import java.io.ByteArrayOutputStream;
33  import java.io.IOException;
34  import java.io.InputStream;
35  import java.nio.charset.Charset;
36  import java.util.Arrays;
37  import java.util.Date;
38  import java.util.HashMap;
39  import java.util.Map;
40  
41  import org.apache.commons.codec.binary.Base64;
42  import org.apache.http.Header;
43  import org.apache.http.ProtocolVersion;
44  import org.apache.http.StatusLine;
45  import org.apache.http.client.cache.HeaderConstants;
46  import org.apache.http.client.cache.HttpCacheEntry;
47  import org.apache.http.client.cache.HttpCacheEntrySerializer;
48  import org.apache.http.client.cache.Resource;
49  import org.apache.http.message.BasicHeader;
50  import org.apache.http.message.BasicStatusLine;
51  import org.junit.Before;
52  import org.junit.Test;
53  
54  public class TestHttpCacheEntrySerializers {
55  
56      private static final Charset UTF8 = Charset.forName("UTF-8");
57  
58      private HttpCacheEntrySerializer impl;
59  
60      @Before
61      public void setUp() {
62          impl = new DefaultHttpCacheEntrySerializer();
63      }
64  
65      @Test
66      public void canSerializeEntriesWithVariantMaps() throws Exception {
67          readWriteVerify(makeCacheEntryWithVariantMap());
68      }
69  
70      public void readWriteVerify(final HttpCacheEntry writeEntry) throws IOException {
71          // write the entry
72          final ByteArrayOutputStream out = new ByteArrayOutputStream();
73          impl.writeTo(writeEntry, out);
74  
75          // read the entry
76          final ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
77          final HttpCacheEntry readEntry = impl.readFrom(in);
78  
79          // compare
80          assertTrue(areEqual(readEntry, writeEntry));
81      }
82  
83      private HttpCacheEntry makeCacheEntryWithVariantMap() {
84          final Header[] headers = new Header[5];
85          for (int i = 0; i < headers.length; i++) {
86              headers[i] = new BasicHeader("header" + i, "value" + i);
87          }
88          final String body = "Lorem ipsum dolor sit amet";
89  
90          final ProtocolVersion pvObj = new ProtocolVersion("HTTP", 1, 1);
91          final StatusLine slObj = new BasicStatusLine(pvObj, 200, "ok");
92          final Map<String,String> variantMap = new HashMap<String,String>();
93          variantMap.put("test variant 1","true");
94          variantMap.put("test variant 2","true");
95          final HttpCacheEntry cacheEntry = new HttpCacheEntry(new Date(), new Date(),
96                  slObj, headers, new HeapResource(Base64.decodeBase64(body
97                          .getBytes(UTF8))), variantMap, HeaderConstants.GET_METHOD);
98  
99          return cacheEntry;
100     }
101 
102     private boolean areEqual(final HttpCacheEntry one, final HttpCacheEntry two) throws IOException {
103         // dates are only stored with second precision, so scrub milliseconds
104         if (!((one.getRequestDate().getTime() / 1000) == (two.getRequestDate()
105                 .getTime() / 1000))) {
106             return false;
107         }
108         if (!((one.getResponseDate().getTime() / 1000) == (two
109                 .getResponseDate().getTime() / 1000))) {
110             return false;
111         }
112         if (!one.getProtocolVersion().equals(two.getProtocolVersion())) {
113             return false;
114         }
115 
116         final byte[] onesByteArray = resourceToBytes(one.getResource());
117         final byte[] twosByteArray = resourceToBytes(two.getResource());
118 
119         if (!Arrays.equals(onesByteArray,twosByteArray)) {
120             return false;
121         }
122 
123         final Header[] oneHeaders = one.getAllHeaders();
124         final Header[] twoHeaders = two.getAllHeaders();
125         if (!(oneHeaders.length == twoHeaders.length)) {
126             return false;
127         }
128         for (int i = 0; i < oneHeaders.length; i++) {
129             if (!oneHeaders[i].getName().equals(twoHeaders[i].getName())) {
130                 return false;
131             }
132             if (!oneHeaders[i].getValue().equals(twoHeaders[i].getValue())) {
133                 return false;
134             }
135         }
136 
137         return true;
138     }
139 
140     private byte[] resourceToBytes(final Resource res) throws IOException {
141         final InputStream inputStream = res.getInputStream();
142         final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
143 
144         int readBytes;
145         final byte[] bytes = new byte[8096];
146         while ((readBytes = inputStream.read(bytes)) > 0) {
147             outputStream.write(bytes, 0, readBytes);
148         }
149 
150         final byte[] byteData = outputStream.toByteArray();
151 
152         inputStream.close();
153         outputStream.close();
154 
155         return byteData;
156     }
157 }