package com.ubermq.jms.common.datagram.impl;
import com.ubermq.jms.common.datagram.*;
import com.ubermq.kernel.*;
import java.nio.*;
/**
* An implementation of an ACK (acknowledgement) datagram.
*/
public class AckDatagram
extends AbstractDatagram
implements IAckDatagram
{
private MessageId msgId;
private boolean nack;
/**
* Constructs a general purpose ACK datagram that does not refer to
* a message, that is either a success or failure ACK.
* @param nack true if NACK, false otherwise.
*/
AckDatagram(boolean nack)
{
super(DatagramFactory.DGRAM_ACK, 0);
this.msgId = null;
this.nack = nack;
}
/**
* Constructs an ACK for a specific message.
* @param msgId the message ID of the message that the datagram isreferring to.
* @param nack true if NACK, false otherwise.
*/
AckDatagram(MessageId msgId, boolean nack)
{
super(DatagramFactory.DGRAM_ACK, 0);
this.msgId = msgId;
this.nack = nack;
}
/**
* No-arg constructor for reading datagrams from byte buffers.
*/
public AckDatagram()
{
super(DatagramFactory.DGRAM_ACK, 0);
}
// ack-specific
public MessageId getAckMessageId() {return msgId;}
public boolean isNegativeAck() {return nack;}
/**
* the ACK datagram format is:
*
* <pre>
* -------
* nack? 1 non-zero for true
* -------
* msgId 12 optional, sender ID followed by sequence
* -------
* </pre>
*/
public void incoming(java.nio.ByteBuffer bb)
throws java.io.IOException
{
super.incoming(bb);
setDatagramProps(DatagramFactory.DGRAM_ACK, 0);
nack = (bb.get() != 0);
if (bb.remaining() > 0) {
msgId = new MessageId(bb.getLong(), bb.getInt());
} else {
msgId = null;
}
}
/**
* allows the datagram to be output to a channel.
*/
public void outgoing(java.nio.ByteBuffer bb)
{
super.outgoing(bb);
bb.put(nack ? (byte)0x1 : (byte)0x0);
if (msgId != null) {
bb.putLong(msgId.getSenderId());
bb.putInt(msgId.getSequence());
}
}
public String toString()
{
return super.toString() +
"\nMsgID:\t\t" + msgId +
"\nnack:\t\t" + nack;
}
public boolean equals(Object o)
{
if (o instanceof IAckDatagram) {
IAckDatagram ad = (IAckDatagram)o;
return ( ((ad.getAckMessageId() == null && getAckMessageId() == null) ||
ad.getAckMessageId().equals(getAckMessageId())) &&
ad.isNegativeAck() == isNegativeAck());
} else {
return false;
}
}
public int hashCode() {
int result = 17;
result = 37*result + getAckMessageId().hashCode();
result = 37*result + (isNegativeAck() ? 0 : 1);
return result;
}
}
|