com.gistlabs.mechanize.cache.HttpCacheFilter.java Source code

Java tutorial

Introduction

Here is the source code for com.gistlabs.mechanize.cache.HttpCacheFilter.java

Source

/**
 * Copyright (C) 2012-2014 Gist Labs, LLC. (http://gistlabs.com)
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */
package com.gistlabs.mechanize.cache;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.protocol.HttpContext;

import com.gistlabs.mechanize.cache.api.CacheEntry;
import com.gistlabs.mechanize.cache.api.HttpCache;
import com.gistlabs.mechanize.cache.inMemory.InMemoryCacheEntry;
import com.gistlabs.mechanize.cache.inMemory.InMemoryHttpCache;
import com.gistlabs.mechanize.filters.MechanizeChainFilter;
import com.gistlabs.mechanize.filters.MechanizeFilter;

/**
 * Support for cache and conditional HTTP request/response handling
 *
 * Includes support for the following HTTP Headers to support caching: Cache-Control, Expires, Date, Age
 * Includes support for the following HTTP Headers to support conditions: Last-Modified, ETag, If-Modified-Since, If-None-Match
 *
 */
public class HttpCacheFilter implements MechanizeChainFilter {
    final HttpCache cache;

    public HttpCacheFilter() {
        this(new InMemoryHttpCache());
    }

    public HttpCacheFilter(final HttpCache cache) {
        this.cache = cache;
    }

    @Override
    public HttpResponse execute(final HttpUriRequest request, final HttpContext context,
            final MechanizeFilter chain) {
        String method = request.getMethod().toUpperCase();
        if (method.equals("GET"))
            return executeGET(request, context, chain);
        else if (method.equals("HEAD"))
            return executeHEAD(request, context, chain);
        else
            return executeOther(request, context, chain);
    }

    public HttpResponse executeOther(final HttpUriRequest request, final HttpContext context,
            final MechanizeFilter chain) {
        String uri = request.getURI().toString();
        invalidate(uri, request);
        return chain.execute(request, context);
    }

    public HttpResponse executeGET(final HttpUriRequest request, final HttpContext context,
            final MechanizeFilter chain) {
        String uri = request.getURI().toString();
        CacheEntry previous = cache.get(uri);
        if (previous != null && previous.isValid())
            return previous.getResponse();

        if (previous != null)
            previous.prepareConditionalGet(request);

        HttpResponse response = chain.execute(request, context); // call the chain

        if (response.getStatusLine().getStatusCode() == 304) // not modified
            return previous.updateCacheValues(response).getResponse();

        CacheEntry maybe = generateCacheEntry(request, response);

        if (maybe.isCacheable())
            store(uri, previous, maybe);

        return response;
    }

    protected InMemoryCacheEntry generateCacheEntry(final HttpUriRequest request, HttpResponse response) {
        return new InMemoryCacheEntry(request, response);
    }

    public HttpResponse executeHEAD(final HttpUriRequest request, final HttpContext context,
            final MechanizeFilter chain) {
        String uri = request.getURI().toString();
        CacheEntry previous = cache.get(uri);

        if (previous != null && previous.isValid())
            return previous.head();

        if (previous != null)
            previous.prepareConditionalGet(request);

        HttpResponse response = chain.execute(request, context); // call the chain

        if (previous != null)
            previous.updateCacheValues(response);

        return response;
    }

    protected void invalidate(final String uri, final HttpUriRequest request) {
        cache.remove(uri);
    }

    protected boolean store(final String uri, final CacheEntry cachedValue, final CacheEntry maybe) {
        if (cachedValue == null)
            return cache.putIfAbsent(uri, maybe);
        else
            return cache.replace(uri, cachedValue, maybe);
    }

}