Skip to content

MT content modification

This section describes common message edit use cases

The ordering of fields in an MT message can sometimes make it challenging to make changes, especially when the required modification involves adding new fields or altering the content of existing ones.

Modifying content of an existing message is done with the generic backbone model; implemented in the SwiftMessage class and in particular for the text block implementation in the SwiftBlock3 and SwiftBlock4 classes.

If the message to modify has been created or parsed into an MTnnn class, the underlying model can be accessed like this:

        MT103 mt = MT103.parse(file);

        SwiftBlock3 block3 = mt.getSwiftMessage().getBlock3();

        SwiftBlock4 block4 = mt.getSwiftMessage().getBlock4();
Notice the MTnnn classes and its getFieldnn methods are a convenient abstraction to read message content or to create new messages from scratch, but they are not suitable for content modification.

The SwiftBlock3 class implements the structure of any MT message text block, it is optional, and contains special processing instructions.

The SwiftBlock4 class implements the structure of any MT message text block and provides several helpful API to retrieve fields and alter content.

Both classes provides API to insert new fields between others.

Updating a field value

Updating an existing field value or component within a field can be achieved in several ways.

The simplest scenario, when a complete field value must be changed can be handled by just retrieving the generic Tag object and setting its new value as a string.

For SwiftBlock3:

    block3.getTagByName(Field106.NAME).setValue("FOO");

For SwiftBlock4:

    block4.getTagByName("20").setValue("NEWREFERENCE");

Both SwiftBlock3 and SwiftBlock4 provides several API to retrieve tags; by name and letter option, by number, by name and qualifier, etc..

For example, if we need to set a new value for field 103, which in this case is in the first position of the SwiftBlock3. We can do that as follows:

    block3.getTag(0).setValue("NEW VALUE");

Let's say now we need to set a new value for field 57A. Since this field has several internal components (subfields) it can be useful to build the new value from a Field57A object. We can do that as follows:

    Field57A field57A = new Field57A();
    field57A.setAccount("12345");
    field57A.setBIC("NEWAESMMXXX");
    block4.getTagByName("57A").setValue(field57A.getValue());

Notice how we created a new field, but then we had to load the actual Tag instance in order to overwrite its value.

The getValue() call returns the serialization of all present field components into a proper string format. For instance in the example the resulting string would be:

    /12345 [CRLF]
    NEWAESMMXXX

Notice the starting slash and the line feed are automatically added.

A similar approach can be use if we need to change just a specific component from an existing field. As in the previous example we use a Field object because it provides helpful API to manipulate internal components. But instead of creating the Field object from scratch, we start by loading it from the actual message. In this example we will change just the value date from the existing field 32A:

Field32A field32A = mt.getField32A().setComponent1(Calendar.getInstance());
b4.getTagByName("32A").setValue(field32A.getValue());

Notice how we first loaded the helper Field32A instance, which is filled with content from the internal Tag object. The we use this field object to alter the value date. At that moment the actual message content has not been modified because the Field instance is a detached object, changing it does not modify the actual message. So finally, we used the detached modified field to update the current Tag value in the underlying message.

Inserting new fields in MT message

The text block of a SWIFT message is syntactically an ordered list of fields and as such in the underlying model it is actually implemented as a List<Tag>. So depending on the specific need, inserting new fields in specific positions into an existing block can be tricky. Unfortunately in current version there is no easy/out-of-the-box API for this but the following workaround can be handy.

First alternative involves inserting new fields by means of plain List manipulation using Java API. This can be done in combination of the indexOf methods provided by both SwiftBlock3 and SwiftBlock4 to select the specific positions where new fields must be added. The text block can be thought of as a String, and the provided API as StringUtils.

Then, depending on how many fields are being added and how many remain the same, it may be also convenient to create a new block, appending in order the fields from the original message plus the new ones to add.

Finally, if you are comfortable manipulating XML a total different approach is to convert the SWIFT message into XML, manipulating the XML, and then converting the XML back to SWIFT. The proprietary XML parser and writer are provided within the API.

The alternative to choose depends mainly on the use case. If the implementation is for a specific MT and use case the first two options can be convenient. But if the requirements is generic, for several situations and MTs, the XML approach would be better.

An extension for both SwiftBlock3 and SwiftBlock4 API is in the roadmap and will provide methods to insert new fields in specific index based positions.

Using the tag index

For the block 4 a couple of methods were also introduced to handle fields order, the addTag(index, Tag) and setTag(index, Tag).

The addTag at index adds a tag at the specified position in this tag list, and shifts the element currently at that position (if any) and any subsequent elements to the right (adds one to their indices).

    SwiftBlock4 b4 = new SwiftBlock4();
    b4.append(new Tag("20:PAY01"));
    b4.append(new Tag("23B:CRED"));
    b4.append(new Tag("71A:SHA"));
    b4.addTag(2 , (new Tag("21:RELREF")));

At this point the tag list will contain fields: 20, 21, 23B and 71A

Then the setTag at index replaces the tag at the specified position in the tag list with the new tag.

    b4.setTag(2, (new Tag("32A", "180419USD1234,")));
At this point the tag list will contain fields: 20, 32A, 23B and 71A

Reference for block 4 manipulation API can be found online at SwiftTagListBlock

Using the SwiftBlock3Builder

The SwiftBlock3Builder class provides a convenient API to build a SwiftBlock3 instance from scratch. It is useful when you need to create a new message from scratch, or when you need to modify the block 3 of an existing message. This class ensures that only expected fields are set and fields are set in proper order. Each time a new field is set, the internal tag list will be updated in proper order.

The following example shows how to create a new block 3 from scratch:

        //this will setup all  the fields in the proper order
        SwiftBlock3 b = new SwiftBlock3();
        SwiftBlock3Builder builder = b.builder();
        builder
        .setField121(new Field121("foo"))
        .setField106(new Field106("foo"))
        .setField165(new Field165("foo"))
        .setField106(new Field106("finalValue106"))
        .setField108(new Field108("foo"));

        //this will set the field 121 again, in the proper position, and update the internal Field list
        b.builder()
            .setField121(new Field121("another_foo"))