Progress
External Program
Interfaces


Message Objects

The following sections describe the functions and procedures of the Message Objects, including message headers, message properties, and the various message types.

Message Header Interface

The message header provides envelope information about a message. The message header interface is supported by all message types and all message types have the same header information. Header information is the same for both PTP and Pub/Sub messaging.

The message header is not created directly by the application. When any type of message is created, its header procedure is automatically created. The message procedure delegates header method calls to its header procedure.

All the fields of the header can be seen by either the sender or receiver:

Setting Message Header Information

Header information is:

The following procedure sets a destination for replies. Note that the destination can be a name of a queue even if the message is sent by a Pub/Sub session and the destination can be the name of the topic even if the message is sent by a PTP session. However, in that case, setReplyToDestinationType must be called to set the correct destination type:

SYNTAX
PROCEDURE setJMSReplyTo 
DEFINE INPUT PARAMETER destination AS CHAR. 

The following procedure sets the type of the destination specified by setJMSReplyTo; the type can be “queue” or “topic” If setReplyToDestinationType is not called, a default type is automatically set when the message is sent, according to the type of the session:

SYNTAX
PROCEDURE setReplyToDestinationType 
DEFINE INPUT PARAMETER type AS CHAR. 

The following procedure sets the correlationID. This value is application-defined; typically it is set to the ID of the message replied to:

SYNTAX
PROCEDURE setJMSCorrelationID 
DEFINE INPUT PARAMETER correlationID AS CHAR. 

The following procedure sets the bytes correlationID; the bytesCorrelation ID usage is proprietary (JMS provider-dependent). (A JMS provider is a messaging system that implements the JMS interface.) When accessing SonicMQ, the bytesCorrelationID field can be used for storing application-defined values:

SYNTAX
PROCEDURE setJMSCorrelationIDAsBytes 
DEFINE INPUT PARAMETER bytesCorrelationID AS RAW. 

The following procedure sets the type name; the type name is proprietary (JMS provider-dependent). When accessing SonicMQ, the JMSType field can be used for storing application-defined values:

SYNTAX
PROCEDURE setJMSType 
DEFINE INPUT PARAMETER typeName AS CHAR. 

Getting Message Header Information

The following functions return message header information.

The following function returns the SonicMQ Adapter message type: TextMessage, MapMessage, StreamMessage, BytesMessage, HeaderMessage, or XMLMessage:

SYNTAX
FUNCTION getMessageType RETURNS CHAR. 

The following function returns the message ID, a unique ID that the JMS server assigns to each message:

SYNTAX
FUNCTION getJMSMessageID RETURNS CHAR. 

The following function returns the message sending time, which is the difference in milliseconds between the message creation time and midnight, January 1, 1970 UTC:

SYNTAX
FUNCTION getJMSTimestamp RETURNS DECIMAL. 

The following function returns the name of the destination this message was sent to. The value is valid after the message was sent (at the sender side) and in the received message (at the receiver side):

SYNTAX
FUNCTION getJMSDestination RETURNS CHAR. 

The following function returns true (at the receiver side) if this is not the first delivery of this message. A second delivery can take place if the first delivery is not acknowledged by the receiver or the transaction was rolled back, in a transacted session:

SYNTAX
FUNCTION getJMSRedelivered RETURNS LOGICAL. 

The following function returns the correlationID. This value is application-defined, typically the ID of the message replied to:

SYNTAX
FUNCTION getJMSCorrelationID RETURNS CHAR. 

The following function returns a proprietary (JMS provider-dependent) correlation ID. When accessing SonicMQ, the bytesCorrelationID field can be used for storing application-defined values:

SYNTAX
FUNCTION getJMSCorrelationIDAsBytes RETURNS RAW. 

The following function returns the delivery mode. This value is PERSISTENT, NON_PERSISTENT, or DISCARDABLE. The message receiver never gets the NON_PERSISTENT_ASYNC value. A message sent using NON_PERSISTENT_ASYNC is received with the standard NON_PERSISTENT value:

