/*
* JBoss, Home of Professional Open Source
* Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.messaging.core.message.impl;
import org.jboss.messaging.core.logging.Logger;
import org.jboss.messaging.core.message.Message;
import org.jboss.messaging.core.remoting.spi.MessagingBuffer;
import static org.jboss.messaging.util.DataConstants.*;
import org.jboss.messaging.util.SimpleString;
import org.jboss.messaging.util.TypedProperties;
import java.util.Set;
/**
* A concrete implementation of a message
*
* All messages handled by JBM core are of this type
*
* @author <a href="mailto:ovidiu@feodorov.com">Ovidiu Feodorov</a>
* @author <a href="mailto:tim.fox@jboss.com">Tim Fox</a>
* @author <a href="mailto:clebert.suconic@jboss.com">Clebert Suconic</a>
* @author <a href="mailto:ataylor@redhat.com">Andy Taylor</a>
* @version <tt>$Revision: 2740 $</tt>
*
* For normal message transportation serialization is not used
*
* $Id: MessageSupport.java 2740 2007-05-30 11:36:28Z timfox $
*/
public abstract class MessageImpl implements Message
{
// Constants -----------------------------------------------------
private static final Logger log = Logger.getLogger(MessageImpl.class);
public static final SimpleString HDR_ACTUAL_EXPIRY_TIME = new SimpleString("JBMActualExpiryTime");
public static final SimpleString HDR_ORIGIN_QUEUE = new SimpleString("JBMOriginQueue");
public static final SimpleString GROUP_ID = new SimpleString("JBMGroupID");
// Attributes ----------------------------------------------------
protected long messageID;
private SimpleString destination;
private byte type;
protected boolean durable;
/** GMT milliseconds at which this message expires. 0 means never expires * */
private long expiration;
private long timestamp;
private TypedProperties properties;
private byte priority;
private MessagingBuffer body;
// Constructors --------------------------------------------------
protected MessageImpl()
{
this.properties = new TypedProperties();
}
/**
* overridden by the client message, we need access to the connection so we can create the appropriate MessagingBuffer.
* @param type
* @param durable
* @param expiration
* @param timestamp
* @param priority
* @param body
*/
protected MessageImpl(final byte type, final boolean durable, final long expiration,
final long timestamp, final byte priority, MessagingBuffer body)
{
this();
this.type = type;
this.durable = durable;
this.expiration = expiration;
this.timestamp = timestamp;
this.priority = priority;
this.body = body;
}
/*
* Copy constructor
*/
protected MessageImpl(final MessageImpl other)
{
this();
this.messageID = other.messageID;
this.destination = other.destination;
this.type = other.type;
this.durable = other.durable;
this.expiration = other.expiration;
this.timestamp = other.timestamp;
this.priority = other.priority;
this.properties = new TypedProperties(other.properties);
this.body = other.body;
}
protected MessageImpl(final long messageID)
{
this();
this.messageID = messageID;
}
// Message implementation ----------------------------------------
public void encode(MessagingBuffer buff)
{
buff.putLong(messageID);
buff.putSimpleString(destination);
buff.putByte(type);
buff.putBoolean(durable);
buff.putLong(expiration);
buff.putLong(timestamp);
buff.putByte(priority);
properties.encode(buff);
buff.putInt(body.limit());
buff.putBytes(body.array(), 0, body.limit());
}
public int getEncodeSize()
{
return SIZE_LONG + /* Destination */ SimpleString.sizeofString(destination) +
/* Type */ SIZE_BYTE +
/* Durable */ SIZE_BOOLEAN +
/* Expiration */ SIZE_LONG +
/* Timestamp */ SIZE_LONG +
/* Priority */ SIZE_BYTE +
/* PropertySize and Properties */ properties.getEncodeSize() +
/* BodySize and Body */ SIZE_INT + body.limit();
}
public void decode(final MessagingBuffer buffer)
{
messageID = buffer.getLong();
destination = buffer.getSimpleString();
type = buffer.getByte();
durable = buffer.getBoolean();
expiration = buffer.getLong();
timestamp = buffer.getLong();
priority = buffer.getByte();
properties.decode(buffer);
int len = buffer.getInt();
//TODO - this can be optimised
byte[] bytes = new byte[len];
buffer.getBytes(bytes);
body = buffer.createNewBuffer(len);
body.putBytes(bytes);
}
public long getMessageID()
{
return messageID;
}
public SimpleString getDestination()
{
return destination;
}
public void setDestination(SimpleString destination)
{
this.destination = destination;
}
public byte getType()
{
return type;
}
public boolean isDurable()
{
return durable;
}
public void setDurable(final boolean durable)
{
this.durable = durable;
}
public long getExpiration()
{
return expiration;
}
public void setExpiration(final long expiration)
{
this.expiration = expiration;
}
public long getTimestamp()
{
return timestamp;
}
public void setTimestamp(final long timestamp)
{
this.timestamp = timestamp;
}
public byte getPriority()
{
return priority;
}
public void setPriority(final byte priority)
{
this.priority = priority;
}
public boolean isExpired()
{
if (expiration == 0)
{
return false;
}
return System.currentTimeMillis() - expiration >= 0;
}
// Properties
// ---------------------------------------------------------------------------------------
public void putBooleanProperty(final SimpleString key, final boolean value)
{
properties.putBooleanProperty(key, value);
}
public void putByteProperty(final SimpleString key, final byte value)
{
properties.putByteProperty(key, value);
}
public void putBytesProperty(final SimpleString key, final byte[] value)
{
properties.putBytesProperty(key, value);
}
public void putShortProperty(final SimpleString key, final short value)
{
properties.putShortProperty(key, value);
}
public void putIntProperty(final SimpleString key, final int value)
{
properties.putIntProperty(key, value);
}
public void putLongProperty(final SimpleString key, final long value)
{
properties.putLongProperty(key, value);
}
public void putFloatProperty(final SimpleString key, final float value)
{
properties.putFloatProperty(key, value);
}
public void putDoubleProperty(final SimpleString key, final double value)
{
properties.putDoubleProperty(key, value);
}
public void putStringProperty(final SimpleString key, final SimpleString value)
{
properties.putStringProperty(key, value);
}
public Object getProperty(final SimpleString key)
{
return properties.getProperty(key);
}
public Object removeProperty(final SimpleString key)
{
return properties.removeProperty(key);
}
public boolean containsProperty(final SimpleString key)
{
return properties.containsProperty(key);
}
public Set<SimpleString> getPropertyNames()
{
return properties.getPropertyNames();
}
// Body
// -------------------------------------------------------------------------------------
public MessagingBuffer getBody()
{
return body;
}
public void setBody(final MessagingBuffer body)
{
this.body = body;
}
// Public --------------------------------------------------------
// Package protected ---------------------------------------------
// Protected -----------------------------------------------------
// Private -------------------------------------------------------
// Inner classes -------------------------------------------------
}