com.google.android.filecache
Class FileResponseCache

java.lang.Object
  extended by java.net.ResponseCache
      extended by com.google.android.filecache.FileResponseCache

public abstract class FileResponseCache
extends ResponseCache

File-based implementation of ResponseCache.

Usage:

 // Step 1: Implement cache
 class MyResponseCache extends FileResponseCache { ... }

 // Step 2: Install cache
 ResponseCache.setDefault(new MyResponseCache(...));

 // Step 3: Use cache
 ContentHandler handler = new MyParser(...);
 handler = MyResponseCache.capture(handler, cookie);
 handler.getContent(connection);
 

Note: Due to a bug in the Android platform, HttpURLConnection.getResponseCode() will return -1 and HttpURLConnection.getResponseMessage() will return null when the response is cached, but you can get the status line by calling URLConnection.getHeaderField(String) with the value "status".

Please see http://java.sun.com/j2se/1.5.0/docs/guide/net/http-cache.html for more information about the ResponseCache API.


Constructor Summary
protected FileResponseCache()
           
 
Method Summary
static ContentHandler capture(ContentHandler handler, Object cookie)
          Creates a ContentHandler wrapper to capture a URLConnection using the currently installed FileResponseCache.
 CacheResponse get(URI uri, String requestMethod, Map<String,List<String>> requestHeaders)
          Please see ResponseCache.get(URI, String, Map).
protected abstract  File getFile(URI uri, String requestMethod, Map<String,List<String>> requestHeaders, Object cookie)
          Returns the File used for caching the given request, or null if this type of request should not be cached.
static int getResponseCode(URLConnection connection)
          Returns the response code, even if the response is cached.
static String getResponseMessage(URLConnection connection)
          Returns the response message, even if the response is cached.
protected  boolean isCacheable(URLConnection connection)
          Returns true if the given URLConnection is cacheable, false otherwise.
protected  boolean isStale(File file, URI uri, String requestMethod, Map<String,List<String>> requestHeaders, Object cookie)
          Returns true if the given cache File is too stale to satisfy the given request parameters.
 CacheRequest put(URI uri, URLConnection connection)
          Please see ResponseCache.put(URI, URLConnection).
static ContentHandler sink()
          Creates a ContentHandler that consumes the content of a URLConnection so that the response data will be captured by a ResponseCache.
 
Methods inherited from class java.net.ResponseCache
getDefault, setDefault
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

FileResponseCache

protected FileResponseCache()
Method Detail

getResponseCode

public static int getResponseCode(URLConnection connection)
                           throws IOException
Returns the response code, even if the response is cached.

Calling HttpURLConnection.getResponseCode() directly when the response is cached will always return -1.

Throws:
IOException

getResponseMessage

public static String getResponseMessage(URLConnection connection)
                                 throws IOException
Returns the response message, even if the response is cached.

Calling HttpURLConnection.getResponseMessage() directly when the response is cached will always return null.

Throws:
IOException

isStale

protected boolean isStale(File file,
                          URI uri,
                          String requestMethod,
                          Map<String,List<String>> requestHeaders,
                          Object cookie)
Returns true if the given cache File is too stale to satisfy the given request parameters.

The current implementation only considers the max-age value specified in the cache-control header.

Parameters:
file - the cache file.
uri - the request URI
requestMethod - the HTTP request method.
requestHeaders - the HTTP request headers. Keys should be specified in lower-case.
Returns:
true if the given cache File is too stale to satisfy the given request parameters, false otherwise.

isCacheable

protected boolean isCacheable(URLConnection connection)
                       throws IOException
Returns true if the given URLConnection is cacheable, false otherwise.

The default implementation returns true if and only if the request method is HTTP GET and the response code is HTTP 200 OK. Subclasses may override this method to implement different behavior. For example, some applications may cache certain 206 Partial Content or HTTP POST responses.

Parameters:
connection - the URLConnection to be cached.
Returns:
true if the given URLConnection is cacheable, false otherwise.
Throws:
IOException