SYNTAX
FUNCTION getJMSDeliveryMode RETURNS CHAR. 

The following function returns the reply destination. The destination can be the name of a queue, even if the message is received from a Pub/Sub session, and the destination can be the name of a topic even if the message is received from a PTP session. The replyToDestinationType function must be called if both a queue destination and a topic destination might be stored in the received message:

SYNTAX
FUNCTION getJMSReplyTo RETURNS CHAR. 

The following function returns “queue,” “topic,” or UNKNOWN. The UNKNOWN value is returned if the message was just created, not sent yet, and setReplyToDestinationType was not called. Call getReplyToDestinationType when the domain of the ReplyTo field is not known:

SYNTAX
FUNCTION getReplyToDestinationType RETURNS CHAR. 

The following function returns a proprietary (JMS provider-dependent) type name. When accessing SonicMQ, the JMSType field can be used for storing application-defined values:

SYNTAX
FUNCTION getJMSType RETURNS CHAR. 

The following function returns the expiration time (GMT):

SYNTAX
FUNCTION getJMSExpiration RETURNS DECIMAL. 

The following function returns priority values in the range of 0–9:

SYNTAX
FUNCTION getJMSPriority RETURNS int. 

The following function returns true if the JMSReplyTo header was set:

SYNTAX
FUNCTION hasReplyTo RETURNS LOGICAL. 

Message Properties

Message properties can add more envelope information about a message. There is a fixed number of header fields, but properties are flexible. An application can add any number of properties—property name and value pairs.

The following function returns the message property’s data type. UNKNOWN is returned if the property was not set in the message:

SYNTAX
FUNCTION getPropertyType RETURNS CHAR (propertyName AS CHAR). 

The following function returns a comma-separated list of the properties of the message:

SYNTAX
FUNCTION getPropertyNames RETURNS CHAR. 

Setting Message Properties

The following procedures set message properties.

NOTE: The server returns a NumberFormatException message for value overflows (for example, if setByteProperty(“prop1”, 1000) is called).

The following procedure sets a boolean message property. An UNKNOWN value is considered a false value:

SYNTAX
PROCEDURE setBooleanProperty. 
DEFINE INPUT PARAMETER propertyName AS CHAR. 
DEFINE INPUT PARAMETER propertyValue AS LOGICAL. 

The following procedure sets a bytes message property; the values range from –128 to 127:

SYNTAX
PROCEDURE setByteProperty. 
DEFINE INPUT PARAMETER propertyName AS CHAR. 
DEFINE INPUT PARAMETER propertyValue AS INT. 

The following procedure sets a short message property:

SYNTAX
PROCEDURE setShortProperty. 
DEFINE INPUT PARAMETER propertyName AS CHAR. 
DEFINE INPUT PARAMETER propertyValue AS INT. 

The following procedure sets an int message property:

SYNTAX
PROCEDURE setIntProperty. 
DEFINE INPUT PARAMETER propertyName AS CHAR. 
DEFINE INPUT PARAMETER propertyValue AS INT. 

The following procedure sets a long message property; any fractional part of the DECIMAL value is truncated:

SYNTAX
PROCEDURE setLongProperty. 
DEFINE INPUT PARAMETER propertyName AS CHAR. 
DEFINE INPUT PARAMETER propertyValue AS DECIMAL. 

The following procedure sets a float message property:

SYNTAX
PROCEDURE setFloatProperty. 
DEFINE INPUT PARAMETER propertyName AS CHAR. 
DEFINE INPUT PARAMETER propertyValue AS DECIMAL. 

The following procedure sets a double message property:

SYNTAX
PROCEDURE setDoubleProperty. 
DEFINE INPUT PARAMETER propertyName AS CHAR. 
DEFINE INPUT PARAMETER propertyValue AS DECIMAL. 

