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();
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
:
For SwiftBlock4
:
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:
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.
At this point the tag list will contain fields: 20, 32A, 23B and 71AReference 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"))