/*
* Copyright (c) 2009, 2012 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Dave Locke - initial API and implementation and/or initial documentation
*/
package org.eclipse.paho.client.mqttv3;
/**
* An MQTT message. The message includes a "payload" (the body of the message)
* represented as a byte[].
*/
public class MqttMessage {
private boolean mutable = true;
private byte[] payload;
private int qos = 1;
private boolean retained = false;
private boolean dup = false;
/**
* Utility method to validate the supplied QoS value.
* @throws IllegalArgumentException if value of QoS is not 0, 1 or 2.
*/
protected static void validateQos(int qos) {
if ((qos < 0) || (qos > 2)) {
throw new IllegalArgumentException();
}
}
/**
* Constructs a message with an empty payload, and all other values
* set to defaults.
*
* The defaults are:
* <ul>
* <li>Message QoS set to 1</li>
* <li>Message will not be "retained" by the server</li>
* </ul>
*/
public MqttMessage() {
setPayload(new byte[]{});
}
/**
* Constructs a message with the specified byte array as a payload,
* and all other values set to defaults.
*/
public MqttMessage(byte[] payload) {
setPayload(payload);
}
/**
* Returns the payload as a byte array.
*
* @return the payload as a byte array.
*/
public byte[] getPayload() throws MqttException {
return payload;
}
/**
* Clears the payload, resetting it to be empty.
* @throws IllegalStateException if this message cannot be edited
*/
public void clearPayload() {
checkMutable();
this.payload = new byte[] {};
}
/**
* Sets the payload of this message to be the specified byte array.
*
* @param payload the payload for this message.
* @throws IllegalStateException if this message cannot be edited
*/
public void setPayload(byte[] payload) {
checkMutable();
this.payload = payload;
}
/**
* Returns whether or not this message should be/was retained by the server.
* For messages received from the server, this method returns whether or not
* the message was from a current publisher, or was "retained" by the server as
* the last message published on the topic.
*
* @return <code>true</code> if the message should be, or was, retained by
* the server.
* @see #setRetained(boolean)
*/
public boolean isRetained() {
return retained;
}
/**
* Whether or not the publish message should be retained by the messaging engine.
* Sending a message with the retained set to <code>false</code> will clear the
* retained message from the server. The default value is <code>false</code>
*
* @param retained whether or not the messaging engine should retain the message.
* @throws IllegalStateException if this message cannot be edited
*/
public void setRetained(boolean retained) {
checkMutable();
this.retained = retained;
}
/**
* Returns the quality of service for this message.
* @return the quality of service to use, either 0, 1, or 2.
* @see #setQos(int)
*/
public int getQos() {
return qos;
}
/**
* Sets the quality of service for this message.
* <ul>
* <li>Quality of service 0 - indicates that a message should
* be delivered at most once (zero or one times). The message will not be persisted to disk,
* and will not be acknowledged across the network. This QoS is the fastest,
* but should only be used for messages which are not valuable - note that
* if the server cannot process the message (for example, there
* is an authorization problem), then an
* {@link MqttCallback#deliveryComplete(MqttDeliveryToken)}.
* Also known as "fire and forget".</li>
*
* <li>Quality of service 1 - indicates that a message should
* be delivered at least once (one or more times). The message can only be delivered safely if
* it can be persisted, so the application must supply a means of
* persistence using <code>MqttConnectOptions</code>.
* If a persistence mechanism is not specified, the message will not be
* delivered in the event of a client failure.
* The message will be acknowledged across the network.
* This is the default QoS.</li>
*
* <li>Quality of service 2 - indicates that a message should
* be delivered once. The message will be persisted to disk, and will
* be subject to a two-phase acknowledgement across the network.
* The message can only be delivered safely if
* it can be persisted, so the application must supply a means of
* persistence using <code>MqttConnectOptions</code>.
* If a persistence mechanism is not specified, the message will not be
* delivered in the event of a client failure.</li>
*
* If persistence is not configured, QOS 1 and 2 messages will still be delivered
* in the event of a network or server problem as the client will hold state in memory.
* If the MQTT client is shutdown or fails and persistence is not configured then
* delivery of QOS 1 and 2 messages can not be maintained as client side state will
* be lost.
*
* @param qos the "quality of service" to use. Set to 0, 1, 2.
* @throws IllegalArgumentException if value of QoS is not 0, 1 or 2.
* @throws IllegalStateException if this message cannot be edited
*/
public void setQos(int qos) {
checkMutable();
validateQos(qos);
this.qos = qos;
}
/**
* Returns a string representation of this message.
* @return a string representation of this message.
*/
public String toString() {
return new String(payload);
}
/**
* Sets the mutability of this object (whether or not its values can be
* changed.
* @param mutable <code>true</code> if the values can be changed,
* <code>false</code> to prevent them from being changed.
*/
protected void setMutable(boolean mutable) {
this.mutable = mutable;
}
protected void checkMutable() throws IllegalStateException {
if (!mutable) {
throw new IllegalStateException();
}
}
protected void setDuplicate(boolean dup) {
this.dup = dup;
}
/**
* Returns whether or not this message might be a duplicate of one which has
* already been received. This will only be set on messages received from
* the server.
* @return <code>true</code> if the message might be a duplicate.
*/
public boolean isDuplicate() {
return this.dup;
}
}