The following procedure sets a String message property:

SYNTAX
PROCEDURE setStringProperty. 
DEFINE INPUT PARAMETER propertyName AS CHAR. 
DEFINE INPUT PARAMETER propertyValue AS CHAR. 

The following procedure clears the body of a message and keeps header and property values unchanged. This procedure transfers a StreamMessage, TextMessage, XMLMessage, and a BytesMessage to write-only mode:

SYNTAX
PROCEDURE clearBody. 

The following procedure clears the properties of the message, keeping header and body values unchanged:

SYNTAX
PROCEDURE clearProperties. 

Getting Message Properties

The following function returns a boolean message property:

SYNTAX
FUNCTION getLogicalProperty RETURNS LOGICAL (propertyName AS CHAR). 

The following function returns int, short, and byte message properties:

SYNTAX
FUNCTION getIntProperty RETURNS INT (propertyName AS CHAR). 

The following function returns any numeric message property:

SYNTAX
FUNCTION getDecimalProperty RETURNS DECIMAL (propertyName AS CHAR). 

The following function returns a message property of any data type:

SYNTAX
FUNCTION getCharProperty RETURNS CHAR (propertyName AS CHAR). 

Deleting Messages

The following procedure deletes a message:

SYNTAX
PROCEDURE deleteMessage. 

Maximum Number Of Messages

The default maximum number of JMS messages in a 4GL session is 50 (the total number of messages created by the application plus messages received from JMS). To change the default to new–val, the following definition must be included in the main procedure of the 4GL application:

SYNTAX
DEFINE NEW GLOBAL SHARED VAR JMS-MAXIMUM-MESSAGES AS INT INIT new-val. 

Error Display

If setNoErrorDisplay is set to true, messages from errors that occur when methods in a message are called are not automatically displayed. The default value is false. Messages inherit the display/noDisplay property from the session that created them. However, after the message is created, it is independent from the session, and setNoErrorDisplay must be called in the message itself to change the display/noDisplay property:

SYNTAX
PROCEDURE setNoErrorDisplay. 
DEFINE INPUT PARAMETER noDisplay AS LOGICAL. 

Message Handler

The message handler is written by an application and must be registered with the Message Consumer object. When a message is received, the message handler is called automatically so the application can process the message.

The messageHandler parameters are:

The 4GL programmer implements procedures with the following signature for handling incoming messages (JMS messages and error messages):

SYNTAX
PROCEDURE messageHandler. 
DEFINE INPUT PARAMETER message AS HANDLE.       
DEFINE INPUT PARAMETER messageConsumer AS HANDLE.  
DEFINE OUTPUT PARAMETER reply AS HANDLE. 

TextMessage

An application creates a TextMessage by calling createTextMessage in a Session object with the following output parameter:

SYNTAX
PROCEDURE createTextMessage. 
DEFINE OUTPUT PARAMETER messageHandle AS HANDLE. 

The following function returns the total number of characters in the message:

SYNTAX
FUNCTION getCharCount RETURNS INT. 

The following function returns true if the last text segment was retrieved:

SYNTAX
FUNCTION endOfStream RETURNS LOGICAL. 

When a TextMessage is created, it is in a write-only mode. Calling reset changes the mode to read-only and places the cursor before the first text segment. Sending the message causes an implicit reset and the message becomes read-only. The message arrives at the receiver in a reset state:

SYNTAX
PROCEDURE reset. 

Setting Text

The following procedure clears the message body and sets a new text value. The call can be made when the message is in write-only or read-only mode. After the call, the message is in write-only mode and additional appendText calls can be made to append more text:

SYNTAX
PROCEDURE setText. 
DEFINE INPUT PARAMETER textValue AS CHAR. 

The following procedure can be called in write-only mode to append text to the message in several calls to overcome the Progress 32K limit on the number of characters:

SYNTAX
PROCEDURE appendText. 
DEFINE INPUT PARAMETER textValue AS CHAR. 

