com.shekar.msrp.codec.MsrpResponseStatus.java Source code

Java tutorial

Introduction

Here is the source code for com.shekar.msrp.codec.MsrpResponseStatus.java

Source

package com.shekar.msrp.codec;

import io.netty.buffer.ByteBuf;

import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;

import com.shekar.msrp.utils.MsrpConstants;

public class MsrpResponseStatus {

    /**
     * <p>The <strong>200</strong> response code indicates a successful transaction</p>.
     */
    public static final MsrpResponseStatus OK = new MsrpResponseStatus(200, "OK", true);

    /**
     * <p>A <strong>400</strong> response indicates that a request was unintelligible. The 
     * sender may retry the request after correcting the error.
     * </p>
     */
    public static final MsrpResponseStatus UNINTELLIGIBLE = new MsrpResponseStatus(400, "Unintelligible", true);

    /**
     * <p>A <strong>400</strong> response indicates that a request was unintelligible. The 
     * sender may retry the request after correcting the error.
     * </p>
     */
    public static final MsrpResponseStatus UNAUTHORIZED = new MsrpResponseStatus(401, "Unauthorized", true);
    /**
     * <p>A <strong>403</strong> response indicates that the attempted action is not allowed. 
     * The sender should not try the request again.
     * </p>
     */
    public static final MsrpResponseStatus NOT_ALLOWED = new MsrpResponseStatus(403, "Not Allowed", true);

    /**
     * A <strong>408</strong> response indicates that a downstream transaction did not 
     * complete in the allotted time. It is never sent by any elements
     * described in this specification. However, <strong>408</strong> is used in the MSRP
     * relay extension; therefore, MSRP end-points may receive it. An
     * end-point MUST treat a <strong>408</strong> response in the same manner as it would
     * treat a local timeout.
     */
    public static final MsrpResponseStatus DOWNSTREAM_TRANSACTION_TIMEOUT = new MsrpResponseStatus(408,
            "Downstream Transaction Timeout", true);

    /**
     * <p>A <strong>413</strong> response indicates that the receiver wishes the sender to stop
     * sending the particular message. Typically, a 413 is sent in response
     * to a chunk of an undesired message.
     * </p>
     * <p>If a message sender receives a <strong>413</strong> in a response, or in a REPORT
     * request, it MUST NOT send any further chunks in the message, that is,
     * any further chunks with the same Message-ID value. If the sender
     * receives the <strong>413</strong> while in the process of sending a chunk, and the
     * chunk is interruptible, the sender MUST interrupt it.
     * </p>
     */
    public static final MsrpResponseStatus STOP_SENDING_IMMEDIATELY = new MsrpResponseStatus(413,
            "Stop Sending Immediately", true);

    /**
     * <p>A <strong>415</strong> response indicates that the SEND request contained a media type
     * that is not understood by the receiver. The sender should not send
     * any further messages with the same content-type for the duration of
     * the session.
     * </p>
     */
    public static final MsrpResponseStatus MEDIA_TYPE_NOT_SUPPORTED = new MsrpResponseStatus(415,
            "Media Type Not Supported", true);

    /**
     * <p>A <strong>423</strong> response indicates that one of the requested parameters is out
     * of bounds. It is used by the relay extensions to this document.
     * </p>
     */
    public static final MsrpResponseStatus PARAMETER_OUT_OF_BOUND = new MsrpResponseStatus(423,
            "Parameter Out Of Bounds", true);

    /**
     * 423
     */
    public static final MsrpResponseStatus INTERVAL_OUT_OF_BOUNDS = new MsrpResponseStatus(423,
            "Interval Out-of-Bounds", true);

    /**
     * 425
     */
    public static final MsrpResponseStatus NICKNAME_RESERVED_OR_ALREADY_IN_USE = new MsrpResponseStatus(425,
            "Nickname reserved or already in use", true);

    /**
     * <p>A <strong>481</strong> response indicates that the indicated session does not exist.
     * The sender should terminate the session.
     * </p>
     */
    public static final MsrpResponseStatus SESSION_NOT_FOUND = new MsrpResponseStatus(481, "Session Not Found",
            true);

    /**
     * <p>A <strong>501</strong> response indicates that the recipient does not understand the
     * request method.
     * </p>
     * <p>The <strong>501</strong> response code exists to allow some degree of method
     * extensibility. It is not intended as a license to ignore methods
     * defined in this document; rather, it is a mechanism to report lack
     * of support of extension methods.
     * </p>
     */
    public static final MsrpResponseStatus UNKNOWN_REQUEST = new MsrpResponseStatus(501, "Unknown Request", true);

