public class cMsgMessage
extends java.lang.Object
implements java.lang.Cloneable, java.io.Serializable
This class implements a message in the cMsg messaging system. Each cMsgMessage object contains many different fields. User-settable fields include a time, an int, a text, and a binary array field. However, the most complex field (and thus deserving a full explanation) is the compound payload. In short, the payload allows a string to store messages of arbitrary length and complexity. All types of ints (1,2,4,8 bytes, BigInteger), 4,8-byte floats, strings, binary, whole messages and arrays of all these types can be stored and retrieved from the compound payload. These methods are thread-safe.
Although XML would be a format well-suited to this task, it takes more time and memory to decode XML than a simple format. Thus, a simple, easy-to-parse format was developed to implement the payload. A side benefit is no external XML parsing package is needed.
Following is the text format of a complete compound payload (where [nl] means newline). Each payload consists of a number of items. The very first line is the number of items in the payload. That is followed by the text representation of each item. The first line of each item consists of 5 entries.
Note that there is only 1 space or newline between all entries. The only exception to the 1 space spacing is between the last two entries on each "header" line (the line that contains the item_name). There may be several spaces between the last 2 entries on these lines.
item_count[nl]
for (arrays of) string items:
item_name item_type item_count isSystemItem? item_length[nl]
string_length_1[nl]
string_characters_1[nl]
.
.
.
string_length_N[nl]
string_characters_N
for (arrays of) binary (converted into text) items:
item_name item_type item_count isSystemItem? item_length[nl]
string_length_1 original_binary_byte_length_1 endian_1[nl]
string_characters_1[nl]
.
.
.
string_length_N original_binary_byte_length_N endian_N[nl]
string_characters_N
for primitive type items:
item_name item_type item_count isSystemItem? item_length[nl]
value_1 value_2 ... value_N[nl]
A cMsg message is formatted as a compound payload. Each message has
a number of fields (payload items).
for message items:
_
item_name item_type item_count isSystemItem? item_length[nl] /
message_1_in_compound_payload_text_format[nl] < field_count[nl]
. \ list_of_payload_format_items
. -
.
message_N_in_compound_payload_text_format[nl]
Notice that this format allows a message to store a message which stores a message which stores a message, ad infinitum. In other words, recursive message storing. The item_length in each case is the length in bytes of the rest of the item (not including the newline at the end). Note that accessor methods can return null objects.
Modifier and Type | Field and Description |
---|---|
static int |
allFields
When converting text to message fields, convert all fields.
|
(package private) boolean |
byteArrayCopied
Was the byte array copied in or only a reference assigned?
|
protected byte[] |
bytes
Byte array of message.
|
protected cMsgMessageContextInterface |
context
Object giving info about callback environment.
|
protected static java.text.SimpleDateFormat |
dateFormatter
Object to format and parse date strings.
|
protected java.lang.String |
domain
Message exists in this domain.
|
static int |
expandedPayload
If the message has a compound payload, is the payload only in text form
or has it been expanded into a hashtable of real objects?
Is stored in the 7th bit of info.
|
static int |
hasPayload
Does the message have a compound payload? -- is stored in 6th bit of info.
|
protected int |
info
Condensed information stored in bits.
|
static int |
isBigEndian
Is the byte array data in big endian form? -- stored in 4th bit of info.
|
static int |
isGetRequest
Is message a sendAndGet request? -- stored in 1st bit of info.
|
static int |
isGetResponse
Is message a response to a sendAndGet? -- stored in 2nd bit of info.
|
static int |
isNullGetResponse
Is message null response to a sendAndGet from a responder? -- stored in 3rd bit of info.
|
protected java.util.concurrent.ConcurrentHashMap<java.lang.String,cMsgPayloadItem> |
items
List of payload items.
|
protected int |
length
Length of byte array elements to use.
|
protected boolean |
noHistoryAdditions
If true, do NOT add current sender to message history in payload.
|
static int |
nullGetServerResponse
Does local server have no subscriber to send from sendAndGet?
Is stored in 8rd bit of info.
|
protected int |
offset
Offset into byte array of first element.
|
static int |
payloadFieldsOnly
When converting text to message fields, only convert non-system fields.
|
protected java.lang.String |
payloadText
String representation of the entire payload (including hidden system payload items).
|
protected java.lang.String |
receiver
Name of message receiver.
|
protected java.lang.String |
receiverHost
Host receiver is running on.
|
protected long |
receiverTime
Time message was received in milliseconds from midnight GMT, Jan 1st, 1970.
|
protected boolean |
reliableSend
Should the message be sent with a reliable method (TCP) or is
an unreliable method (UDP) ok?
|
protected int |
reserved
Class member reserved for future use.
|
protected java.lang.String |
sender
Name of message sender (must be unique in some domains).
|
protected java.lang.String |
senderHost
Host sender is running on.
|
protected long |
senderTime
Time message was sent in milliseconds from midnight GMT, Jan 1st, 1970.
|
protected int |
senderToken
Field used by domain server in implementing "sendAndGet".
|
protected java.lang.String |
subject
Subject of message.
|
protected int |
sysMsgId
Unique message intVal created by cMsg system.
|
static int |
systemFieldsOnly
When converting text to message fields, only convert system fields.
|
protected java.lang.String |
text
Text of message.
|
protected java.lang.String |
type
Type of message.
|
protected int |
userInt
Integer supplied by user.
|
protected long |
userTime
Time supplied by user in milliseconds from midnight GMT, Jan 1st, 1970.
|
protected int |
version
Version number of cMsg.
|
static int |
wasSent
Has the message been sent over the wire? -- is stored in 5th bit of info.
|
Constructor and Description |
---|
cMsgMessage()
The constructor for a blank message.
|
cMsgMessage(cMsgMessage msg)
The constructor which copies a given message.
|
Modifier and Type | Method and Description |
---|---|
java.lang.String |
addHistoryToPayloadText(java.lang.String sendersName,
java.lang.String sendersHost,
long sendersTime)
This method creates a string representation out of the existing payload text and the
given history parameters made into payload items together.
|
void |
addPayloadItem(cMsgPayloadItem item)
Adds an item to the payload.
|
void |
clearPayload()
Clears the payload of all user-added items.
|
java.lang.Object |
clone()
Cloning this object does not pass on the context and copies the byte array if it exists.
|
cMsgMessage |
copy()
Creates a complete copy of this message.
|
static void |
copy(cMsgMessage src,
cMsgMessage dst)
This method turns the destination message into a complete copy of the source message.
|
void |
copyPayload(cMsgMessage msg)
Copy only the payload of the given message, overwriting
the existing payload.
|
(package private) java.lang.String |
createPayloadText(java.util.Map<java.lang.String,cMsgPayloadItem> map)
This method creates a string representation out of a given map of payload items
with names as keys.
|
(package private) static java.lang.String |
escapeAllForXML(java.lang.String s)
This method escapes the chars <, >, " for putting strings into XML.
|
(package private) static java.lang.String |
escapeCdataForXML(java.lang.String s)
This method escapes CDATA constructs which will appear inside of XML CDATA sections.
|
(package private) static java.lang.String |
escapeQuotesForXML(java.lang.String s)
This method escapes the " char for putting strings into XML.
|
protected void |
expandPayload()
If this message is unexpanded (has a non-null payloadText field but
no items in its payload hashmap), then expand the payload text into
a hashmap containing all cMsgPayloadItems.
|
byte[] |
getByteArray()
Get byte array of message.
|
int |
getByteArrayEndian()
Get endianness of the byte array data.
|
int |
getByteArrayLength()
Get byte array length of region of interest.
|
int |
getByteArrayLengthFull()
Get full length of the byte array or 0 if it is null.
|
int |
getByteArrayOffset()
Get byte array index to region of interest.
|
cMsgMessageContextInterface |
getContext()
Gets the object containing information about the context of the
callback receiving this message.
|
java.lang.String |
getDomain()
Get domain this message exists in.
|
int |
getHistoryLengthMax()
Gets the maximum number of entries this message keeps of its history of various parameters.
|
int |
getInfo()
Gets information compacted into a bit pattern.
|
java.lang.String |
getItemsText()
This method creates a string of all the payload items concatonated.
|
cMsgPayloadItem |
getPayloadItem(java.lang.String name)
Get a single, named payload item.
|
java.util.Map<java.lang.String,cMsgPayloadItem> |
getPayloadItems()
Gets an unmodifiable (read only) hashmap of all payload items.
|
java.util.Set<java.lang.String> |
getPayloadNames()
Get the set of payload item names (may be empty set).
|
int |
getPayloadSize()
Get the number of items in the payload.
|
java.lang.String |
getPayloadText()
Gets the String representation of the compound payload of this message.
|
java.lang.String |
getReceiver()
Get message receiver.
|
java.lang.String |
getReceiverHost()
Get message receiver's host computer.
|
java.util.Date |
getReceiverTime()
Get time message was received.
|
boolean |
getReliableSend()
Gets whether the send will be reliable (default, TCP)
or will be allowed to be unreliable (UDP).
|
java.lang.String |
getSender()
Get message sender.
|
java.lang.String |
getSenderHost()
Get message sender's host computer.
|
java.util.Date |
getSenderTime()
Get time message was sent.
|
int |
getSenderToken()
Get sender's token.
|
java.lang.String |
getSubject()
Get subject of message.
|
int |
getSysMsgId()
Get system intVal of message.
|
java.lang.String |
getText()
Get text of message.
|
java.lang.String |
getType()
Get type of message.
|
int |
getUserInt()
Get user supplied integer.
|
java.util.Date |
getUserTime()
Get user supplied time.
|
int |
getVersion()
Gets the version number of this message which is the same
as that of the cMsg software package that created it.
|
boolean |
hasPayload()
Does this message have a payload?
|
protected void |
hasPayload(boolean hp)
Set the "has-a-compound-payload" bit of a message.
|
(package private) static int |
hexStrToInt(java.lang.String hex,
boolean zeroSup)
Method to convert 8 hex characters into a int value.
|
(package private) static long |
hexStrToLong(java.lang.String hex,
boolean zeroSup)
Method to convert 16 hex characters into a long value.
|
(package private) static short |
hexStrToShort(java.lang.String hex,
boolean zeroSup)
Method to convert 4 hex characters into a short value.
|
protected boolean |
isExpandedPayload()
Does this message have a payload that consists of objects in a hashmap
(ie.
|
boolean |
isGetRequest()
Is this message a "sendAndGet" request?
|
boolean |
isGetResponse()
Is this message a response to a "sendAndGet" message?
|
boolean |
isNullGetResponse()
Is this message a null response to a "sendAndGet" message?
|
protected boolean |
isNullGetServerResponse()
Is this message a result of the local server having no subscribers
to the send part of a sendAndGet?
|
void |
makeNullResponse(cMsgMessage msg)
Converts existing message to null response of supplied message.
|
void |
makeResponse(cMsgMessage msg)
Converts existing message to response of supplied message.
|
boolean |
needToSwap()
This method specifies whether the endian value of the byte array is little
endian or not.
|
boolean |
noHistoryAdditions()
Does the message record sender history (assuming history length max is not exceeded)?
|
cMsgMessage |
nullResponse()
Creates a proper response message to this message which was sent by a client calling
sendAndGet.
|
void |
payloadPrintout(int level)
This method prints out the message payload in a readable form.
|
java.lang.String |
payloadToString()
This method converts the message payload to a printable string in XML format.
|
boolean |
removePayloadItem(cMsgPayloadItem item)
Remove an item from the payload.
|
boolean |
removePayloadItem(java.lang.String name)
Remove an item from the payload.
|
void |
resetByteArrayLength()
Reset the byte array length to the full length of the array or zero if
there is none.
|
void |
resetPayload()
Clears the payload of all items including system items.
|
cMsgMessage |
response()
Creates a proper response message to this message which was sent by a client calling
sendAndGet.
|
void |
setByteArray(byte[] b)
Copy byte array into message.
|
void |
setByteArray(byte[] b,
int offset,
int length)
Copy byte array into message by copying "length" number of elements
starting at "offset".
|
void |
setByteArray(java.nio.ByteBuffer buf)
Copy buffer data into message's byte array.
|
void |
setByteArrayEndian(int endian)
Set endianness of the byte array data.
|
void |
setByteArrayLength(int length)
Set byte array length of data of interest.
|
void |
setByteArrayNoCopy(byte[] b)
Set byte array to the given argument without copying the byte array
itself - only the reference is copied.
|
void |
setByteArrayNoCopy(byte[] b,
int offset,
int length)
Set byte array to the given argument without copying the byte array
itself - only the reference is copied.
|
void |
setByteArrayOffset(int offset)
Set byte array index to region of interest.
|
protected void |
setExpandedPayload(boolean ep)
Set the "expanded-payload" bit of a message.
|
protected int |
setFieldsFromText(java.lang.String text,
int flag)
This method takes a string representation of the whole compound payload,
including the system (hidden) fields of the message,
as it gets sent over the network and converts it into the standard message
payload.
|
void |
setGetResponse(boolean getResponse)
Specify whether this message is a response to a "sendAndGet" message.
|
void |
setHistoryLengthMax(int historyLengthMax)
Sets the maximum number of entries this message keeps of its history of various parameters.
|
void |
setNullGetResponse(boolean nullGetResponse)
Specify whether this message is a null response to a "sendAndGet" message.
|
protected void |
setNullGetServerResponse(boolean ngsr)
Set the "nullGetServerResponse" bit of a message.
|
void |
setReliableSend(boolean b)
Sets whether the send will be reliable (default, TCP)
or will be allowed to be unreliable (UDP).
|
void |
setSubject(java.lang.String subject)
Set subject of message.
|
void |
setText(java.lang.String text)
Set text of message.
|
void |
setType(java.lang.String type)
Set type of message.
|
void |
setUserInt(int userInt)
Set message sender's intVal.
|
void |
setUserTime(java.util.Date time)
Set time.
|
void |
setUserTime(long time)
Set time.
|
java.lang.String |
toString()
This method converts the message to a printable string in XML format.
|
java.lang.String |
toString(boolean binary,
boolean compact,
boolean noSystemFields)
This method converts the message to a printable string in XML format.
|
void |
updatePayloadText()
This method creates a string representation of the whole compound
payload and the hidden system fields (currently fields describing
the history of the message being sent) of the message and stores
it in the
payloadText member. |
public static final int isGetRequest
public static final int isGetResponse
public static final int isNullGetResponse
public static final int isBigEndian
public static final int wasSent
public static final int hasPayload
public static final int expandedPayload
public static final int nullGetServerResponse
public static final int systemFieldsOnly
public static final int payloadFieldsOnly
public static final int allFields
protected static final transient java.text.SimpleDateFormat dateFormatter
boolean byteArrayCopied
protected int sysMsgId
protected java.lang.String domain
protected int info
protected int version
protected int reserved
protected java.lang.String subject
protected java.lang.String type
protected java.lang.String text
protected int userInt
protected long userTime
protected byte[] bytes
protected int offset
protected int length
protected transient java.util.concurrent.ConcurrentHashMap<java.lang.String,cMsgPayloadItem> items
protected java.lang.String payloadText
protected transient boolean noHistoryAdditions
protected java.lang.String sender
protected java.lang.String senderHost
protected long senderTime
protected int senderToken
protected java.lang.String receiver
protected java.lang.String receiverHost
protected long receiverTime
protected boolean reliableSend
protected transient cMsgMessageContextInterface context
public cMsgMessage()
public cMsgMessage(cMsgMessage msg)
msg
- message to be copiedpublic java.lang.Object clone()
clone
in class java.lang.Object
public static void copy(cMsgMessage src, cMsgMessage dst)
src
- message to be copieddst
- message to be copied topublic cMsgMessage copy()
public cMsgMessage response() throws cMsgException
cMsgException
- if this message was not sent from a "sendAndGet" method callpublic cMsgMessage nullResponse() throws cMsgException
cMsgException
- if this message was not sent from a "sendAndGet" method callpublic void makeResponse(cMsgMessage msg)
msg
- message this message will be made a response topublic void makeNullResponse(cMsgMessage msg)
msg
- message this message will be made a null response topublic boolean noHistoryAdditions()
public int getHistoryLengthMax()
public void setHistoryLengthMax(int historyLengthMax) throws cMsgException
historyLengthMax
- the maximum number of entries this message keeps of its history of various parameterscMsgException
- if historyLengthMax is < 0 or > historyLengthAbsoluteMaxpublic int getSysMsgId()
public java.lang.String getDomain()
public boolean isGetResponse()
public void setGetResponse(boolean getResponse)
getResponse
- true if this message is a response to a "sendAndGet" messagepublic boolean isNullGetResponse()
public void setNullGetResponse(boolean nullGetResponse)
nullGetResponse
- true if this message is a null response to a "sendAndGet" messagepublic boolean isGetRequest()
public int getInfo()
public int getVersion()
public java.lang.String getSubject()
public void setSubject(java.lang.String subject)
subject
- subject of message.public java.lang.String getType()
public void setType(java.lang.String type)
type
- type of message.public java.lang.String getText()
public void setText(java.lang.String text)
text
- text of message.public int getUserInt()
public void setUserInt(int userInt)
userInt
- message sender's intVal.public java.util.Date getUserTime()
public void setUserTime(java.util.Date time)
time
- time ad Date object.public void setUserTime(long time)
time
- time as long (amount of millisec since Jan 1 1970, 12am, GMT)public byte[] getByteArray()
public void setByteArray(byte[] b)
b
- byte array of message.public void setByteArray(byte[] b, int offset, int length) throws cMsgException
b
- byte array of message.offset
- index into byte array to bytes to be copied.length
- number of bytes to be copied.cMsgException
- if length, offset, or offset+length is out of array boundspublic void setByteArray(java.nio.ByteBuffer buf) throws cMsgException
buf
- ByteBuffer with data for byte array of message.cMsgException
- if length, offset, or offset+length is out of array boundspublic void setByteArrayNoCopy(byte[] b)
b
- byte array of message.public void setByteArrayNoCopy(byte[] b, int offset, int length) throws cMsgException
b
- byte array of message.offset
- index into byte array to bytes of interest.length
- number of bytes of interest.cMsgException
- if length, offset, or offset+length is out of array boundspublic int getByteArrayLength()
public int getByteArrayLengthFull()
public void setByteArrayLength(int length) throws cMsgException
length
- of byte array's data of interest.cMsgException
- if length or offset+length is out of array boundspublic void resetByteArrayLength()
public int getByteArrayOffset()
public void setByteArrayOffset(int offset) throws cMsgException
offset
- index to byte array's data of interest.cMsgException
- if offset or offset+length is out of array boundspublic int getByteArrayEndian()
cMsgConstants.endianBig
or cMsgConstants.endianLittle
)public void setByteArrayEndian(int endian) throws cMsgException
cMsgConstants.endianBig
for a big endian
cMsgConstants.endianLittle
for a little endian
cMsgConstants.endianLocal
for same endian as local host
cMsgConstants.endianNotLocal
for opposite endian as local host
cMsgConstants.endianSwitch
for opposite current endian
endian
- endianness of the byte array datacMsgException
- if argument invalid valuepublic boolean needToSwap()
public java.lang.String getSender()
public java.lang.String getSenderHost()
public java.util.Date getSenderTime()
public int getSenderToken()
public java.lang.String getReceiver()
public java.lang.String getReceiverHost()
public java.util.Date getReceiverTime()
public void setReliableSend(boolean b)
b
- false if using UDP, or true if using TCPpublic boolean getReliableSend()
public cMsgMessageContextInterface getContext()
static java.lang.String escapeAllForXML(java.lang.String s)
s
- string to be escapedstatic java.lang.String escapeQuotesForXML(java.lang.String s)
s
- string to be escapedstatic java.lang.String escapeCdataForXML(java.lang.String s)
This method escapes CDATA constructs which will appear inside of XML CDATA sections. It is not possible to have nested cdata sections. Actually the CDATA ending sequence, ]]> , is what cannot be containing in a surrounding CDATA section. This restriction can be cleverly circumvented by inserting "<![CDATA[]]]]><![CDATA[>" after each CDATA ending sequence. This creates independent CDATA sections which are not nested.
This method assumes that there are no nested cdata sections in the input string. Nothing is done to the string if:s
- string to be escapedpublic java.lang.String toString()
toString
in class java.lang.Object
public java.lang.String toString(boolean binary, boolean compact, boolean noSystemFields)
binary
- includes binary as ASCII if true, else binary is ignoredcompact
- if true, do not include attributes with null or default integer valuesnoSystemFields
- if true, do not include system (metadata) payload fieldspublic java.lang.String payloadToString() throws cMsgException
cMsgException
- if payload is not expandedstatic final long hexStrToLong(java.lang.String hex, boolean zeroSup)
hex
- string to convertzeroSup
- first char is "Z" for zero suppression so only
convert next 15 charsstatic final int hexStrToInt(java.lang.String hex, boolean zeroSup)
hex
- string to convertzeroSup
- first char is "Z" for zero suppression so only
convert next 7 charsstatic final short hexStrToShort(java.lang.String hex, boolean zeroSup)
hex
- string to convertzeroSup
- first char is "Z" for zero suppression so only
convert next 3 charsprotected boolean isNullGetServerResponse()
protected void setNullGetServerResponse(boolean ngsr)
ngsr
- boolean which is true if msg is result of the local server
having no subscribers to the send part of a sendAndGet, else false.public void copyPayload(cMsgMessage msg)
msg
- message to copy payload frompublic java.lang.String getPayloadText()
public boolean hasPayload()
protected void hasPayload(boolean hp)
hp
- boolean which is true if msg has a compound payload, else is false (no payload)protected boolean isExpandedPayload()
protected void setExpandedPayload(boolean ep)
ep
- boolean which is true if msg has an expanded payload, else falseprotected void expandPayload()
public java.util.Map<java.lang.String,cMsgPayloadItem> getPayloadItems()
public void resetPayload()
public void clearPayload()
public void addPayloadItem(cMsgPayloadItem item)
item
- item to add to payloadpublic boolean removePayloadItem(cMsgPayloadItem item)
item
- item to remove from the payloadpublic boolean removePayloadItem(java.lang.String name)
name
- name of the item to remove from the payloadpublic cMsgPayloadItem getPayloadItem(java.lang.String name)
name
- name of item to retrievepublic java.util.Set<java.lang.String> getPayloadNames()
public int getPayloadSize()
public void updatePayloadText()
payloadText
member.
This string is used for sending the payload over the network.java.lang.String createPayloadText(java.util.Map<java.lang.String,cMsgPayloadItem> map)
map
- a map of payload items to be turned into a string representationpublic java.lang.String addHistoryToPayloadText(java.lang.String sendersName, java.lang.String sendersHost, long sendersTime)
When a client sends the same message over and over again, we do NOT want the history to change. To ensure this, we follow a simple principle: the sender history needs to go into the sent message (ie. over the wire), but must not be added to the local one. Thus, if I send a message, its local sender history will not change.
sendersName
- name to be added to history of senderssendersHost
- host to be added to history of sender hostssendersTime
- time to be added to history of sender timespublic java.lang.String getItemsText()
protected int setFieldsFromText(java.lang.String text, int flag) throws cMsgException
text
- string sent over network to be unmarshalledflag
- if systemFieldsOnly
, set system msg fields only,
if payloadFieldsOnly
set payload msg fields only,
and if allFields
set bothcMsgException
- if the text is in a bad format or the text arg is nullpublic void payloadPrintout(int level)
level
- level of indentation (0 = normal)