Getting Text

The following function returns all the text in the TextMessage and then implicitly calls reset. A run-time error occurs if the size of the message is too large to be handled by the 4GL interpreter:

SYNTAX
FUNCTION getText RETURNS CHAR. 

The following function can be called in read-only mode to return the next text segment when handling large messages:

SYNTAX
FUNCTION getTextSegment RETURNS CHAR. 

Header Messages

A HeaderMessage is a message type that is the 4GL–JMS equivalent of Java’s javax.jms.Message, a header-only message. It sends information through message properties without a message body.

An application creates a HeaderMessage by calling createHeaderMessage in a Session object with the following output parameter:

SYNTAX
PROCEDURE createHeaderMessage. 
DEFINE OUTPUT PARAMETER messageHandle AS HANDLE. 

StreamMessage

A StreamMessage allows applications to send and receive an unspecified number of items; each item is a Java data type. All basic Java data types are supported. When receiving any arbitrary Java data type, an application uses methods to read and specify a Progress data type. When writing a message from the Progress 4GL, an application uses methods to send any of those Java data types and to specify the data.

To create a StreamMessage, an application calls createStreamMessage in a session object with the following output parameter:

SYNTAX
PROCEDURE createStreamMessage. 
DEFINE OUTPUT PARAMETER messageHandle AS HANDLE. 

When a StreamMessage is created, it is in a write-only mode. The following procedure changes the mode to read-only. Sending the message causes an implicit reset. The message arrives at the receiver in a reset mode:

SYNTAX
PROCEDURE reset. 

The following function returns true if the last item of the stream was retrieved:

SYNTAX
FUNCTION endOfStream RETURNS LOGICAL. 

Writing Data To a StreamMessage

The following procedures write data to the body of a StreamMessage.

NOTE: The server returns a NumberFormatException message for a value overflow, for example, if writeByte(1000) is called.

The following procedure writes boolean data to the body of a StreamMessage. An UNKNOWN value is considered false:

SYNTAX
PROCEDURE writeBoolean. 
DEFINE INPUT PARAMETER value AS LOGICAL. 

The following procedure writes bytes data to the body of a StreamMessage; byte values are –128 to 127:

SYNTAX
PROCEDURE writeByte. 
DEFINE INPUT PARAMETER value AS INT. 

The following procedure writes short data to the body of a StreamMessage:

SYNTAX
PROCEDURE writeShort. 
DEFINE INPUT PARAMETER value AS INT. 

The following procedure writes character data to the body of a StreamMessage; the number of characters in the CHAR value must be one:

SYNTAX
PROCEDURE writeChar. 
DEFINE INPUT PARAMETER value AS CHAR. 

The following procedure writes integer data to the body of a StreamMessage:

SYNTAX
PROCEDURE writeInt. 
DEFINE INPUT PARAMETER value AS INT. 

The following procedure writes long data to the body of a StreamMessage. The fractional part of the DECIMAL value is truncated:

SYNTAX
PROCEDURE writeLong. 
DEFINE INPUT PARAMETER value AS DECIMAL. 

The following procedure writes float data to the body of a StreamMessage:

SYNTAX
PROCEDURE writeFloat. 
DEFINE INPUT PARAMETER value AS DECIMAL. 

The following procedure writes double data to the body of a StreamMessage:

SYNTAX
PROCEDURE writeDouble. 
DEFINE INPUT PARAMETER value AS DECIMAL. 

The following procedure writes String data to the body of a StreamMessage:

SYNTAX
PROCEDURE writeString. 
DEFINE INPUT PARAMETER value AS CHAR. 

The following procedure writes bytes data to the body of a StreamMessage:

SYNTAX
PROCEDURE writeBytesFromRaw. 
DEFINE INPUT PARAMETER value AS RAW. 

Reading Data From a StreamMessage

The following functions read data from the body of a StreamMessage.

