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.client.cache;
28  
29  import java.io.Serializable;
30  import java.util.Collections;
31  import java.util.Date;
32  import java.util.HashMap;
33  import java.util.Map;
34  
35  import org.apache.http.Header;
36  import org.apache.http.ProtocolVersion;
37  import org.apache.http.StatusLine;
38  import org.apache.http.annotation.Immutable;
39  import org.apache.http.client.utils.DateUtils;
40  import org.apache.http.message.HeaderGroup;
41  import org.apache.http.protocol.HTTP;
42  import org.apache.http.util.Args;
43  
44  /**
45   * Structure used to store an {@link org.apache.http.HttpResponse} in a cache.
46   * Some entries can optionally depend on system resources that may require
47   * explicit deallocation. In such a case {@link #getResource()} should return
48   * a non null instance of {@link Resource} that must be deallocated by calling
49   * {@link Resource#dispose()} method when no longer used.
50   *
51   * @since 4.1
52   */
53  @Immutable
54  public class HttpCacheEntry implements Serializable {
55  
56      private static final long serialVersionUID = -6300496422359477413L;
57  
58      private final Date requestDate;
59      private final Date responseDate;
60      private final StatusLine statusLine;
61      private final HeaderGroup responseHeaders;
62      private final Resource resource;
63      private final Map<String,String> variantMap;
64      private final Date date;
65  
66      /**
67       * Create a new {@link HttpCacheEntry} with variants.
68       * @param requestDate
69       *          Date/time when the request was made (Used for age
70       *            calculations)
71       * @param responseDate
72       *          Date/time that the response came back (Used for age
73       *            calculations)
74       * @param statusLine
75       *          HTTP status line from origin response
76       * @param responseHeaders
77       *          Header[] from original HTTP Response
78       * @param resource representing origin response body
79       * @param variantMap describing cache entries that are variants
80       *   of this parent entry; this maps a "variant key" (derived
81       *   from the varying request headers) to a "cache key" (where
82       *   in the cache storage the particular variant is located)
83       */
84      public HttpCacheEntry(
85              final Date requestDate,
86              final Date responseDate,
87              final StatusLine statusLine,
88              final Header[] responseHeaders,
89              final Resource resource,
90              final Map<String,String> variantMap) {
91          super();
92          Args.notNull(requestDate, "Request date");
93          Args.notNull(responseDate, "Response date");
94          Args.notNull(statusLine, "Status line");
95          Args.notNull(responseHeaders, "Response headers");
96          this.requestDate = requestDate;
97          this.responseDate = responseDate;
98          this.statusLine = statusLine;
99          this.responseHeaders = new HeaderGroup();
100         this.responseHeaders.setHeaders(responseHeaders);
101         this.resource = resource;
102         this.variantMap = variantMap != null
103             ? new HashMap<String,String>(variantMap)
104             : null;
105         this.date = parseDate();
106     }
107 
108     /**
109      * Create a new {@link HttpCacheEntry}.
110      *
111      * @param requestDate
112      *          Date/time when the request was made (Used for age
113      *            calculations)
114      * @param responseDate
115      *          Date/time that the response came back (Used for age
116      *            calculations)
117      * @param statusLine
118      *          HTTP status line from origin response
119      * @param responseHeaders
120      *          Header[] from original HTTP Response
121      * @param resource representing origin response body
122      */
123     public HttpCacheEntry(final Date requestDate, final Date responseDate, final StatusLine statusLine,
124             final Header[] responseHeaders, final Resource resource) {
125         this(requestDate, responseDate, statusLine, responseHeaders, resource,
126                 new HashMap<String,String>());
127     }
128 
129     /**
130      * Find the "Date" response header and parse it into a java.util.Date
131      * @return the Date value of the header or null if the header is not present
132      */
133     private Date parseDate() {
134         final Header dateHdr = getFirstHeader(HTTP.DATE_HEADER);
135         if (dateHdr == null) {
136             return null;
137         }
138         return DateUtils.parseDate(dateHdr.getValue());
139     }
140 
141     /**
142      * Returns the {@link StatusLine} from the origin
143      * {@link org.apache.http.HttpResponse}.
144      */
145     public StatusLine getStatusLine() {
146         return this.statusLine;
147     }
148 
149     /**
150      * Returns the {@link ProtocolVersion} from the origin
151      * {@link org.apache.http.HttpResponse}.
152      */
153     public ProtocolVersion getProtocolVersion() {
154         return this.statusLine.getProtocolVersion();
155     }
156 
157     /**
158      * Gets the reason phrase from the origin
159      * {@link org.apache.http.HttpResponse}, for example, "Not Modified".
160      */
161     public String getReasonPhrase() {
162         return this.statusLine.getReasonPhrase();
163     }
164 
165     /**
166      * Returns the HTTP response code from the origin
167      * {@link org.apache.http.HttpResponse}.
168      */
169     public int getStatusCode() {
170         return this.statusLine.getStatusCode();
171     }
172 
173     /**
174      * Returns the time the associated origin request was initiated by the
175      * caching module.
176      * @return {@link Date}
177      */
178     public Date getRequestDate() {
179         return requestDate;
180     }
181 
182     /**
183      * Returns the time the origin response was received by the caching module.
184      * @return {@link Date}
185      */
186     public Date getResponseDate() {
187         return responseDate;
188     }
189 
190     /**
191      * Returns all the headers that were on the origin response.
192      */
193     public Header[] getAllHeaders() {
194         return responseHeaders.getAllHeaders();
195     }
196 
197     /**
198      * Returns the first header from the origin response with the given
199      * name.
200      */
201     public Header getFirstHeader(final String name) {
202         return responseHeaders.getFirstHeader(name);
203     }
204 
205     /**
206      * Gets all the headers with the given name that were on the origin
207      * response.
208      */
209     public Header[] getHeaders(final String name) {
210         return responseHeaders.getHeaders(name);
211     }
212 
213     /**
214      * Gets the Date value of the "Date" header or null if the header is missing or cannot be
215      * parsed.
216      *
217      * @since 4.3
218      */
219     public Date getDate() {
220         return date;
221     }
222 
223     /**
224      * Returns the {@link Resource} containing the origin response body.
225      */
226     public Resource getResource() {
227         return this.resource;
228     }
229 
230     /**
231      * Indicates whether the origin response indicated the associated
232      * resource had variants (i.e. that the Vary header was set on the
233      * origin response).
234      * @return {@code true} if this cached response was a variant
235      */
236     public boolean hasVariants() {
237         return getFirstHeader(HeaderConstants.VARY) != null;
238     }
239 
240     /**
241      * Returns an index about where in the cache different variants for
242      * a given resource are stored. This maps "variant keys" to "cache keys",
243      * where the variant key is derived from the varying request headers,
244      * and the cache key is the location in the
245      * {@link org.apache.http.client.cache.HttpCacheStorage} where that
246      * particular variant is stored. The first variant returned is used as
247      * the "parent" entry to hold this index of the other variants.
248      */
249     public Map<String, String> getVariantMap() {
250         return Collections.unmodifiableMap(variantMap);
251     }
252 
253     /**
254      * Provides a string representation of this instance suitable for
255      * human consumption.
256      */
257     @Override
258     public String toString() {
259         return "[request date=" + this.requestDate + "; response date=" + this.responseDate
260                 + "; statusLine=" + this.statusLine + "]";
261     }
262 
263 }