Java tutorial
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); } } }