The following function moves the cursor to the next data item and returns its data type, one of the following values: UNKNOWN, boolean, byte, short, char, int, long, float, double, string, or bytes. UNKNOWN is returned when the value of the item is NULL. When the message is received or after reset is called, the cursor is set before the first data item. It is an error to try to move the cursor beyond the last item:

SYNTAX
FUNCTION moveToNext RETURNS CHAR. 

The following function returns boolean data from the body of a StreamMessage:

SYNTAX
FUNCTION readLogical RETURNS LOGICAL. 

The following function returns int, short, or bytes data from the body of a StreamMessage:

SYNTAX
FUNCTION readInt RETURNS INT. 

The following function returns any numeric data from the body of a StreamMessage:

SYNTAX
FUNCTION readDecimal RETURNS DECIMAL. 

The following function returns any data except bytes data from the body of a StreamMessage:

SYNTAX
FUNCTION readChar RETURNS CHAR. 

The following function returns bytes data from the body of a StreamMessage:

SYNTAX
FUNCTION readBytesToRaw RETURNS RAW. 

MapMessage

A MapMessage contains multiple pairs of item names and item values. When setting the data, the application specifies the Java data type. When getting the data, the application specifies the 4GL data type to convert into. For more information on mapping data types, see the "Data Storage and Extraction Methods" section in this chapter.

An application creates a MapMessage by calling createMapMessage in a Session object with the following output parameter:

SYNTAX
PROCEDURE createMapMessage. 
DEFINE OUTPUT PARAMETER messageHandle AS HANDLE. 

The following function returns a comma-separated list of the item names in a MapMessage:

SYNTAX
FUNCTION getMapNames RETURNS CHAR. 

The following function returns the data type of an item in a MapMessage. UNKNOWN is returned if the item does not exist:

SYNTAX
FUNCTION getItemType RETURNS CHAR (itemName AS CHAR). 

Setting Items In a MapMessage

A MapMessage supports setting multiple named item pairs: {item-name, item-value}. The following procedures convert data from 4GL to JMS data types.

NOTE: The server returns a NumberFormatException message for a value overflow, for example, if setByte(“item1”, 1000) is called.

The following procedure sets boolean data in a MapMessage. An UNKNOWN value is considered false:

SYNTAX
PROCEDURE setBoolean. 
DEFINE INPUT PARAMETER itemName AS CHAR. 
DEFINE INPUT PARAMETER value AS LOGICAL. 

The following procedure sets bytes data in a MapMessage; byte values are –128 to 127:

SYNTAX
PROCEDURE setByte. 
DEFINE INPUT PARAMETER itemName AS CHAR. 
DEFINE INPUT PARAMETER value AS INT. 

The following procedure sets short data in a MapMessage:

SYNTAX
PROCEDURE setShort. 
DEFINE INPUT PARAMETER itemName AS CHAR. 
DEFINE INPUT PARAMETER value AS INT. 

The following procedure sets character data in a MapMessage; the number of characters in the CHAR value must be one:

SYNTAX
PROCEDURE setChar. 
DEFINE INPUT PARAMETER itemName AS CHAR. 
DEFINE INPUT PARAMETER value AS CHAR. 

The following procedure sets integer data in a MapMessage:

SYNTAX
PROCEDURE setInt. 
DEFINE INPUT PARAMETER itemName AS CHAR. 
DEFINE INPUT PARAMETER value AS INT. 

The following procedure sets long data in a MapMessage; any fractional part of the DECIMAL value is truncated:

SYNTAX
PROCEDURE setLong. 
DEFINE INPUT PARAMETER itemName AS CHAR. 
DEFINE INPUT PARAMETER value AS DECIMAL. 

The following procedure sets float data in a MapMessage:

SYNTAX
PROCEDURE setFloat. 
DEFINE INPUT PARAMETER itemName AS CHAR. 
DEFINE INPUT PARAMETER value AS DECIMAL. 

