package org.openamq.framing;
import org.apache.mina.common.ByteBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class BasicContentHeaderProperties implements ContentHeaderProperties
{
private static final Logger _logger = LoggerFactory.getLogger(BasicContentHeaderProperties.class);
/**
* We store the encoded form when we decode the content header so that if we need to
* write it out without modifying it we can do so without incurring the expense of
* reencoding it
*/
private byte[] _encodedForm;
/**
* Flag indicating whether the entire content header has been decoded yet
*/
private boolean _decoded = true;
/**
* We have some optimisations for partial decoding for maximum performance. The headers are used in the broker
* for routing in some cases so we can decode that separately.
*/
private boolean _decodedHeaders = true;
/**
* We have some optimisations for partial decoding for maximum performance. The content type is used by all
* clients to determine the message type
*/
private boolean _decodedContentType = true;
private String _contentType;
private String _encoding;
private FieldTable _headers;
private byte _deliveryMode;
private byte _priority;
private String _correlationId;
private String _replyTo;
private long _expiration;
private String _messageId;
private long _timestamp;
private String _type;
private String _userId;
private String _appId;
private String _clusterId;
private int _propertyFlags = 0;
public BasicContentHeaderProperties()
{
}
public int getPropertyListSize()
{
if (_encodedForm != null)
{
return _encodedForm.length;
}
else
{
int size = 0;
if ((_propertyFlags & (1 << 15)) > 0)
{
size += EncodingUtils.encodedShortStringLength(_contentType);
}
if ((_propertyFlags & (1 << 14)) > 0)
{
size += EncodingUtils.encodedShortStringLength(_encoding);
}
if ((_propertyFlags & (1 << 13)) > 0)
{
size += EncodingUtils.encodedFieldTableLength(_headers);
}
if ((_propertyFlags & (1 << 12)) > 0)
{
size += 1;
}
if ((_propertyFlags & (1 << 11)) > 0)
{
size += 1;
}
if ((_propertyFlags & (1 << 10)) > 0)
{
size += EncodingUtils.encodedShortStringLength(_correlationId);
}
if ((_propertyFlags & (1 << 9)) > 0)
{
size += EncodingUtils.encodedShortStringLength(_replyTo);
}
if ((_propertyFlags & (1 << 8)) > 0)
{
size += EncodingUtils.encodedShortStringLength(String.valueOf(_expiration));
}
if ((_propertyFlags & (1 << 7)) > 0)
{
size += EncodingUtils.encodedShortStringLength(_messageId);
}
if ((_propertyFlags & (1 << 6)) > 0)
{
size += 8;
}
if ((_propertyFlags & (1 << 5)) > 0)
{
size += EncodingUtils.encodedShortStringLength(_type);
}
if ((_propertyFlags & (1 << 4)) > 0)
{
size += EncodingUtils.encodedShortStringLength(_userId);
}
if ((_propertyFlags & (1 << 3)) > 0)
{
size += EncodingUtils.encodedShortStringLength(_appId);
}
if ((_propertyFlags & (1 << 2)) > 0)
{
size += EncodingUtils.encodedShortStringLength(_clusterId);
}
return size;
}
}
private void clearEncodedForm()
{
if (!_decoded && _encodedForm != null)
{
//decode();
}
_encodedForm = null;
}
public void setPropertyFlags(int propertyFlags)
{
clearEncodedForm();
_propertyFlags = propertyFlags;
}
public int getPropertyFlags()
{
return _propertyFlags;
}
public void writePropertyListPayload(ByteBuffer buffer)
{
if (_encodedForm != null)
{
buffer.put(_encodedForm);
}
else
{
if ((_propertyFlags & (1 << 15)) > 0)
{
EncodingUtils.writeShortStringBytes(buffer, _contentType);
}
if ((_propertyFlags & (1 << 14)) > 0)
{
EncodingUtils.writeShortStringBytes(buffer, _encoding);
}
if ((_propertyFlags & (1 << 13)) > 0)
{
EncodingUtils.writeFieldTableBytes(buffer, _headers);
}
if ((_propertyFlags & (1 << 12)) > 0)
{
buffer.put(_deliveryMode);
}
if ((_propertyFlags & (1 << 11)) > 0)
{
buffer.put(_priority);
}
if ((_propertyFlags & (1 << 10)) > 0)
{
EncodingUtils.writeShortStringBytes(buffer, _correlationId);
}
if ((_propertyFlags & (1 << 9)) > 0)
{
EncodingUtils.writeShortStringBytes(buffer, _replyTo);
}
if ((_propertyFlags & (1 << 8)) > 0)
{
EncodingUtils.writeShortStringBytes(buffer, String.valueOf(_expiration));
}
if ((_propertyFlags & (1 << 7)) > 0)
{
EncodingUtils.writeShortStringBytes(buffer, _messageId);
}
if ((_propertyFlags & (1 << 6)) > 0)
{
EncodingUtils.writeUnsignedInteger(buffer, 0/*timestamp msb*/);
EncodingUtils.writeUnsignedInteger(buffer, _timestamp);
}
if ((_propertyFlags & (1 << 5)) > 0)
{
EncodingUtils.writeShortStringBytes(buffer, _type);
}
if ((_propertyFlags & (1 << 4)) > 0)
{
EncodingUtils.writeShortStringBytes(buffer, _userId);
}
if ((_propertyFlags & (1 << 3)) > 0)
{
EncodingUtils.writeShortStringBytes(buffer, _appId);
}
if ((_propertyFlags & (1 << 2)) > 0)
{
EncodingUtils.writeShortStringBytes(buffer, _clusterId);
}
}
}
public void populatePropertiesFromBuffer(ByteBuffer buffer, int propertyFlags, int size)
throws AMQFrameDecodingException
{
_propertyFlags = propertyFlags;
if (_logger.isDebugEnabled())
{
_logger.debug("Property flags: " + _propertyFlags);
}
decode(buffer);
/*_encodedForm = new byte[size];
buffer.get(_encodedForm, 0, size);
_decoded = false;
_decodedHeaders = false;
_decodedContentType = false;*/
}
private void decode(ByteBuffer buffer)
{
//ByteBuffer buffer = ByteBuffer.wrap(_encodedForm);
int pos = buffer.position();
try
{
if ((_propertyFlags & (1 << 15)) > 0)
{
_contentType = EncodingUtils.readShortString(buffer);
}
if ((_propertyFlags & (1 << 14)) > 0)
{
_encoding = EncodingUtils.readShortString(buffer);
}
if ((_propertyFlags & (1 << 13)) > 0)
{
_headers = EncodingUtils.readFieldTable(buffer);
}
if ((_propertyFlags & (1 << 12)) > 0)
{
_deliveryMode = buffer.get();
}
if ((_propertyFlags & (1 << 11)) > 0)
{
_priority = buffer.get();
}
if ((_propertyFlags & (1 << 10)) > 0)
{
_correlationId = EncodingUtils.readShortString(buffer);
}
if ((_propertyFlags & (1 << 9)) > 0)
{
_replyTo = EncodingUtils.readShortString(buffer);
}
if ((_propertyFlags & (1 << 8)) > 0)
{
_expiration = Long.valueOf(EncodingUtils.readShortString(buffer)).longValue();
}
if ((_propertyFlags & (1 << 7)) > 0)
{
_messageId = EncodingUtils.readShortString(buffer);
}
if ((_propertyFlags & (1 << 6)) > 0)
{
// Discard msb from AMQ timestamp
buffer.getUnsignedInt();
_timestamp = buffer.getUnsignedInt();
}
if ((_propertyFlags & (1 << 5)) > 0)
{
_type = EncodingUtils.readShortString(buffer);
}
if ((_propertyFlags & (1 << 4)) > 0)
{
_userId = EncodingUtils.readShortString(buffer);
}
if ((_propertyFlags & (1 << 3)) > 0)
{
_appId = EncodingUtils.readShortString(buffer);
}
if ((_propertyFlags & (1 << 2)) > 0)
{
_clusterId = EncodingUtils.readShortString(buffer);
}
}
catch (AMQFrameDecodingException e)
{
throw new RuntimeException("Error in content header data: " + e);
}
final int endPos = buffer.position();
buffer.position(pos);
final int len = endPos - pos;
_encodedForm = new byte[len];
final int limit = buffer.limit();
buffer.limit(endPos);
buffer.get(_encodedForm, 0, len);
buffer.limit(limit);
buffer.position(endPos);
_decoded = true;
}
private void decodeUpToHeaders()
{
ByteBuffer buffer = ByteBuffer.wrap(_encodedForm);
try
{
if ((_propertyFlags & (1 << 15)) > 0)
{
byte length = buffer.get();
buffer.skip(length);
}
if ((_propertyFlags & (1 << 14)) > 0)
{
byte length = buffer.get();
buffer.skip(length);
}
if ((_propertyFlags & (1 << 13)) > 0)
{
_headers = EncodingUtils.readFieldTable(buffer);
}
_decodedHeaders = true;
}
catch (AMQFrameDecodingException e)
{
throw new RuntimeException("Error in content header data: " + e);
}
}
private void decodeUpToContentType()
{
ByteBuffer buffer = ByteBuffer.wrap(_encodedForm);
if ((_propertyFlags & (1 << 15)) > 0)
{
_contentType = EncodingUtils.readShortString(buffer);
}
_decodedContentType = true;
}
private void decodeIfNecessary()
{
if (!_decoded)
{
//decode();
}
}
private void decodeHeadersIfNecessary()
{
if (!_decoded && !_decodedHeaders)
{
decodeUpToHeaders();
}
}
private void decodeContentTypeIfNecessary()
{
if (!_decoded && !_decodedContentType)
{
decodeUpToContentType();
}
}
public String getContentType()
{
decodeContentTypeIfNecessary();
return _contentType;
}
public void setContentType(String contentType)
{
clearEncodedForm();
_propertyFlags |= (1 << 15);
_contentType = contentType;
}
public String getEncoding()
{
decodeIfNecessary();
return _encoding;
}
public void setEncoding(String encoding)
{
clearEncodedForm();
_propertyFlags |= (1 << 14);
_encoding = encoding;
}
public FieldTable getHeaders()
{
decodeHeadersIfNecessary();
return _headers;
}
public void setHeaders(FieldTable headers)
{
clearEncodedForm();
_propertyFlags |= (1 << 13);
_headers = headers;
}
public byte getDeliveryMode()
{
decodeIfNecessary();
return _deliveryMode;
}
public void setDeliveryMode(byte deliveryMode)
{
clearEncodedForm();
_propertyFlags |= (1 << 12);
_deliveryMode = deliveryMode;
}
public byte getPriority()
{
decodeIfNecessary();
return _priority;
}
public void setPriority(byte priority)
{
clearEncodedForm();
_propertyFlags |= (1 << 11);
_priority = priority;
}
public String getCorrelationId()
{
decodeIfNecessary();
return _correlationId;
}
public void setCorrelationId(String correlationId)
{
clearEncodedForm();
_propertyFlags |= (1 << 10);
_correlationId = correlationId;
}
public String getReplyTo()
{
decodeIfNecessary();
return _replyTo;
}
public void setReplyTo(String replyTo)
{
clearEncodedForm();
_propertyFlags |= (1 << 9);
_replyTo = replyTo;
}
public long getExpiration()
{
decodeIfNecessary();
return _expiration;
}
public void setExpiration(long expiration)
{
clearEncodedForm();
_propertyFlags |= (1 << 8);
_expiration = expiration;
}
public String getMessageId()
{
decodeIfNecessary();
return _messageId;
}
public void setMessageId(String messageId)
{
clearEncodedForm();
_propertyFlags |= (1 << 7);
_messageId = messageId;
}
public long getTimestamp()
{
decodeIfNecessary();
return _timestamp;
}
public void setTimestamp(long timestamp)
{
clearEncodedForm();
_propertyFlags |= (1 << 6);
_timestamp = timestamp;
}
public String getType()
{
decodeIfNecessary();
return _type;
}
public void setType(String type)
{
clearEncodedForm();
_propertyFlags |= (1 << 5);
_type = type;
}
public String getUserId()
{
decodeIfNecessary();
return _userId;
}
public void setUserId(String userId)
{
clearEncodedForm();
_propertyFlags |= (1 << 4);
_userId = userId;
}
public String getAppId()
{
decodeIfNecessary();
return _appId;
}
public void setAppId(String appId)
{
clearEncodedForm();
_propertyFlags |= (1 << 3);
_appId = appId;
}
public String getClusterId()
{
decodeIfNecessary();
return _clusterId;
}
public void setClusterId(String clusterId)
{
clearEncodedForm();
_propertyFlags |= (1 << 2);
_clusterId = clusterId;
}
}