001package com.pusher.rest.data;
002
003import static com.pusher.rest.data.Result.Status.*;
004
005import java.io.IOException;
006
007import org.apache.http.client.ClientProtocolException;
008
009public class Result {
010    public enum Status {
011        SUCCESS(false), // No need!
012        CLIENT_ERROR(false),
013        AUTHENTICATION_ERROR(false),
014        MESSAGE_QUOTA_EXCEEDED(false),
015        NOT_FOUND(false),
016        SERVER_ERROR(true),
017        NETWORK_ERROR(true),
018        UNKNOWN_ERROR(true),
019        ;
020
021        private final boolean shouldRetry;
022
023        private Status(final boolean shouldRetry) {
024            this.shouldRetry = shouldRetry;
025        }
026
027        /**
028         * @return whether the call should be retried without modification with an expectation of success
029         */
030        public boolean shouldRetry() {
031            return shouldRetry;
032        }
033    }
034
035    private final Status status;
036    private final Integer httpStatus;
037    private final String message;
038
039    private Result(final Status status, final Integer httpStatus, final String message) {
040        this.status = status;
041        this.httpStatus = httpStatus;
042        this.message = message;
043    }
044
045    /**
046     * Factory method
047     *
048     * @param statusCode HTTP status code
049     * @param responseBody HTTP response body
050     * @return a Result encapsulating the params
051     */
052    public static Result fromHttpCode(final int statusCode, final String responseBody) {
053        final Status status;
054        switch (statusCode) {
055        case 200:
056            status = SUCCESS;
057            break;
058        case 400:
059            status = CLIENT_ERROR;
060            break;
061        case 401:
062            status = AUTHENTICATION_ERROR;
063            break;
064        case 403:
065            status = MESSAGE_QUOTA_EXCEEDED;
066            break;
067        case 404:
068            status = NOT_FOUND;
069            break;
070        default:
071            status = statusCode >= 500 && statusCode < 600 ? SERVER_ERROR : UNKNOWN_ERROR;
072        }
073
074        return new Result(status, statusCode, responseBody);
075    }
076
077    /**
078     * Factory method
079     *
080     * @param e cause
081     * @return a Result encapsulating the params
082     */
083    public static Result fromException(final IOException e) {
084        return new Result(Status.NETWORK_ERROR, null, e.toString());
085    }
086
087    /**
088     * Factory method
089     *
090     * @param e cause
091     * @return a Result encapsulating the params
092     */
093    public static Result fromException(final ClientProtocolException e) {
094        return new Result(Status.UNKNOWN_ERROR, null, e.toString());
095    }
096
097    /**
098     * Factory method
099     *
100     * @param t cause
101     * @return a Result encapsulating the params
102     */
103    public static Result fromThrowable(final Throwable t) {
104        return new Result(Status.UNKNOWN_ERROR, null, t.toString());
105    }
106
107    /**
108     * @return the enum classifying the result of the call
109     */
110    public Status getStatus() {
111        return status;
112    }
113
114    /**
115     * @return the data response (success) or descriptive message (error) returned from the call
116     */
117    public String getMessage() {
118        return message;
119    }
120
121    /**
122     * @return the HTTP status code of the call, useful for debugging instances of UNKNOWN_ERROR
123     */
124    public Integer getHttpStatus() {
125        return httpStatus;
126    }
127}