The following procedure sets double data in a MapMessage:

SYNTAX
PROCEDURE setDouble. 
DEFINE INPUT PARAMETER itemName AS CHAR. 
DEFINE INPUT PARAMETER value AS DECIMAL. 

The following procedure sets String data in a MapMessage:

SYNTAX
PROCEDURE setString. 
DEFINE INPUT PARAMETER itemName AS CHAR. 
DEFINE INPUT PARAMETER value AS CHAR. 

The following procedure sets bytes data in a MapMessage:

SYNTAX
PROCEDURE setBytesFromRaw. 
DEFINE INPUT PARAMETER itemName AS CHAR. 
DEFINE INPUT PARAMTER values AS RAW. 

Getting Item Values By Name In a MapMessage

A MapMessage supports getting multiple named item pairs: {item-name, item-value}. The following functions convert data from JMS data types to 4GL data types.

The following function gets a boolean item from a MapMessage:

SYNTAX
FUNCTION getLogical RETURNS LOGICAL (itemName AS CHAR). 

The following function gets an int, short, or bytes item from a MapMessage:

SYNTAX
FUNCTION getInt RETURNS INT (itemName AS CHAR). 

The following function gets any numeric item from a MapMessage:

SYNTAX
FUNCTION getDecimal RETURNS DECIMAL (itemName AS CHAR). 

The following function gets an item of any data type except bytes from a MapMessage:

SYNTAX
FUNCTION getChar RETURNS CHAR (itemName AS CHAR). 

The following function gets a bytes item from a MapMessage:

SYNTAX
FUNCTION getBytesToRaw RETURNS RAW (itemName AS CHAR). 

BytesMessage

A BytesMessage is an uninterpreted stream of bytes.

To create a BytesMessage, an application calls createBytesMessage in a Session object with the following output parameter:

SYNTAX
PROCEDURE createBytesMessage. 
DEFINE OUTPUT PARAMETER messageHandle AS HANDLE. 

The following function returns the number of bytes in a BytesMessage:

SYNTAX
FUNCTION getBytesCount RETURNS INT. 

The following function returns true if the last bytes segment was retrieved:

SYNTAX
FUNCTION endOfStream RETURNS LOGICAL. 

NOTE: An application should not call endOfStream if it used getMemptr to extract the data.

The following procedure changes the mode of a BytesMessage from write-only mode to read-only mode and places the cursor before the first bytes segment. Sending the message causes an implicit reset. The message arrives at the receiver in a reset state:

SYNTAX
PROCEDURE reset. 

MultipartMessage

A multipart message contains one or more message parts. Each message part is identified by a content type and a content ID, and contains a set of message headers and a message body. Message parts can be Sonic messages, character data, and binary data.

When you access a multipart message, you can retrieve each part as a SonicMQ message (if that is how it was sent), as a character data, or as a byte array. The SonicMQ Adapter supports only message parts and byte-array parts returned as a CHARACTER string or a MEMPTR.

The following method creates a multipart message:

SYNTAX
PROCEDURE createMultipartMessage.  
DEFINE OUTPUT PARAMETER messageH AS HANDLE. 

The following method adds a Sonic message to a multipart message:

SYNTAX
PROCEDURE addMessagePart.  
DEFINE INPUT PARAMETER messagePartH AS HANDLE. 
DEFINE INPUT PARAMETER contentIDString AS CHARACTER. 

The following method adds binary data to a multipart message:

SYNTAX
PROCEDURE addBytesPart.  
DEFINE INPUT PARAMETER memptr AS MEMPTR. 
DEFINE INPUT PARAMETER contentTypeString AS CHARACTER. 
DEFINE INPUT PARAMETER contentIDString AS CHARACTER. 

The following method adds CHARACTER data to a multipart message:

SYNTAX
PROCEDURE addTextPart.  
DEFINE INPUT PARAMETER charString        AS CHARACTER. 
DEFINE INPUT PARAMETER contentTypeString AS CHARACTER. 
DEFINE INPUT PARAMETER contentIDString   AS CHARACTER. 

The following method returns the number of parts contained by a multipart message:

SYNTAX
FUNCTION getPartCount RETURNS INTEGER. 

The following method returns TRUE if the part specified by the index is a SonicMQ message:

SYNTAX
FUNCTION isMessagePart RETURNS LOGICAL 
  (INPUT messageH AS HANDLE, INPUT index AS INTEGER). 

The following method returns the message part corresponding to the given index:

SYNTAX
FUNCTION isMessagePart RETURNS CHARACTER 
  (INPUT index AS INTEGER, OUTPUT messagePartH AS HANDLE). 

The following method returns the message part corresponding to the given content ID:

SYNTAX
FUNCTION getMessagePartByID RETURNS CHARACTER 
  (INPUT contentID AS INTEGER, OUTPUT messagePartH AS HANDLE). 

The following method returns the bytes part corresponding to the given index:

SYNTAX
FUNCTION getMessagePartByID RETURNS CHARACTER 
  (INPUT iIndex AS INTEGER, OUTPUT memPtr AS MEMPTR). 

The following method returns the bytes part corresponding to the given content ID:

SYNTAX
FUNCTION getBytesPartByID RETURNS CHARACTER 
  (INPUT-OUTPUT memPtr AS MEMPTR, INPUT contentID AS INTEGER). 

Overcoming the 32K RAW Bytes Limit

The RAW data type has a 32K size limit. To bypass this limit, an application can do multiple read... and write... calls as with a TextMessage.

The following procedure can be called in write-only mode to write an additional bytes segment to a BytesMessage:

SYNTAX
PROCEDURE writeBytesFromRaw. 
DEFINE INPUT PARAMETER bytesValue AS RAW. 

The following function can be called in read-only mode to return the next bytes segment. The size of all the bytes segments other than the last one is 8192; the size of the last one is 8192 or less:

SYNTAX
FUNCTION readBytesToRaw RETURNS RAW. 

Writing and Reading MEMPTR Bytes Data

The MEMPTR data type does not have a 32K limit. An application can make one get... or set... MEMPTR call.

The following procedure sets the specified number of bytes from the MEMPTR variable starting at startIndex (the first byte is 1). The setMemptr procedure implicitly calls clearBody before setting the data and resets after setting the data. Therefore, it can be used whether the message is in read-only or write-only mode prior to the call. The call makes a copy of the data. Thus, the memptrVal variable is not modified by the 4GL–JMS implementation and can be modified by the 4GL application after the call without corrupting the message:

SYNTAX
PROCEDURE setMemptr. 
DEFINE INPUT PARAMETER memptrVar AS MEMPTR. 
DEFINE INPUT PARAMETER startIndex AS INT. 
DEFINE INPUT PARAMETER numBytes AS INT. 

The following function returns a reference to a MEMPTR variable that contains exactly all the bytes of the message. The getMemptr function implicitly calls reset. If the message was in a write-only mode, it will be in a read-only/reset mode after the call. The getMemptr function does not create a copy of the MEMPTR variable; it returns a reference to the data maintained by the Message object. The deleteMessage call releases the variable’s memory, and the caller must copy any data it will need or need to modify before deleting the message:

SYNTAX
FUNCTION getMemptr RETURNS MEMPTR. 

Discardable Messages

Sonic contains a message delivery mode called DISCARDABLE for messages published to a topic. When a message with the delivery mode DISCARDABLE is published to a topic, if the topic’s queue is full, the message is automatically deleted.

The setDefaultPersistency method sets the persistency mode of a session. Its syntax is:

SYNTAX
PROCEDURE setDefaultPersistency.  
DEFINE INPUT PARAMETER deliveryMode AS CHAR. 

