Message Object Population

After you’ve declared and instantiated your message object, you want to populate it with data. If your data is coming from the component buffers, populating your message is easy.

A message definition can contain a hierarchy of records. A component buffer contains a hierarchy of records. If you want to copy data from a component buffer rowset to a message, the structure of the message and the component must be the same. That is, if you have a record at level two in your message and you want that data, you must have the same level zero and level one records in your message as in your component.

For example, suppose your component had the following structure (that is, that PO_INFO and PO_LINE are at the same level, and PO_DETAIL is the child of PO_INFO):

PO_HEADER
   PO_LINE
   PO_INFO
      PO_DETAIL

To include the information in the PO_DETAIL record, you must have at least the following record structure in your message:

PO_HEADER
   PO_INFO
      PO_DETAIL

Any records that are in the page that aren’t in the message (and vice-versa) are ignored.

After you get your message object, you can create a rowset from it. This rowset has the same structure as the message. If the message is empty, the rowset has no data. If the message has data, the rowset is automatically populated.

The following example is the simplest way of populating a message with data. This assumes that the structure of the message is the same as the structure of the page.


         /* this gets all the data in the Component buffer */

&RS = GetLevel0();/* this instantiates a message object */

&MSG = CreateMessage(OPERATION.MY_MESSAGE);/* creates a rowset with the same structure as the message */

&MSG_RS = &MSG.GetRowset();/* this copies all the data from the page to the message */

&RS.CopyTo(&MSG_RS);/* this publishes the message */

%IntBroker.Publish(&MSG_RS);

A message rowset is the same as a Component buffer rowset, or any other rowset. It is composed of rows, records, and fields. Suppose you didn’t want to get all the data from the Component buffer, but instead wanted to populate just a particular record in your message.

To access a record in a message rowset is the same as accessing a record in a component buffer rowset. You must instantiate the rowset, then specify the row before you can access the record.

The following selects values into a record, then uses the record method CopyFieldTo to copy from the Component buffer record to the message record.

Local SQL &LN_SQL;
Local Message &MSG;
Local Rowset &HDR_RS, &LN_RS;
Local Record &LN_REC, &ln_rec_msg;

&MSG = CreateMessage(OPERATION.STOCK_REQUEST);
&HDR_RS = &MSG.GetRowset();
&LN_REC = CreateRecord(Record.DEMAND_INF_INV);

&LN_SQL = CreateSQL("Select * from PS_DEMAND_INF_INV where  BUSINESS_UNIT= :1 and ORDER_NO = :2", &BUSINESS_UNIT, &ORDER_NO);

&J = 1;
While &LN_SQL.Fetch(&LN_REC)

  /* copy data into the Level 1 of &MSG object */
  &LN_RS = &HDR_RS(&I).GetRowset(1);

  If &J > 1 Then
    &LN_RS.InsertRow(&J - 1);
  End-If;

  &ln_rec_msg = &LN_RS.GetRow(&J).GetRecord(Record.DEMAND_INF_INV);
  &LN_REC.CopyFieldsTo(&ln_rec_msg);
  &J = &J + 1;
End-While;

This section also discusses items to keep in mind when:

  • Populating a rowset from a message.

  • Publishing and subscribing to partial records.

  • Subscribing to character fields.

Suppose your message had two rowsets, one at level zero, a second at level one. In the message, only the level zero rowset contains any data. When you use GetRowset to create a rowset for the entire message, the rowset at level one will contain an empty row, even if there isn’t any data in it. (This is standard behavior for all rowsets.) However, you can use the IsChanged property on the record object to determine the status of the data.

The following notification PeopleCode example traverse the rowset. (Notice the use of ChildCount, ActiveRowCount, and IsChanged properties).

‘. . .’ is where application specific code would go.

&MSG_ROWSET = &MSG.GetRowset();
For &A0 = 1 To &MSG_ROWSET.ActiveRowCount

/***************************/
/* Process Level 1 Records */
/*-------------------------*/

  If &MSG_ROWSET(&A0).ChildCount > 0 Then
  For &B1 = 1 To &MSG_ROWSET(&A0).ChildCount

    &LEVEL1_ROWSET = &MSG_ROWSET(&A0).GetRowset(&B1);
      For &A1 = 1 To &LEVEL1_ROWSET.ActiveRowCount
        If &LEVEL1_ROWSET(&A1).GetRecord(1).IsChanged Then
          . . .

/***************************/
/* Process Level 2 Records */
/*-------------------------*/

          If &LEVEL1_ROWSET(&A1).ChildCount > 0 Then
          For &B2 = 1 To &LEVEL1_ROWSET(&A1).ChildCount
            &LEVEL2_ROWSET = &LEVEL1_ROWSET(&A1).GetRowset(&B2);
              For &A2 = 1 To &LEVEL2_ROWSET.ActiveRowCount
                If &LEVEL2_ROWSET(&A2).GetRecord(1).IsChanged Then
                .  .  .

/***************************/
/* Process Level 3 Records */
/*-------------------------*/

                If &LEVEL2_ROWSET(&A2).ChildCount > 0 Then
                  For &B3 = 1 To &LEVEL1_ROWSET(&A2).ChildCount
                    &LEVEL3_ROWSET = &LEVEL2_ROWSET(&A2).GetRowset(&B3);
                    For &A3 = 1 To &LEVEL3_ROWSET.ActiveRowCount
                      If &LEVEL3_ROWSET(&A3).GetRecord(1).IsChanged Then
                      .  .  .

                      End-If; /* A3 - IsChanged */
                    End-For; /* A3 - Loop */
                  End-For; /* B3 - Loop */
                End-If; /* A2 - ChildCount > 0 */

/*--------------------------------*/
/* End of Process Level 3 Records */
/**********************************/

              End-If; /* A2 - IsChanged */
            End-For; /* A2 - Loop */
          End-For; /* B2 - Loop */
        End-If; /* A1 - ChildCount > 0 */

/*--------------------------------*/
/* End of Process Level 2 Records */
/**********************************/

      End-If; /* A1 - IsChanged */
    End-For; /* A1 - Loop */
   End-For; /* B1 - Loop */
  End-If; /* A0 - ChildCount > 0 */

/*--------------------------------*/
/* End of Process Level 1 Records */
/**********************************/

End-For; /* A0 - Loop */

If you've selected to not publish all the fields in the message, you must be careful when inserting that data into a record.

Deselecting the Include check box in the message definition means that the field is excluded from the message definition.

  • The field won't be included when generating an XML document (when publishing a message.)

  • If the field is present in the XML (that is, it wasn't excluded from the published message) it is ignored by the subscribing system.

When you insert the data from the message into the database, you must set the values for the fields that aren't in the message. You can use the SetDefault record class method to do this. You could also use a Component Interface based on the component the message was created from to leverage the component defaults.

If a message definition has character fields that are defined as uppercase, when the message is subscribed to, character data for those fields is automatically converted to uppercase.