getFile

protected abstract File getFile(URI uri,
                                String requestMethod,
                                Map<String,List<String>> requestHeaders,
                                Object cookie)
Returns the File used for caching the given request, or null if this type of request should not be cached.

It is not necessary to create the parent directories; this will be done automatically before the file is written.

Parameters:
uri - the URI of the request.
requestMethod - the HTTP request method.
requestHeaders - the HTTP request headers.

Due to a bug in the platform, the current implementation is limited to one value per key.

Keys should be specified in lower-case.

cookie - the cookie passed to getFile(URI, String, Map, Object) or null if none was passed.
Returns:
the File in which to cache the given request, or null to not cache this request.

get

public CacheResponse get(URI uri,
                         String requestMethod,
                         Map<String,List<String>> requestHeaders)
                  throws IOException
Please see ResponseCache.get(URI, String, Map).

Specified by:
get in class ResponseCache
Throws:
IOException

put

public CacheRequest put(URI uri,
                        URLConnection connection)
                 throws IOException
Please see ResponseCache.put(URI, URLConnection).

Specified by:
put in class ResponseCache
Throws:
IOException

capture

public static ContentHandler capture(ContentHandler handler,
                                     Object cookie)
Creates a ContentHandler wrapper to capture a URLConnection using the currently installed FileResponseCache.

A wrapper is required to work-around platform bugs and to guard against cache corruption. It also provides a nice mechanism for passing parameters to the cache on a per-resource basis.

Usage:

 // Parses binary content from a URLConnection
 class MyContentHandler extends java.net.ContentHandler { ... }

 // Parses binary content from a URL with caching
 Object getContent(URL url) {
     ContentHandler handler = new MyContentHandler(...);
     handler = ResponseCache.capture(handler, cookie);

     URLConnection connection = url.openConnection();
     return handler.getContent(connection);
 }
 

The wrapper ensures that the correct values are passed to getFile(URI, String, Map, Object). Without the wrapper, the URI and headers passed to getFile(URI, String, Map, Object) may be incorrect due to platform bugs.

The wrapper will also delete the cache file associated with a URLConnection passed to ContentHandler.getContent(URLConnection) if any type of exception is thrown.

The wrapper specifies the cookie value passed to getFile(URI, String, Map, Object).

In general, the cookie contains information about a request that is required to calculate the cache file location. This is especially important when the information is difficult to extract from the URI and headers passed to getFile(URI, String, Map, Object).

Frequently, the cookie is an account identifier so that cached responses are grouped by account. Grouping cached files by account makes it easy to remove the cached content associated with an account when an account is removed from the system. It is also common for a single URL to provide different content depending on the account that was used to access it, and separating the cached content ensures that one account does not overwrite the content of another.

The cookie could also just be the File that should be returned by getFile(URI, String, Map, Object).

Implementation Notes: It is important that the URLConnection is only accessed by a single thread (the one that calls ContentHandler.getContent(URLConnection)). Nesting is allowed (i.e., caching a different URLConnection from within a call to ContentHandler.getContent(URLConnection)), however the URLConnection owned by the enclosing ContentHandler must not be accessed while the nested request is in progress.

Parameters:
handler - a ContentHandler.
cookie - a cookie to pass to getFile(URI, String, Map, Object) or null.
Returns:
a ContentHandler wrapper or the original ContentHandler if a FileResponseCache has not been installed.
Throws:
IllegalStateException - if a FileResponseCache has not been installed using ResponseCache.setDefault(ResponseCache).

sink

public static ContentHandler sink()
Creates a ContentHandler that consumes the content of a URLConnection so that the response data will be captured by a ResponseCache.

The returned ContentHandler must be wrapped with capture(ContentHandler, Object) to enable caching.

The bytes of the input stream are not interpreted, which saves CPU resources and makes this method ideal for pre-fetching data. The method ContentHandler.getContent(URLConnection) will always return null.

If the URLConnection is already being served from the local cache, this ContentHandler does nothing.