The publish method, which publishes a message to a session, lets you specify the delivery mode. Its syntax is:

SYNTAX
PROCEDURE publish. 
DEFINE INPUT PARAMETER topicName AS CHAR.  
DEFINE INPUT PARAMETER message AS HANDLE.  
DEFINE INPUT PARAMETER priority AS INT.            /*Session default is 
                                                     used if UNKNOWN.*/ 
DEFINE INPUT PARAMETER timeToLive AS DECIMAL.      /*Session default is 
                                                     used if UNKNOWN.*/ 
DEFINE INPUT PARAMETER deliveryMode AS CHAR.       /*Session default is 
                                                     used if UNKNOWN.*/ 

XMLMessage

SonicMQ’s XMLMessage is an extension of TextMessage and it supports all the methods of TextMessage. For more information, see the "TextMessage" section in this chapter.

To create an XML message, an application calls createXMLMessage in a Session object with the following output parameter:

SYNTAX
PROCEDURE createXMLMessage. 
DEFINE OUTPUT PARAMETER messageHandle AS HANDLE. 

XML Code-page Encoding

4GL applications work with the built-in XML parser. It is important to consider the code-page encoding of XML messages. In principle, XML documents can be encoded with any code page. However, XML parsers support some or all code pages, and XML parsers also differ in the code-page conversions they support.

4GL clients set and get XML text using the 4GL CHARACTER data type. CHARACTER data is encoded by the 4GL interpreter using the internal code page (the –cpinternal startup parameter). The 4GL–JMS implementation automatically converts the text to Unicode when sent to the JMS server and from Unicode to the internal client’s code page when sent from the server to client.

In general, when the characters used by the XML document are from the 7 byte ASCII subset, there are no issues the 4GL programmer has to consider. Otherwise, observe the following examples and guidelines.

Example 1

In this example, two 4GL clients use the ISO8859-1 code page:

The following code-page conversions take place:

  1. ISO8859-1 (client1) to Unicode (SonicMQ XML message)
  2. Unicode (SonicMQ XML message) to ISO8859-1 (client2)

In this example, the XML parser parses the XML document correctly if the header of the document specifies that the encoding is ISO8859-1 and the parser can handle ISO8859-1.

Example 2

In this example, two 4GL clients use ISO8859–1 for their internal code page. Client1 saves a UTF–8 encoded XML document in a MEMPTR variable (using the X–DOC:SAVE() 4GL method) and then uses the 4GL GET–STRING statement to extract the text from the MEMPTR and pass it into the XML message. (This is a deliberate error.) UTF–8 (Unicode Transformation Format) is an 8-bit encoding form that serializes a Unicode scalar value as a sequence of one to four bytes.

A 4GL client cannot mix code pages. The text it sets in the XML message must be encoded in the same code page as the client’s internal code page. In general, a MEMPTR variable must be used carefully, since it can have any data in it. The 4GL programmer must be sure that it contains only NULL free text (no embedded NULL bytes), encoded with the same code page as the internal code page, before loading it into an XML message.

In this example, if the 4GL client cannot be started up with –cpinternal UTF–8, but still wants to use 4GL–JMS to pass that UTF–8 document, it can use a BytesMessage or bytes elements in a StreamMessage. When sent as bytes, the XML data will get to the receiver uninterpreted and unconverted. The 4GL receiver can then set the data in a MEMPTR variable and load the parser. (See the "Publishing, Subscribing, and Receiving an XML Document In a BytesMessage" section in Using the SonicMQ Adapter.") A second option is to convert the text (and the document’s header) to ISO8859–1 using the CODEPAGE–CONVERT 4GL function.

If the 4GL receiver of an XML message is unsure about the XML header encoding declaration, it must check it and perhaps modify it to match its internal code page before loading the parser.


Copyright © 2004 Progress Software Corporation
www.progress.com
Voice: (781) 280-4000
Fax: (781) 280-4095