com.talvish.tales.contracts.services.http.HttpResult.java Source code

Java tutorial

Introduction

Here is the source code for com.talvish.tales.contracts.services.http.HttpResult.java

Source

// ***************************************************************************
// *  Copyright 2012 Joseph Molnar
// *
// *  Licensed 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.
// ***************************************************************************
package com.talvish.tales.contracts.services.http;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.Cookie;

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import com.google.common.base.Preconditions;
import com.talvish.tales.communication.HeaderConstants;
import com.talvish.tales.communication.Status;

/**
 * This class represents the result of an execution of a HTTP request.
 * It covers both successful and unsuccessful cases.
 * This is a class really meant for implementation re-use by the framework. 
 * @author jmolnar
 *
 */
@SuppressWarnings("rawtypes")
public abstract class HttpResult<V, T extends HttpResult> {
    protected V value;

    // share items 
    protected Map<String, String> headers = new HashMap<String, String>();
    protected Map<String, Cookie> cookies = new HashMap<String, Cookie>();
    protected Status code = Status.UNKNOWN;
    protected String subcode;
    protected String subject;
    protected String message;
    protected Throwable exception;

    private static final String[] defaultCachingEnabledOptions = new String[] {
            HeaderConstants.CACHE_CONTROL_PUBLIC_DIRECTIVE };

    private static final DateTimeFormatter RFC_1123_DATE_FORMATTER = DateTimeFormat
            .forPattern("EEE, dd MMM yyyy HH:mm:ss 'GMT'");
    //.withLocale( Locale.US )
    //.withZone(DateTimeZone.UTC);

    // ******* below are success items

    /**
     * The return value, which may be null if a failure case.
     * @return the result value
     */
    public V getValue() {
        return value;
    }

    /**
     * A convenience method that sets caching related headers to indicate we
     * don't want to cache.
     * @return returns itself so that calls can be chained together
     */
    @SuppressWarnings("unchecked")
    public T setCachingDisabled() {
        headers.put(HeaderConstants.CACHE_CONTROL, HeaderConstants.CACHE_CONTROL_DEFAULT_DIRECTIVE);
        headers.put(HeaderConstants.PRAGMA, HeaderConstants.PRAGMA_DEFAULT_DIRECTIVE);
        headers.put(HeaderConstants.EXPIRES, HeaderConstants.EXPIRES_DEFAULT_VALUE);
        return (T) this;
    }

    /**
     * A convenience method that sets the to enable caching up to a particular date.
     * This method will indicate the result can be cached publicly as well.
     * @param theMaxAge the maximum age of the result in seconds
     * @return returns itself so that calls can be chained together
     */
    @SuppressWarnings("unchecked")
    public T setCachingEnabled(int theMaxAge) {
        Preconditions.checkArgument(theMaxAge >= 0, "need a max-age greater than or equal to zero");
        setCachingEnabled(theMaxAge, defaultCachingEnabledOptions);
        return (T) this;
    }

    /**
     * A convenience method that sets the to enable caching up to a particular date 
     * and a particular set of options.
     * @param theMaxAge the maximum age of the result in seconds
     * @param theOptions the options to use for the caching
     * @return returns itself so that calls can be chained together
     */
    @SuppressWarnings("unchecked")
    public T setCachingEnabled(int theMaxAge, String[] theOptions) {
        Preconditions.checkArgument(theMaxAge >= 0, "need a max-age greater than or equal to zero");

        DateTime dateTimeNow = new DateTime(DateTimeZone.UTC);
        DateTime dateTimeExpired = dateTimeNow.plusSeconds(theMaxAge);

        StringBuilder value = new StringBuilder(HeaderConstants.CACHE_CONTROL_MAX_AGE_DIRECTIVE);
        value.append("=");
        value.append(theMaxAge);
        for (String option : theOptions) {
            value.append(", ");
            value.append(option);
        }

        // we put the date header so relative time can be calculated and as outlined
        // for origin-servers according to RFC2616
        headers.put(HeaderConstants.DATE_HEADER, RFC_1123_DATE_FORMATTER.print(dateTimeNow));
        // now we put in HTTP 1.1 headers
        headers.put(HeaderConstants.CACHE_CONTROL, value.toString());
        // and then the older HTTP 1.0 header, just in case
        headers.put(HeaderConstants.EXPIRES, RFC_1123_DATE_FORMATTER.print(dateTimeExpired));
        // and remove pragma, to ensure no conflict
        headers.remove(HeaderConstants.PRAGMA);
        return (T) this;
    }

    // ******* below are shared success and failure items

    /**
     * The HTTP headers to add to the result. 
     * @return the headers to add
     */
    public Map<String, String> getHeaders() {
        return this.headers;
    }

    public Map<String, Cookie> getCookies() {
        return this.cookies;
    }

    /**
     * The overall status code.
     * @return The status code.
     */
    public Status getCode() {
        return code;
    }

    /**
     * The  subcode, which is a simple free-form
     * value that the handler of the request can return.
     * @return the subcode
     */
    public String getSubcode() {
        return subcode;
    }

    /**
     * An exception, which is non-null if an exception occurred.
     * @return the failure exception or null
     */
    public Throwable getException() {
        return exception;
    }

    /**
     * The subject of the status code or status subcode.
     * Commonly this will point out issues with parameters.
     * @return the subject of the status
     */
    public String getSubject() {
        return subject;
    }

    /**
     * The message to display.
     * @return the failure message, which may also be null.
     */
    public String getMessage() {
        return message;
    }
}