    /**
     * <p>A <strong>506</strong> response indicates that a request arrived on a session that is
     * already bound to another network connection. The sender should cease
     * sending messages for that session on this connection.
     * </p>
     */
    public static final MsrpResponseStatus WRONG_SESSION = new MsrpResponseStatus(506, "Wrong Session", true);

    private static final Map<String, MsrpResponseStatus> statusMap = new HashMap<String, MsrpResponseStatus>();

    static {
        statusMap.put("200", OK);
        statusMap.put("400", UNINTELLIGIBLE);
        statusMap.put("403", NOT_ALLOWED);
        statusMap.put("408", DOWNSTREAM_TRANSACTION_TIMEOUT);
        statusMap.put("413", STOP_SENDING_IMMEDIATELY);
        statusMap.put("415", MEDIA_TYPE_NOT_SUPPORTED);
        statusMap.put("423", PARAMETER_OUT_OF_BOUND);
        statusMap.put("425", NICKNAME_RESERVED_OR_ALREADY_IN_USE);
        statusMap.put("481", SESSION_NOT_FOUND);
        statusMap.put("501", UNKNOWN_REQUEST);
        statusMap.put("506", WRONG_SESSION);
        statusMap.put("400", UNINTELLIGIBLE);
    }

    public static MsrpResponseStatus valueOf(int code) {
        switch (code) {
        case 200:
            return OK;
        case 400:
            return UNINTELLIGIBLE;
        case 403:
            return DOWNSTREAM_TRANSACTION_TIMEOUT;
        case 413:
            return STOP_SENDING_IMMEDIATELY;
        case 415:
            return MEDIA_TYPE_NOT_SUPPORTED;
        case 423:
            return PARAMETER_OUT_OF_BOUND;
        case 481:
            return SESSION_NOT_FOUND;
        case 501:
            return UNKNOWN_REQUEST;
        case 506:
            return WRONG_SESSION;
        default:
            return null;

        }
    }

    public static MsrpResponseStatus valueOf(String code) {
        if (code == null) {
            throw new NullPointerException("code");
        }

        code = code.trim();
        if (code.isEmpty()) {
            return null;
        }

        return statusMap.get(code);
    }

    private final int code;
    private final String comment;
    private byte[] bytes;

    public MsrpResponseStatus(int code, String comment) {
        this(code, comment, false);
    }

    /**
     * @param code
     * @param comment
     * @param bytes
     */
    public MsrpResponseStatus(int code, String comment, boolean bytes) {
        if (code < 0) {
            throw new IllegalArgumentException("code: " + code + " (expected: 0+)");
        }

        if (comment == null) {
            throw new NullPointerException("comment");
        }
        if (comment != null) {
            for (int i = 0; i < comment.length(); i++) {
                char c = comment.charAt(i);
                // Check prohibited characters.
                switch (c) {
                case '\n':
                case '\r':
                    throw new IllegalArgumentException(
                            "reasonPhrase contains one of the following prohibited characters: " + "\\r\\n: "
                                    + comment);
                }
            }
        }

        this.code = code;
        this.comment = comment;
        if (bytes) {
            this.bytes = (code + " " + comment).getBytes(Charset.forName("UTF-8"));
        } else {
            this.bytes = null;
        }
    }

    public int code() {
        return code;
    }

    public String comment() {
        return comment;
    }

    /**
     * Is given response code a valid MSRP code?
     * 
     * @param code
     *            the response code to check
     * @return true is valid
     */
    public static boolean isValid(int code) {
        if (valueOf(code) != null) {
            return true;
        }
        return false;
    }

    public static boolean isValid(String code) {
        try {
            return isValid(Integer.parseInt(code));
        } catch (NumberFormatException nfe) {
            return false;
        }
    }

    /**
     * Does given response code denote an error?
     * 
     * @param code
     *            the response code to check
     * @return true is (known) error
     */
    public static boolean isError(int code) {
        return isValid(code) && code > 299;
    }

    /**
     * Is response code an indication to abort sending?
     * 
     * @param code
     *            the response code
     * @return true if the code indicates sender should abort sending.
     */
    public static boolean isAbortCode(int code) {
        switch (code) {
        case 400:
        case 403:
        case 413:
        case 415:
        case 481:
            return true;
        default:
            return false;
        }
    }

    public String toString() {
        StringBuilder buf = new StringBuilder(comment.length() + 5);
        buf.append(code);
        buf.append(' ');
        buf.append(comment);
        return buf.toString();
    }

    void encode(ByteBuf buf) {
        if (bytes == null) {
            MsrpHeaders.encodeUtf8(String.valueOf(code()), buf);
            buf.writeByte(MsrpConstants.SP);
            if (comment() != null) {
                MsrpHeaders.encodeUtf8(comment(), buf);
            }
        } else {
            buf.writeBytes(bytes);
        }
    }

}