fm.audiobox.core.exceptions.RemoteMessageException.java Source code

Java tutorial

Introduction

Here is the source code for fm.audiobox.core.exceptions.RemoteMessageException.java

Source

/*
 * Copyright 2009-2014 iCoreTech, Inc.
 *
 * 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 fm.audiobox.core.exceptions;

import com.google.api.client.http.HttpResponse;
import com.google.api.client.http.HttpStatusCodes;
import com.google.api.client.util.LoggingByteArrayOutputStream;
import com.google.api.client.util.LoggingInputStream;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * This exception is the parent exception for:
 * <ul>
 * <li>{@link fm.audiobox.core.exceptions.AuthorizationException}</li>
 * <li>{@link fm.audiobox.core.exceptions.ValidationException}</li>
 * <li>{@link fm.audiobox.core.exceptions.FileAlreadyUploaded}</li>
 * <li>{@link fm.audiobox.core.exceptions.SystemOverloadedException}</li>
 * </ul>
 * It is used for those exception risen by responses given by the service
 * that bring some information on what gone wrong.
 */
public class RemoteMessageException extends AudioBoxException {

    private int statusCode = HttpStatusCodes.STATUS_CODE_UNAUTHORIZED;

    private static final int NO_RESPONSE = -1;

    private Errors errors;

    /**
     * Instantiates a new Remote message exception.
     *
     * @param response the response
     */
    public RemoteMessageException(HttpResponse response) {
        this(RemoteMessageException.parseErrors(response),
                response != null ? response.getStatusCode() : NO_RESPONSE);
    }

    /**
     * Instantiates a new Remote message exception.
     *
     * @param errors     the errors
     * @param statusCode the status code
     */
    public RemoteMessageException(Errors errors, int statusCode) {
        super(RemoteMessageException.firstErrorToString(errors));
        this.errors = errors;
        this.statusCode = statusCode;
    }

    @Override
    public String getMessage() {
        return this.toString();
    }

    /**
     * Gets error code (typically the HTTP STATUS).
     *
     * @return the error code
     */
    public int getErrorCode() {
        return statusCode;
    }

    /**
     * Gets the errors mapping.
     *
     * @return the errors
     */
    public Errors getErrors() {
        if (errors == null) {
            errors = buildEmptyErrors(getErrorCode());
        }
        return errors;
    }

    /**
     * Transforms error mapping into strings.
     *
     * @return the string
     */
    public String toString() {
        return errorsToString(getErrors());
    }

    /**
     * Transforms error mapping into strings.
     *
     * @param errors the errors mapping
     *
     * @return the string
     */
    public static String errorsToString(Errors errors) {
        String msg = errors.toString();
        if (StringUtils.EMPTY.equals(msg)) {
            for (Map.Entry<String, Object> error : errors.getUnknownKeys().entrySet()) {
                msg += errorToString(error) + "\n";
            }
        }
        return msg;
    }

    /**
     * Transform error set into a string.
     *
     * @param error an error in form of a {@link java.util.Map.Entry}
     *
     * @return a single string containing the error.
     */
    private static String errorToString(Map.Entry<String, Object> error) {
        return String.format("%1s: %2s", error.getKey(), error.getValue());
    }

    /* =============== */
    /* Private methods */
    /* =============== */

    /**
     * Parse errors.
     *
     * @param response the response
     *
     * @return the errors
     */
    private static Errors parseErrors(HttpResponse response) {
        try {
            return response.parseAs(Errors.class);
        } catch (Exception e) {
            logger.warn("Here's the 'Maytag(tm) repair man', we got something not expect, see below.");
            logger.warn(e.getMessage());
            if (response != null && response.getStatusMessage() != null) {
                try {
                    // Try to recover error message
                    LoggingInputStream lis = (LoggingInputStream) response.getContent();
                    LoggingByteArrayOutputStream log = lis.getLogStream();
                    Errors es = new Errors();

                    es.setError(response.getStatusMessage());
                    es.setErrorDescription(log.toString());
                    return es;

                } catch (IOException e1) {
                    logger.error("Response message: " + response.getStatusMessage());
                    e1.printStackTrace();
                }
            }

            // Catchall, preserve status message
            return buildEmptyErrors(response == null ? NO_RESPONSE : response.getStatusCode());
        }
    }

    /**
     * Build empty errors.
     *
     * @return the errors
     */
    private static Errors buildEmptyErrors(int statusMessage) {
        Map<String, Object> err = new HashMap<>();
        err.put(RemoteMessageException.class.getCanonicalName(),
                String.format("Client got a remote error (%1d) but no message was given.", statusMessage));
        Errors errors = new Errors();
        errors.setUnknownKeys(err);
        return errors;
    }

    /**
     * Gets the first error and transforms it into a human readable string.
     *
     * @param errors the errors object
     *
     * @return the message string or empty string if none found.
     */
    private static String firstErrorToString(Errors errors) {

        if (errors == null) {
            errors = RemoteMessageException.buildEmptyErrors(0);
        }

        for (Map.Entry<String, Object> error : errors.getUnknownKeys().entrySet()) {
            return errorToString(error);
        }

        return StringUtils.EMPTY;
    }
}