SWIFT MT library documentation

PAYMENTCOMPONENTS Accessible Expertise, Empowering Great Solutions

Swift Message Processor User Manual

Web: http://www.paymentcomponents.com e-mail: info@paymentcomponents.com Phone: +30 210 61 45 050 Fax: +30 210 61 45 055

Overview

Datamation SWIFT MT library can be used to write a full SWIFT (Society for Worldwide Interbank Financial Telecommunication) message handling applications in a fraction of the time and effort needed.

The components can be used to:

Besides the basic functions to parse or build the SWIFT message, it provides tens of methods that will make any programmer's life easier.

About SWIFT messages

All SWIFT messages conform to a defined block structure. Each message block contains data of a particular type and is used for a particular purpose. A typical SWIFT message may consist of the following five blocks:

  1. BASIC HEADER BLOCK
  2. APPLICATION HEADER BLOCK
  3. USER HEADER BLOCK
  4. TEXT BLOCK
  5. TRAILER BLOCK

Each block is sub-divided into a number of tags followed by their values. Each tag hosts particular information (e.g. Message date, Bank Name, Beneficiary name etc) and are defined in the SWIFT manual. Each tag may have one or more lines of information and may exist (one or more times) or not in a block depending on the message type.

There are several rules (both syntax and semantics) that a message must be compliant to in order to be accepted and transferred from the SWIFT network. When a message arrives to its destination, is a large strictly formatted string. This string needs to be parsed so that someone can use its impended information. At that point SwiftMsgProcessor component can be a great help.

The following example illustrates the structure of a financial message (MT 103) as input by the Sender:

{1:F01ABCDGRA0AXXX0057000289}BASIC HEADER BLOCK
{2:I103DDDDGRA0AXXXN}APPLICATION HEADER BLOCK
{3:{113:ABCD}}USER HEADER BLOCK
{4:crlf
:20:494930/DEVcrlf
:32A:020527EUR1958,47crlf
:50:BIODATA GJBHcrlf
ZURICHcrlfTEXT BLOCK
:59:S.T JANSSENcrlf
LEDEBOERSTRAAT 29crlf
AMSTERDAMcrlf
-}
{5:{MAC:75D138E4}{CHK:DE1B0D7}}TRAILER BLOCK

Icon CrLf does not separate basic Header, Application Header, User Header, Text and Trailers Blocks. In the above example, the blocks have been shown on separate lines for clarity purposes. Blocks 1, 2 and 3 relate to header information, Block 4 contains the text of the message, and Block 5 contains trailer information.

Basic Header Block

The Basic Header is given in Block 1 of a SWIFT message and is the only header that appears on all messages. The Basic Header provides the fundamental reference for any particular message. The Basic Header has the same format for both input and output messages. However, the information contained in the Basic Header is relative to the sender when the message is input but relative to the receiver when the same message is output.

The following is an example of a basic input header:

{1:F01ABCDGRA0AXXX0057000289}

The components are separated as follows:

{ 1: F 01 ABCDGRA0AXXX 0057 000289 }
  1. Block Identifier
  2. Application Identifier
  3. Service Identifier

(d) LT Identifier (e) Session Number (f) Sequence Number (ISN or OSN)

Application Header Block

The Application Header of a SWIFT message provides information about the message itself. The Application Header is given in Block 2 of a SWIFT message. It differs whether is part of an input or an output message.

Application Header - Input

For input messages, the Application Header describes the type of message, its addressee and how it should be sent. The following is an example of an input Application Header:

{2:I103DDDDGRA0AXXXU3003}

The components are separated as follows:

{ 2: I 103 DDDDGRA0AXXX U 3 003}

(a) Block Identifier (b) Input/Output Identifier (c) Message Type (d) Receiver's Address (e) Message Priority (f) Delivery Monitoring (g) Obsolescence Period

Application Header - Output

For output messages, the output Application Header defines the type of message, who sent it and when, and when it was delivered.

The following is an example of an output Application Header:

{2:O1031200010103DDDDGRA0AXXX22221234560101031201N}

The components are separated as follows:

{ 2: O 103 1200 010103 DDDDGRA0AXXX 2222 123456 010103 1201 N }

(a) Block Identifier (b) Input/Output Identifier (c) Message Type (d) Input Time (e) MIR :(1) Input date (2) Full input SWIFT address (3) Input Session Number (4) ISN (f) Output Date (g) Output Time (h) Message Priority

User Header Block

The User Header is an optional header available within FIN for user-to-user messages only. It appears in Block 3 of a SWIFT message, and allows users to provide their own reference within the headers for a particular message. The following is an example of an input User Header Block:

{3:{113:xxxx}{108:abcdefgh12345678}}

The components can be separated as follows:

{ 3: {113:xxxx} {108:abcdefgh12345678} }

(a) Block Identifier (b) Banking Priority (c) Message User Reference (MUR)

Text Block

Where applicable, the text of a SWIFT message is given in Block 4. An example of a Text Block follows:

{4:crlf
:20:494930/DEVcrlf
:32A:020527EUR1958,47crlf
:50:BIODATA GJBHcrlf
ZURICHcrlf
:59:S.T JANSSENcrlf
LEDEBOERSTRAAT 29crlf
AMSTERDAMcrlf
-}

In the text of user-to-user messages, CrLf is a mandatory field delimiter.

Trailer Block

Trailers are added to a message for the following reasons:

They may be added by the user or by the system. Trailers always appear in Block 5 of a SWIFT message.

An example of a Trailer Block follows:

5:{MAC:41720873}{CHK:123456789ABC}}

One or more trailers may appear in Block 5 of a SWIFT message.

Conceptual component overview

The components reside in the layer between the SWIFT network and the end user application. Components is a library undertaking the implementation of a heavy business logic that regards SWIFT messages. They provide object-oriented approach to programmatically handle SWIFT messages instead of fiddling with text files. By utilizing components, developers achieve better application architecture, by not implementing similar logic in multiple projects, by having all business logic concentrated in a single place and by leveraging a single gateway for all external SWIFT communication.

Usage flow of the SwiftMsgProcessor and SwiftMsgValidator

The Datamation MT components (gear icons in the diagram below) are incorporated into the end-user application to facilitate different SWIFT message manipulations.

Internal architecture

The basic object produced and consumed by the components is SwiftMessage. SwiftMessage breaks down into a number of attributes (String objects and five lists of Tag objects).

The end user application creates an instance of SwiftMsgParser to parse SWIFT text messages into a SwiftMessage object instance by invoking the method ParseMsgStringToObject. SwiftMsgParser iterates through the contents of the text message to fill the appropriate fields of the SwiftMessage instance. In case of an error during parsing, the method SwiftMsgParser.ParseMsgStringToObject throws an exception.

To produce the SWIFT text message from the SwiftMessage object, there's the method SwiftMsgParser.BuildMsgStringFromObject.

API Specification

Installation

Binaries

Download the latest library:

Incorporate the library into your project by the regular IDE means. This process will vary depending upon your specific IDE and you should consult your documentation on how to deploy a bean. For example in Eclipse all that needs to be done is to import the jar files into a project.

Alternatively, you can import it as a Maven dependency

**Maven dependency

The library is not in the Maven Central. To include it in the pom.xml you would have to:

<repositories>
  ...
  <repository>
    <id>in-project</id>
    <url>file://${basedir}/lib</url>
  </repository>
</repositories>
project_root/> mvn install:install-file -Dfile=smp-13.1.5.jar -DgroupId=gr.datamation -DartifactId=smv -Dversion=13.1.5 -Dpackaging=jar -DlocalRepositoryPath=lib -DcreateChecksum=true
<dependency>
  <groupId>gr.datamation</groupId>
  <artifactId>smv</artifactId>
  <version>13.1.5</version>
</dependency>

Third-party dependencies

The single dependency for the library is jdom 2.0.6.

Maven jdom dependency

<dependency>
    <groupId>org.jdom</groupId>
    <artifactId>jdom2</artifactId>
    <version>2.0.6</version>
</dependency>

After these manipulations your project is good to manipulate MT messages.

Requirements

For runtime environment the jar files must be included in the classpath. Requires at least JDK 6.

SwiftMsgParser object

This object has two methods encapsulating all the functionality needed to handle a SWIFT message

ParseMsgStringToObject method

This is the method used to parse a swift message. It takes as input a string containing a single message as it arrives from the SWIFT network. The method first validates the message for syntax errors, to ensure that the message string was extracted correctly from the SWIFT system. Then parses it producing the SwiftMessage object containing the values of the message tags. The parser uses an efficient and fast algorithm that ensures the correct breakdown of the message to its information in the minimum time.

{1:F01ABCDGRA0AXXX0057000289}{2:O1030919010321DDDDGRA0AXXX00570001710103210920N}{3:{113:ABCD}}{4:crlf
:20:494930/DEVcrlf
:32A:020527EUR1958,47crlf
:50:BIODATA GJBHcrlf
ZURICHcrlf
:59:S.T JANSSENcrlf
LEDEBOERSTRAAT 29crlf
AMSTERDAMcrlf
-}{5:{MAC:75D138E4}{CHK:DE1B0D71FA96}{TNG:}}{S:{SAC:}{COP}}

Observe there are carriage-return line-feeds (crlf) separating each line. So when using your own examples, make sure you use the appropriate crlf's.

To parse it, do the following:

//Put your SWIFT message in a string
String message = "{1:F01ABCDGRA0AXXX0057000289}{2:O1000919010321DDDDGRA0AXXX00570001710103210920N}{3:{113:ABCD}}{4:\n:20:494930/DEV\n:32A:020527EUR1958,47\n:50:BIODATA GJBH\nZURICH\n:59:S.T JANSSEN\nLEDEBOERSTRAAT 29\nAMSTERDAM\n}{5:{MAC:75D138E4}{CHK:DE1B0D71FA96}{TNG:}}{S:{SAC:}{COP}}";
//Create the parser object as below
SwiftMsgProcessor parser = new SwiftMsgProcessor();
//Create the return object to get back the results
SwiftMessage smObj = parser.ParseMsgStringToObject(Message);

You are done! Now the smObj contains the parsed message. To see how to get or manipulate this object read the "SwiftMessage object" section below.

ParseMsgStringsToObject method

Since the version 14.1.0 you can use this method to construct a SwiftMessage object from multiple related SWIFT messages. The parser will undertake the merging process. The message types supported are:

The library will process tags 45B, 46B and 47B in the sequence messages and will assign the concatenated results inside the corresponding master message (i.e. MT700 or MT710 or MT720) in tags 45A, 46A and 47A respectively. Pagination (Field 27 in the resulting message) will be handled automatically. The messages passed as arguments should have correct pagination, but they do not necessarily need to be provided in the correct order as the library will sort them prior to proceeding further.

Sample parsing multiple messages

SwiftMsgProcessor processor = new SwiftMsgProcessor();

String messageContentMaster = //... mt700
String messageContent1 = //... mt701
String messageContent2 = //... mt701
String messageContent3 = //... mt701

//the result message will be an MT700 message holding the content of all messages passed as the arguments
SwiftMessage result = processor.ParseMsgStringsToObject(Arrays.asList(messageContentMaster, messageContent1, messageContent2, messageContent3));

BuildMsgStringFromObject method

Use this method to construct a SWIFT message before sending it to the SWIFT network. It takes as input a SwiftMessage object that has been constructed by the programmer (see next section) and performs all the necessary formatting to produce a message with valid syntax. In other words programmer just assigns the right values to the tags of the SwiftMessage object and calls the method to build the SWIFT string ready to be transmitted to the SWIFT network. To enforce or check semantic rules such as tag sequence required fields etc, the SwiftMessageValidator, another PaymentComponents component should be called. To build a valid Swift string so that it can be transmitted to the SWIFT network follow the steps below:

//Create the component as below
SwiftMsgProcessor SMP = new SwiftMsgProcessor();

//Create the "SwiftMessage" object to set its Tags.
SwiftMessage smObj = new SwiftMessage();

//Set all the needed tags for the message. Start with block1 and block2
smObj.setArgApplid("F");
smObj.setArgServid("01");
smObj.setArgLTaddrBlk1 ("FFFFGRA0AXXX");
smObj.setArgInoutind("I");
smObj.setArgMsgtype("103");
smObj.setArgLTaddrBlk2("UUUUGRA0AXXX");
smObj.setArgMsgprior("N");

//When finished with block1 and block2 continue with block4,
//Create vector to store the line data of tag 20.
java.util.Vector vec20 = new java.util.Vector();
//add one data line
vec20.addElement("12345678");
// Create Tag object to store name and data line for tag 20.
Tag tag20 = new Tag("20",vec20);
//add tag 20 to block4 vector
smObj.getBlock4().addElement(tag20);

//Do the same for 52A
java.util.Vector vec52A = new java.util.Vector();
vec52A.addElement("/12345"); // add first data line
vec52A.addElement("ABCDE"); // add second data line
dat.SwiftCommon.Tag tag52A = new dat.SwiftCommon.Tag("52A", vec52A);
smObj.getBlock4().addElement(tag52A); //add tag 52A to block4 vector  

//Now build the outgoing message in a string format as SWIFT expects it.
String message = SMP.BuildMsgStringFromObject(smObj);

You are done! Now variable message contains all the Tags of the "SwiftMessage" – including the necessary carriage return linefeeds - and looks like the string below

{1:F01FFFFGRA0AXXX0000000000}{2:I103UUUUGRA0AXXXN}{4: crlf :20:12345678 crlf :52A:/12345 crlf ABCDE-}

SwiftMessage object

This is the heart of the component. It is the object that the parser populates with the values of the incoming message. This is the object the programmer accesses to get the values. It keeps the message information in vectors of Tag objects (see next section) and provides various methods to access and manipulate the object. There are more than 70 methods available. The programmer will need a small subset of them. Some of those are described below. The rest are straightforward in their usage and can be seen in the JavaDoc.

clear()

Clears all the fields of the "SwiftMessage". This includes all block vectors and message property fields.

smobj.clear();

displayMessage()

Displays at the standard output a text representation of the SWIFT message filled Tags

smobj.displayMessage();

The above will display as the output the following

Applid : F
Servid : 01
LTaddrBlk1: FFFFGRA0AXXX
Sesno : 0000
Osn : 000000
Inoutind : I
Msgtype : 103
LTaddrBlk2 : UUUUGRA0AXXX
Msgprior: N
113 : ABCD
20 : 494930/DEV
32A : 020527EUR1958,47
21 : 2222222
50 : BIODATA GJBH
50 : ZURICH
59 : S.T JANSSEN
59 : LEDEBOERSTRAAT 
59 : AMSTERDAM

getArgApplid()

Returns "Application Identifier" of the SWIFT message.

smobj.getArgApplid();

The above returns "F"

getArgLTaddrBlk1()

Returns "LT address" of the SWIFT message (Basic Header Block (1))

smobj.getArgLTaddrBlk1();

The above returns "FFFFGRA0AXXX".

getArgMsgtype()

Returns "Message Type" of the SWIFT message

smobj.getArgMsgtype();

The above returns "103".

getBlockx()

Returns a vector with all the tags of block x of the message.

smobj.getBlock1();

The above returns

[Applid[0]:F, Servid[0]:01, LTaddrBlk1[0]:FFFFGRA0AXXX, Sesno[0]:0000, Osn[0]:000000]

getMessageAsVector()

Returns a vector containing all the tags of the message in their original sequence.

smobj.getMessageAsVector();

The above returns

[Applid[0]:F, Servid[0]:01, LTaddrBlk1[0]:FFFFGRA0AXXX, Sesno[0]:0000, Osn[0]:000000,Inoutind[0]:I , Msgtype[0]:103, LTaddrBlk2[0]:UUUUGRA0AXXX, Msgprior[0]:N, 3[0]:ABCD , 20[0]:494930/DEV, 32A[0]:020527EUR1958,47, 21[0]:2222222, 50[0]:BIODATA GJBH 50[1]:ZURICH, 59[0]:S.T JANSSEN 59[1]:LEDEBOERSTRAAT 29 59[2]:AMSTERDAM]

getNumbertOfTagInstances(String name)

Returns the number of instances for the specific Tag. If tag does not exist then it returns 0.

smobj.getNumbertOfTagInstances("20");

The above returns the integer 1.

getTag(String name)

smobj.getTag("20");

The above returns a Tag object with all the information of tag 20 of the message.

A tag may exist more than once. This method returns the first instance of the tag.

getTag(String tagName, int index)

Returns the specified (if exists) instance of the tag with name tagName in the message (i.e. if tag20 exists three times in a message then getTag("20",1) returns the first occurrence of tag20 and getTag("20",3) returns the third. If tag does not exist or index is greater than the maximum number of tag representation then it returns null.

smobj.getTag("20",1);

The above returns a Tag object having all the information of tag 20 of the message.

isblockEmpty(int index)

Returns true when the specific block vector has no Tags.

isblockEmpty(4);

The above returns false.

setArgLTaddrBlk1(String newArgLTaddrBlk1)

Sets the text part for "LT address" of the SWIFT message (Basic Header Block (1))

smobj.setArgLTaddrBlk1("FFFFGRA0AXXX");

The above sets FFFFGRA0AXXX to LTaddrBlk1 property.

setArgMsgtype(String newArgMsgtype)

Sets the "Message Type" of a SWIFT message

smobj.setArgMsgtype("103");

The above sets 103 to MsgType property.

setBlockx(Vector newBlockx)

Sets a vector containing all the tags of a specific block in their original sequence.

java.util.Vector tmpVec = new java.util.Vector();
tmpVec.addElement("I");
tmpVec.addElement("103");
tmpVec.addElement("UUUUGRA0AXXX");
tmpVec.addElement("N");
SwiftMessage smobj = new SwiftMessage();
smobj.setBlock2(tmpVec);

The above sets tmpVec vector to block2 property.

toString()

Returns the String representation of this SWIFT Message

smobj.toString();

The above returns the string

Applid[0]:F Servid[0]:01 LTaddrBlk1[0]:FFFFGRA0AXXX Sesno[0]:0000 Osn[0]:000000 Inoutind[0]:I Msgtype[0]:103 LTaddrBlk2[0]:UUUUGRA0AXXX Msgprior[0]:N 113[0]:ABCD 20[0]:494930/DEV 32A[0]:020527EUR1958,47 21[0]:2222222 50[0]:BIODATA GJBH 50[1]:ZURICH 59[0]:S.T JANSSEN 59[1]:LEDEBOERSTRAAT 29 59[2]:AMSTERDAM

Tag object

This object is used to handle the message tags. Its properties are name and data. Name is a string containing the name of the tag (i.e. 52A). Data is a vector of strings containing the lines of tag information. It is accompanied by a number of utility methods to set and get the values or do other manipulation. Only the most important of these methods are described below. The rest are straight forward in usage and can be seen in the JavaDoc.

addDataLine(String line)

tag59.addDataLine("S.T JANSSEN");
tag59.addDataLine("LEDEBOERSTRAAT 29");
tag59.addDataLine("AMSTERDAM");

Adds a string containing the information of a Tag line to Data vector.

clearAll()

Clears the Tag properties name and data.

tag59.clearAll();

getData()

Returns a vector of strings containing the tag information. Each line of information is a vector element.

Vector tempVec = tag59.getData();

Now tempVec vector contains the value:

[S.T JANSSEN, LEDEBOERSTRAAT 29, AMSTERDAM]

getDataLineAt(int index)

Returns a string containing the information of the specified line of the tag. e.g. Assuming that in the original tag looks like the following

:59:S.T JANSSEN
LEDEBOERSTRAAT 29
AMSTERDAM
String data59l0 = tag59.getDataLineAt(0);
String data59l2 = tag59.getDataLineAt(2);

The above will set "S.T JANSSEN" to data59l0 and "AMSTERDAM" to data59l2 variable.

getName()

Returns a string containing the name of the tag.

tag59.getName();

The above will return "59".

getNumberOfDataLines()

Returns the number of lines that a tag has. Assuming that in the original tag looks like the following

:59:S.T JANSSEN
LEDEBOERSTRAAT 29
AMSTERDAM
tag59.getNumberOfDataLines();

The above returns the integer 3.

insertDataLineAt(String line, int index )

Inserts the specified line in Data vector at the specified index. Each line with an index greater or equal to the specified index is shifted upward.

Throws InvalidActionAttemptedException when the index is invalid. Assuming that in the original tag looks like the following

:59:S.T JANSSEN

LEDEBOERSTRAAT 29

AMSTERDAM
tag59.InsertDataLineAt("HOLLAND",2);

Now tag 59 looks like the following

:59:S.T JANSSEN

LEDEBOERSTRAAT 29
HOLLAND
AMSTERDAM

isEmpty()

Returns true when Tag infromation is empty.

tag59.isEmpty();

setData(Vector Data)

Sets the Data property (Vector) value.

Vector tmpVec = new Vector();
tmpVec.addElement("S.T JANSSEN");
tmpVec.addElement("LEDEBOERSTRAAT 29");
tmpVec.addElement("AMSTERDAM");
Tag tag59 = new Tag();
tag59.setName("59");
tag59.setData(tmpVec);

setDataLineAt(String line, int index )

Inserts the specified line in Data vector at the specified index overwriting the old line. Throws InvalidActionAttemptedException when the index is invalid.

Assuming that in the original tag looks like the following

:59:S.T JANSSEN
LEDEBOERSTRAAT 29
AMSTERDAM
tag59.setDataLineAt("HOLLAND",1);

Now tag 59 looks like the following

:59:S.T JANSSEN
HOLLAND
AMSTERDAM

setName(String newName)

Sets the Tags Name property (String) value.

Tag tag59 = new Tag();
tag59.setName("59");

setTag(String name, Vector data)

Sets Tags properties name and data.

Vector tmpVec = new Vector();
tmpVec.addElement("S.T JANSSEN");
tmpVec.addElement("LEDEBOERSTRAAT 29");
tmpVec.addElement("AMSTERDAM");
Tag tag59 = new Tag();
tag59.setTag("59",tmpVec);

toString()

Returns the String representation of this Tag.

tag59.toString();

The above returns

59[0]:S.T JANSSEN 59[1]:LEDEBOERSTRAAT 29 59[2]:AMSTERDAM

Tag data split functionality

In version 7.0 we have introduced new split functionality for the tag data, as some tags may have multiple values in one line, these can now be separated with this new feature. For example, a sample value for tag 32A could be '070111USD300.' So we have a line containing 3 different values: date, currency and amount. Now these values are stored separately and also as 1 line as before.

Assuming that string "msg" variable contains the message:

SwiftMessage obj = smp.ParseMsgStringToObject(msg);
Vector it = obj.getBlock4(); //We have the vector with the tags of the message.
Tag T32A = SwiftMsgUtils.getTagFromVector(obj.getBlock4(), "32A"); //We have the tag object of the specific tag.

Now, we have 2 options: We can write TAG_OBJECT.getComponentData().get(SPECIFIC_INDEX) or directly TAG_OBJECT.getComponent(SPECIFIC_INDEX). So, concerning the previous example, we would have something like the following

String Date = T32A.getComponent(0); //Value = '070111'
String Currency = T32A.getComponent(1); //Value = 'USD'
String Amount = T32A.getComponent(2); //Value = '300.'

Messages with 2 lines also have their second line split. Messages with more than 2 lines have the 1st component to be the first line and the second component to be all the other lines merged.

Tag description

You can now get each tag's description by using our Utilities class. So, if you have the tag object and you know the MT message it belongs to, you can use the following code

Utilities.getTagDescription("MT_MESSAGE_NUMBER", TAG_OBJECT));

and it will return the description of the tag. MT_MESSAGE_NUMBER is the mt message e.g. 103, 202, 700 etc. We have created a code sample at SWIFT MT Code samples

The use of Repetitive Sequences in SWIFT messages

Repetitive Sequences are used in certain SWIFT messages to enable groups of tags to be repeated more than once. The component represent these repetitive sequences by means of the RepSeq object. This means that a message can contain a combination of simple Tags and Repetitive Sequences, each of which is defined as optional or mandatory.

The following example shows how the SWIFT rulebook defines a mandatory repetitive sequence present in an MT104 message.

When an MT 104 message is parsed by the parser (SMP), the message object will represent this repetitive sequence as the following RepSeq object.

The RepSeq object includes simple Tag objects (i.e. tag 21 will be included in this RepSeq object as a simple Tag object), or even other (nested) RepSeq objects since there are SWIFT messages that are more complicated and include repetitive sequences inside repetitive sequences. The following example code demonstrates how to create a SwiftMessage object containing a RepSeq object.

package test;
import gr.datamation.swift.common.RepSeq;
import gr.datamation.swift.common.SwiftMessage;
import gr.datamation.swift.common.Tag;
import gr.datamation.swift.validator.SwiftMsgValidator;
import gr.datamation.swift.validator.SwiftValidObj;
import java.util.Vector;
public class RepSeqTest {
    /**
     * @param args
     */
    public static void main(String[] args) {
        SwiftMessage msg = new SwiftMessage();
        //block1 and block2 creation --------------
        //These blocks are created via methods
        //information for block 1
        msg.setArgApplid("F");
        msg.setArgServid("01");
        msg.setArgLTaddrBlk1("SIIBUS30AXXX");
        msg.setArgSesno("0466");
        msg.setArgOsn("021062");
        //information for block 2
        msg.setArgInoutind("O");
        msg.setArgMsgtype("430");
        msg.setArgIndate("070522");
        msg.setArgIntime("1607");
        msg.setArgLTaddrBlk2("LRLRXXXX4A07");
        msg.setArgSsesno("0000");
        msg.setArgIsn("592006");
        msg.setArgOutdate("070522");
        msg.setArgOuttime("1807");
        msg.setArgMsgprior("N");
        //block3 creation --------------
        //block 3 contains only simple tags
        //Create a simple tag...
        Tag tag430 = new Tag();
        //this means that we create a 430: tag
        tag430.setName("430");
        //create a vector used for storing the tag's data
        //We use a vector because a tag can have more than one line
        Vector data430 = new Vector();
        data430.addElement("MT430 001 OF 001");
        //set the Tag's vector to be this vector
        tag430.setData(data430);
        //and finally add this tag to block3 part of the message
        msg.getBlock3().addElement(tag430);
        RepSeq rp1 = new RepSeq();
        //CREATE A 20 TAG
        Tag tag20 = new Tag();
        //this means that we create a :20: tag
        tag20.setName("20");
        Vector data20 = new Vector();
        data20.addElement("12456");
        tag20.setData(data20);
        //CREATE A 21 TAG
        Tag tag21 = new Tag();
        //this means that we create a :21: tag
        tag21.setName("21");
        Vector data21 = new Vector();
        data21.addElement("45678");
        tag21.setData(data21);
        //CREATE A 32A TAG
        Tag tag32A = new Tag();
        //this means that we create a :32A: tag
        tag32A.setName("32A");
        Vector data32A = new Vector();
        data32A.addElement("100917USD578000000,0");
        tag32A.setData(data32A);
        rp1.addTag(tag20);
        rp1.addTag(tag21);
        rp1.addTag(tag32A);
        msg.getBlock4().addElement(rp1);
        //block5 creation --------------
        Tag tagCHK = new Tag();
        tagCHK.setName("CHK");
        Vector dataCHK = new Vector();
        dataCHK.addElement("2E8C6DD8A652");
        tagCHK.setData(dataCHK);
        Tag tagMAC = new Tag();
        tagMAC.setName("MAC");
        Vector dataMAC = new Vector();
        dataMAC.addElement("00000000");
        tagMAC.setData(dataMAC);
        msg.getBlock5().addElement(tagCHK);
        msg.getBlock5().addElement(tagMAC);
        SwiftMsgValidator smv = new SwiftMsgValidator();
        SwiftValidObj vobj = smv.validateMsg(msg);
        if (vobj.getErrorMessage() == null || vobj.getErrorMessage().equals("")) {
            vobj.getSwiftMessage().displayMessage();
            System.err.println("ALL IS OK!!!");
        } else {
            System.err.println(vobj.getErrorMessage());
        }
    }
}

SwiftMsgValidator object

SwiftMsgValidator has just one method encapsulating the entire functionality needed to validate and build a SWIFT MT message.

Validating Objects - validateMsg method

This method takes as input a SwiftMessage object that has been manually constructed by a developer (see the "Writing Clients" section), performs SWIFT validations and returns a list of error messages (if the message it correct, then an empty list is returned; null is never returned). For messages that include repetitive sequences, use object RepSeq to set the message tags (see an example below).

Splitting Oversized Messages

Since version 14.1.0, SwiftMsgValidator is able to split oversized messages if they belong in one of the supported categories (MT700, MT710, MT720). The validator will handle splitting automatically depending on the category of the input message.

In case where the message type falls into one of the supported categories, additional sequence messages will be produced based on the input message type, and based on the following rules (applied in this order):

  1. If one or more of fields 45A, 46A, 47A of the input message have more lines than the allowed limit, according to the SWIFT standard, each field will be broken into multiple chunks, each being encapsulated inside a sequence message.
  2. If the message as a whole has more characters than the allowed limit per message, according to the SWIFT standard, each of the fields 45A, 46A, 47A will begin being transferred into new sequence messages (priority is given to the tags that have the most lines) up until the point where the message is not oversized anymore.

In the case where the message will be split, pagination in field 27 will be handled automatically, and field 20 of the sequence messages will hold the value of field 20 of the original input message.

Maximum amount of sequence messages that the original input message should be split into is 8 (to result in 9 messages along with the input one); this will allow to keep the syntax of the field 27 intact. If the original message is required to be split into a number of sequence messages greater than 8, the library will still proceed with the splitting, but the validation that follows will report errors in all messages regarding field 27, where the allowed format is 1!n/1!n.

After splitting, all messages will be validated, and errors will be reported.

Validation Results

Since version 14.1.0, the SwiftValidObj object is able to return multiple message objects as a result of the validation process. The legacy getSwiftMessage method will always return the first message of the resulting array of message objects. The new method getSwiftMessages will return an array of SwiftMessages that are the result of the validation process. The validation error list inside the SwiftValidObj will hold errors that concern the entire array of messages.

Since version 14.1.0, the ValidationError objects have a new method, getMessageIndex which returns an integer indicating the index in the input array of the message this error corresponds to.

XMLWriter object

It is used to serialize the SwiftMessage object to a generic XML document. It does it with the use of buildXML method. It also uses Java Document Object Model (JDOM) that is delivered with the deployment jar. These open source classes can also be downloaded from www.jdom.org.

Note: This article talks about gr.datamation.swift.swift2xml.XMLWriter. Avoid confusing with javax.sql.rowset.spi.XmlWriter.

buildXML method

It is a method within XMLWriter object, and is the only one used to build a generic XML document. It has three inputs:

The method first validates the file name for syntax errors, to ensure that the XML will have alphanumeric characters.

Example

To build an XML, do the following:

SwiftMsgProcessor obj = new SwiftMsgProcessor();
XMLWriter writer = new XMLWriter();
writer.buildXML( swfobj , "/path/to" , "file.xml");

You are done! Now the XML file has been created.

XMLReader object

It is used to parse the swift message from a generic XML document. It does it with the use of parseXML2Object method. It also uses Java Document Object Model (JDOM) that is delivered with the deployment jar. These open source classes can also be downloaded from www.jdom.org.

Note: This article talks about gr.datamation.swift.swift2xml.XMLReader. Avoid confusing with javax.sql.rowset.spi.XmlReader or org.xml.sax.XMLReader.

parseXML2Object method

It is a method within XMLReader object, and is the only one used to build a SwiftMessage object from a generic XML document. It takes one input:

And outputs a SwiftMessage object.

Example

To parse the generic XML file, do the following:

XMLReader xr = new XMLReader();
SwiftMessage message = xr.parseXML2Object("/path/to/file.xml");

You are done! Now the SwiftMessage object has been created from the xml file.

User Manual

Parser

In this section a number of programming ideas and tips are given to help use the component.

To Parse a Message

The following four lines are all you need to parse your incoming message.

// This is the Swift Message String
String Message = "your SWIFT message string";
// Create an object of its type
SwiftMsgProcessor SMP = new SwiftMsgProcessor();
// Create the return object to get back the results
SwiftMessage smObj = SMP.ParseMsgStringToObject(Message);

To Get a tag of a Parsed Message

//To retrieve a simple property, for example the message type
String MsgType = smObj.getArgMsgtype();
//To retrieve a data line of a tag, for example the first line of the data vector.
String MsgType = smObj.getTag("Msgtype").getDataLineAt(0)
//There are cases where you need to get the Tag name and its data (eg: :52A:/123456/ABCDEFG)
Tag tag = smObj.getTag("52A");
String tagName = tag.getName(); // Returns string "52A"
Vector tagVector = tag.getData(); // Returns vector [/123456,ABCDEFG]

There are a number of ways to retrieve a tag of the parsed message. Each time, you chose the way best suited to your application and tag.

To Build a Message

// Create the component
SwiftMsgProcessor SMP = new SwiftMsgProcessor();
// Create the swift message object so that you can set its Tags.
SwiftMessage smObj = new SwiftMessage();
// Set Tags for block1 and block2
smObj.setArgApplid("F");
smObj.setArgServid("01");
smObj.setArgLTaddrBlk1 ("FFFFGRA0AXXX");
smObj.setArgInoutind("I");
smObj.setArgMsgtype("103");
smObj.setArgLTaddrBlk2("UUUUGRA0AXXX");
smObj.setArgMsgprior("N");

// Start Setting Tags for block4,
// Create vector to store the line data of tag 20.
Vector vec20 = new Vector();
vec20.addElement("12345678");//add one data line
// Create Tag object to store name and data line for tag 20.
Tag tag20 = new Tag("20",vec20);
smObj.getBlock4().addElement(tag20); //add tag 20 to block4 vector

//Do the same for 52A
Vector vec52A = new Vector();
vec52A.addElement("/12345"); // add first data lineThe following lines demonstrate the way to call it and get back the returned Message.
 vec52A.addElement("ABCDE"); // add second data line
Tag tag52A = new Tag("52A", vec52A);
smObj.getBlock4().addElement(tag52A); //add tag 52A to block4 vector

// Now build the outgoing message in a string format as SWIFT expects it.
String message = SMP.BuildMsgStringFromObject(smObj);

The object message now contains all the Tags of the SwiftMessage – including the necessary carriage return linefeeds - and looks like below

{1:F01FFFFGRA0AXXX0000000000}{2:I103UUUUGRA0AXXXN}{4:
:20:12345678
:52A:/12345
ABCDE-}

To Parse the SwiftMessage object into a generic XML File

The following lines are all you need to build the XML document.

//Create an object of Swift Message Processor
SwiftMsgProcessor SMP = new SwiftMsgProcessor();
//Parse the Swift Message
SwiftMessage swfobj = (SwiftMessage) SMP.ParseMsgStringToObject(getJTextFieldSwfMsg().getText());
//Create an object of Swift2XML Component
gr.datamation.swift.swift2xml.XMLWriter writer = new gr.datamation.swift.swift2xml.XMLWriter();
//To build the XML in another directory, use the following line.
writer.buildXML( swfobj, "/path/to" , "filename");

Example of a Swift message in generic XML format

Suppose you have a swift message as below

{1:F01AAAAGRA0AXXX0057000289}{2:O1030919010321BBBBGRA0AXXX00570001710103210920N}{4:\\r\\n:20:5387354\\r\\n:23B:CRED\\r\\n:23E:PHOB/20.527.19.60\\r\\n:32A:000526USD1101,50\\r\\n:33B:USD1121,50\\r\\n:50K:FRANZ HOLZAPFEL GMBH\\r\\nVIENNA\\r\\n:52A:BKAUATWW\\r\\n:59:/723491524\\r\\nC. KLEIN\\r\\nBLOEMENGRACHT 15\\r\\nAMSTERDAM\\r\\n:71A:SHA\\r\\n:71F:USD10,\\r\\n:71F:USD10,\\r\\n:72:
/INS/CHASUS33\\r\\n-}{5:{MAC:75D138E4}{CHK:DE1B0D71FA96}}

After processing the message as described above, the XML file that will be created is as follows.

Created blocks have a TITLE tag and a TAG tag. The TITLE tag, occurs only once for each block and it contains the Title of the block. The TAG tag, occurs for every data tag of the SWIFT message. Each TAG has two fields, the LABEL tag, which contains the name of SWIFT tag and the DATA tag, which contains the value of the SWIFT message tag.

Validator

Import Statements

Before coding with the component it is recommended that you use the following import statements

import gr.datamation.swift.processor.SwiftMsgProcessor;
import gr.datamation.swift.common.SwiftMessage;
import gr.datamation.swift.common.Tag;
import gr.datamation.swift.common.RepSeq;

import gr.datamation.swift.validator.SwiftMsgValidator;
import gr.datamation.swift.validator.SwiftValidObj;

Build and validate a message

The following lines demonstrate the way to call it and get back the returned message (example of MT103)

// Create the SwiftMsgValidator component.
SwiftMsgValidator SMV = new SwiftMsgValidator();
// Create the SwiftMessage object so that you can set its Tags.
SwiftMessage smObj = new SwiftMessage();
// Create a SwiftValidObj object.
SwiftValidObj svObj = new SwiftValidObj(smObj);
// Create a Tag object to set your message Tags.
Tag tempTag = new Tag();
// Create a Vector to store Tag data lines.
Vector<String> tempVec = new Vector<String>();
// Set Tags for block1
smObj.setArgApplid("F");
smObj.setArgServid("01");
smObj.setArgLTaddrBlk1("AAAAGRA0AXXX");
smObj.setArgSesno("0057"); // you can ignore this line. In this case SwiftMsgProcessor will set it automatically '0000'

smObj.setArgOsn("000289"); // you can ignore this line. In this case SwiftMsgProcessor will set it automatically '000000'
// Set Tags for block2
smObj.setArgInoutind("I");
smObj.setArgMsgtype("103");
smObj.setArgLTaddrBlk2("BBBBGRA0AXXX");
smObj.setArgMsgprior("N");
// Set Tags for block3
// set tag 113
tempVec = new Vector<String>();
tempVec.addElement("ABCDEFG"); //add one data line
tempTag = new Tag("113",tempVec); // Store name and data line for tag 113 to tempTag.
smObj.getBlock3().addElement(tempTag); //add tag 113 to block3 vector
// Start Setting Tags for block4
// set tag 20
tempVec = new Vector<String>();
tempVec.addElement("5387354"); //add one data line
tempTag = new Tag("20",tempVec); // Store name and data line for tag 20 to tempTag.
smObj.getBlock4().addElement(tempTag); //add tag 20 to block4 vector
// set tag 23B
tempVec = new Vector<String>();
tempVec.addElement("CRED"); //add one data line
tempTag = new Tag("23B",tempVec); // Store name and data line for tag 23B to tempTag.
smObj.getBlock4().addElement(tempTag); //add tag 23B to block4 vector
// set tag 23E
tempVec = new Vector<String>();
tempVec.addElement("PHOB/20.527.19.60"); //add one data line
tempTag = new Tag("23E",tempVec); // Store name and data line for tag 23E to tempTag.
smObj.getBlock4().addElement(tempTag); //add tag 23E to block4 vector
// set tag 32A
tempVec = new Vector<String>();
tempVec.addElement("000526USD1101,50"); //add one data line
tempTag = new Tag("32A",tempVec); // Store name and data line for tag 32A to tempTag.
smObj.getBlock4().addElement(tempTag); //add tag 32A to block4 vector
// set tag 33B
tempVec = new Vector<String>();
tempVec.addElement("USD1121,50"); //add one data line
tempTag = new Tag("33B",tempVec); // Store name and data line for tag 33B to tempTag.
smObj.getBlock4().addElement(tempTag); //add tag 33B to block4 vector
// set tag 50K
tempVec = new Vector<String>();
tempVec.addElement("FRANZ HOLZAPFEL GMBH"); //add first data line
tempVec.addElement("VIENNA"); //add second data line
tempTag = new Tag("50K",tempVec); // Store name and data line for tag 50K to tempTag.
smObj.getBlock4().addElement(tempTag); //add tag 50K to block4 vector
// set tag 52A
tempVec = new Vector<String>();
tempVec.addElement("BKAUATWW"); //add one data line
tempTag = new Tag("52A",tempVec); // Store name and data line for tag 52A to tempTag.
smObj.getBlock4().addElement(tempTag); //add tag 52A to block4 vector
// set tag 59
tempVec = new Vector<String>();
tempVec.addElement("/723491524"); //add first data line
tempVec.addElement("C. KLEIN"); //add second data line
tempVec.addElement("BLOEMENGRACHT 15"); //add third data line
tempVec.addElement("AMSTERDAM"); //add fourth data line
tempTag = new Tag("59",tempVec); // Store name and data line for tag 59 to tempTag.
smObj.getBlock4().addElement(tempTag); //add tag 59 to block4 vector
// set tag 71A
tempVec = new Vector<String>();
tempVec.addElement("SHA"); //add one data line
tempTag = new Tag("71A",tempVec); // Store name and data line for tag 71A to tempTag.
smObj.getBlock4().addElement(tempTag); //add tag 71A to block4 vector
// set tag 71F
tempVec = new Vector<String>();
tempVec.addElement("USD10,"); //add one data line
tempTag = new Tag("71F",tempVec); // Store name and data line for tag 71F to tempTag.
smObj.getBlock4().addElement(tempTag); //add tag 71F to block4 vector
// set tag 71F again like the previous one
smObj.getBlock4().addElement(tempTag); //add tag 71F to block4 vector
// set tag 72
tempVec = new Vector<String>();
tempVec.addElement("/INS/CHASUS33"); //add one data line
tempTag = new Tag("72",tempVec); // Store name and data line for tag 72 to tempTag.
smObj.getBlock4().addElement(tempTag); //add tag 72 to block4 vector
// Set Tags for block5 (This block is optional)
// set tag MAC
tempVec = new Vector<String>();
tempVec.addElement("75D138E4"); //add one data line
tempTag = new Tag("MAC",tempVec); // Store name and data line for tag MAC to tempTag.
smObj.getBlock5().addElement(tempTag); //add tag MAC to block5 vector
// set tag CHK
tempVec = new Vector<String>();
tempVec.addElement("DE1B0D71FA96"); //add one data line
tempTag = new Tag("CHK",tempVec); // Store name and data line for tag CHK to tempTag.
smObj.getBlock5().addElement(tempTag); //add tag CHK to block5 vector


// Now validate and build the outgoing message in a string format as SWIFT expects it.
svObj = SMV.validateMsg(smObj);
if (!svObj.getErrorMessage().trim().equalsIgnoreCase("")) { //If validation error
String errorMessage = svObj.getErrorMessage();
System.out.println(errorMessage); //Print error message.
} else { // Else no error.
String swiftMessage = svObj.getMessage();
System.out.println(swiftMessage); //Print the constructed Swift message.
}
//Alternatively you can use the following to display all errors found during validation:

for (ValidationError error : svObj.getValidationErrorList()) {
System.err.println(error.getDescription());
}

The message produced by the code above is

{1:F01AAAAGRA0AXXX0057000289}{2:I103BBBBGRA0AXXXN}{3:{113:ABCDEFG}}{4:
:20:5387354
:23B:CRED
:23E:PHOB/20.527.19.60
:32A:000526USD1101,50
:33B:USD1121,50
:50K:FRANZ HOLZAPFEL GMBH
VIENNA
:52A:BKAUATWW
:59:/723491524
C. KLEIN
BLOEMENGRACHT 15
AMSTERDAM
:71A:SHA
:71F:USD10,
:71F:USD10,
:72:/INS/CHASUS33
-}{5:{CHK:DE1B0D71FA96}{MAC:75D138E4}}

Comment out the code that sets tag 20 to see what happens. You should get the message below:

SV16 - Mandatory Tag is missing (20)

Build and validate a message with repetitive sequence

The following code demonstrates the way to call it and get back the returned Message. (example of MT110)

// Create the SwiftMsgProcessor component.
SwiftMsgValidator SMV = new SwiftMsgValidator();

// Create the SwiftMessage object so that you can set its Tags.
SwiftMessage smObj = new SwiftMessage();

// Create a SwiftValidObj object.
SwiftValidObj svObj = new SwiftValidObj(smObj);

// Create the RepSeq object so that you can set the Tags of a repetitive sequence.
RepSeq tempRepSep = new RepSeq();

// Create a Tag object to set your message Tags.
Tag tempTag = new Tag();

// Create a Vector to store Tag data lines.
Vector<String> tempVec = new Vector<String>();

// Set Tags for block1
smObj.setArgApplid("F");
smObj.setArgServid("01");
smObj.setArgLTaddrBlk1("AAAAGRA0AXXX");

// Set Tags for block2
smObj.setArgInoutind("I");
smObj.setArgMsgtype("110");
smObj.setArgLTaddrBlk2("BBBBGRA0AXXX");
smObj.setArgMsgprior("N");
    // Start Setting Tags for block4
// set tag 20
tempVec = new Vector<String>();
tempVec.addElement("CHQ293844"); //add one data line
tempTag = new Tag("20",tempVec); // Store name and data line for tag 20 to tempTag.
smObj.getBlock4().addElement(tempTag); //add tag 20 to block4 vector
// Create the 1st repetitive sequence.
// set tag 21
tempVec = new Vector<String>();
tempVec.addElement("G304987"); //add one data line
tempTag = new Tag("21",tempVec); // Store name and data line for tag 21 to tempTag.
tempRepSep.addTag(tempTag); //add tag 21 to block4 vector
// set tag 30
tempVec = new Vector<String>();
tempVec.addElement("020731"); //add one data line
tempTag = new Tag("30",tempVec); // Store name and data line for tag 30 to tempTag.
tempRepSep.addTag(tempTag); //add tag 30 to block4 vector
// set tag 32B
tempVec = new Vector<String>();
tempVec.addElement("GBP135,66"); //add one data line
tempTag = new Tag("32B",tempVec); // Store name and data line for tag 32B to tempTag.
tempRepSep.addTag(tempTag); //add tag 32B to block4 vector
// set tag 52A
tempVec = new Vector<String>();
tempVec.addElement("KREDBEBB100"); //add one data line
tempTag = new Tag("52A",tempVec); // Store name and data line for tag 52A to tempTag.
tempRepSep.addTag(tempTag); //add tag 52A to block4 vector
// set tag 59
tempVec = new Vector<String>();
tempVec.addElement("PETER BOGAERT"); //add first data line
tempVec.addElement("LEUVEN"); //add second data line
tempTag = new Tag("59",tempVec); // Store name and data line for tag 59 to tempTag.
tempRepSep.addTag(tempTag); //add tag 59 to block4 vector

// Add the repetitive sequence to SwiftMessage Object
smObj.getBlock4().addElement(tempRepSep);
// Create the 2nd repetitive sequence.
// Initialize RepSeq Object
tempRepSep = new RepSeq();
// set tag 21
tempVec = new Vector<String>();
tempVec.addElement("G304988"); //add one data line
tempTag = new Tag("21",tempVec); // Store name and data line for tag 21 to tempTag.
tempRepSep.addTag(tempTag); //add tag 21 to block4 vector
// set tag 30
tempVec = new Vector<String>();
tempVec.addElement("020801"); //add one data line
tempTag = new Tag("30",tempVec); // Store name and data line for tag 30 to tempTag.
tempRepSep.addTag(tempTag); //add tag 30 to block4 vector
// set tag 32B
tempVec = new Vector<String>();
tempVec.addElement("GBP523,"); //add one data line
tempTag = new Tag("32B",tempVec); // Store name and data line for tag 32B to tempTag.
tempRepSep.addTag(tempTag); //add tag 32B to block4 vector
// set tag 52A
tempVec = new Vector<String>();
tempVec.addElement("KREDBEBB100"); //add one data line
tempTag = new Tag("52A",tempVec); // Store name and data line for tag 52A to tempTag.
tempRepSep.addTag(tempTag); //add tag 52A to block4 vector
// set tag 59
tempVec = new Vector<String>();
tempVec.addElement("ANNA SMYTHE"); //add first data line
tempVec.addElement("LEUVEN"); //add second data line
tempTag = new Tag("59",tempVec); // Store name and data line for tag 59 to tempTag.
tempRepSep.addTag(tempTag); //add tag 59 to block4 vector

// Add the repetitive sequence to SwiftMessage Object
smObj.getBlock4().addElement(tempRepSep);
// Create the 3rd repetitive sequence.
// Initialize RepSeq Object
tempRepSep = new RepSeq();
// set tag 21
tempVec = new Vector<String>();
tempVec.addElement("G305766"); //add one data line
tempTag = new Tag("21",tempVec); // Store name and data line for tag 21 to tempTag.
tempRepSep.addTag(tempTag); //add tag 21 to block4 vector
// set tag 30
tempVec = new Vector<String>();
tempVec.addElement("020802"); //add one data line
tempTag = new Tag("30",tempVec); // Store name and data line for tag 30 to tempTag.
tempRepSep.addTag(tempTag); //add tag 30 to block4 vector
// set tag 32B
tempVec = new Vector<String>();
tempVec.addElement("GBP324,"); //add one data line
tempTag = new Tag("32B",tempVec); // Store name and data line for tag 32B to tempTag.
tempRepSep.addTag(tempTag); //add tag 32B to block4 vector
// set tag 52A
tempVec = new Vector<String>();
tempVec.addElement("KREDBE88"); //add one data line
tempTag = new Tag("52A",tempVec); // Store name and data line for tag 52A to tempTag.
tempRepSep.addTag(tempTag); //add tag 52A to block4 vector
// set tag 59
tempVec = new Vector<String>();
tempVec.addElement("GEORGE GRUT"); //add first data line
tempVec.addElement("BRUGGE"); //add second data line
tempTag = new Tag("59",tempVec); // Store name and data line for tag 59 to tempTag.
tempRepSep.addTag(tempTag); //add tag 59 to block4 vector

// Add the repetitive sequence to SwiftMessage Object
smObj.getBlock4().addElement(tempRepSep);

// Now validate and build the outgoing message in a string format as SWIFT expects it.
svObj = SMV.validateMsg(smObj);

if (!svObj.getErrorMessage().trim().equalsIgnoreCase("")){ //If validation error
    String errorMessage = svObj.getErrorMessage();
    System.out.println(errorMessage); //Print error message.
} else { // Else no error.
    String swiftMessage = svObj.getMessage();
    System.out.println(swiftMessage); //Print the constructed Swift message.
}

//Alternatively you can use the following to display all errors found during validation:

for (ValidationError error : svObj.getValidationErrorList()) {
    System.err.println(error.getDescription());
}

The message produce by the code above is

{1:F01AAAAGRA0AXXX0000000000}{2:I110BBBBGRA0AXXXN}{4:
:20:CHQ293844
:21:G304987
:30:020731
:32B:GBP135,66
:52A:KREDBEBB100
:59:PETER BOGAERT
LEUVEN
:21:G304988
:30:020801
:32B:GBP523,
:52A:KREDBEBB100
:59:ANNA SMYTHE
LEUVEN
:21:G305766
:30:020802
:32B:GBP324,
:52A:KREDBE88
:59:GEORGE GRUT
BRUGGE
-}

Build and validate a message with repetitive blocks

The following lines demonstrate the way to manipulate repetitive blocks that are used in messages of category 5xx. Suppose that we want to build a SWIFT message of the MT 542 type and that the fourth block (we will refer to it as "BLOCK 4") of this message starts as follows:

:16R:GENL
:20C::SEME//01410
:23G:NEWM/CODU
:16R:LINK
:20C::POOL//EQ3TEST3/CASE3
:36B::PAIR//FAMT/12345678901234,
:16S:LINK
:16R:LINK
:20C::PREV//EQ3TEST3/CASE3
:36B::TURN//FAMT/12345678901234,
:16S:LINK
:16S:GENL
:16R:TRADDET
:98A::SETT//20130124
:35B:ISIN A2C4E6G8I0K2
:16S:TRADDET
:16R:FIAC
:36B::SETT//UNIT/1,3456789012345
:97A::SAFE//x
:16S:FIAC
:16R:SETDET
:22F::STCO/A2C4E6G8/PHYS
:16R:SETPRTY
:95R::REAG/A2C4E6G8/x
:16S:SETPRTY
:16S:SETDET

To build this message, we start the same way as in the previous examples.

// Create the SwiftMsgValidator component.
SwiftMsgValidator SMV = new SwiftMsgValidator();

// Create the SwiftMessage object so that you can set its Tags.
SwiftMessage smObj = new SwiftMessage();

// Create a SwiftValidObj object.
SwiftValidObj svObj = new SwiftValidObj(smObj);
//Now blocks 1, 2 and 3 of the smObj should be built.
// Set Tags for block1
smObj.setArgApplid("F");
smObj.setArgServid("01");
smObj.setArgLTaddrBlk1("AAAAGRA0AXXX");

// Set Tags for block2
smObj.setArgInoutind("I");
smObj.setArgMsgtype("542");
smObj.setArgLTaddrBlk2("BBBBGRA0AXXX");
smObj.setArgMsgprior("N");

//For the construction of block 4 we will only describe the building of the first sub-block (GENL). The others can be built in the same fashion.
Block tempBlock = new Block();
// Create the three Tags and put them in the tempBlock.
tempBlock.addSimpleTag("16R", "GENL");
tempBlock.addSimpleTag("20C", ":SEME//01410");
tempBlock.addSimpleTag("23G", "NEWM/CODU");
// Create the first BlockRepSeq and add values to it.
BlockRepSeq tempBlockRepSeq;
tempBlockRepSeq = new BlockRepSeq();
tempBlockRepSeq.addSimpleTag("16R", "LINK");
tempBlockRepSeq.addSimpleTag("20C", ":POOL//EQ3TEST3/CASE3");
tempBlockRepSeq.addSimpleTag("36B", ":PAIR//FAMT/12345678901234,");
tempBlockRepSeq.addSimpleTag("16S", "LINK");
// Add the tempBlockRepSeq variable to the tempBlock.
tempBlock.addRepetitive(tempBlockRepSeq);
// Create the second BlockRepSeq and add values to it.
tempBlockRepSeq = new BlockRepSeq();
tempBlockRepSeq.addSimpleTag("16R", "LINK");
tempBlockRepSeq.addSimpleTag("20C", ":PREV//EQ3TEST3/CASE3");
tempBlockRepSeq.addSimpleTag("36B", ":TURN//FAMT/12345678901234,");
tempBlockRepSeq.addSimpleTag("16S", "LINK");
// Add the second tempBlockRepSeq variable to the tempBlock.
tempBlock.addRepetitive(tempBlockRepSeq);
// Finally, add the last Tag to the Block.
tempBlock.addSimpleTag("16S", "GENL");
//Add the Block to the block4 vector of the smObj:
smObj.getBlock4().addElement(tempBlock);
//We will build this message's BLOCK 4 using variables of the "Block" type (dat.SwiftCommon.Block), each representing a sub-block of BLOCK 4 (GENL, TRADDET etc).
//Do the same for all sub-blocks (TRADDET etc).
Block traddetBlock = new Block();
traddetBlock.addSimpleTag("16R", "TRADDET");
traddetBlock.addSimpleTag("98A", ":SETT//20130124");
traddetBlock.addSimpleTag("35B", "ISIN A2C4E6G8I0K2");
traddetBlock.addSimpleTag("16S", "TRADDET");

smObj.getBlock4().addElement(traddetBlock);
//FIAC
Block fiacBlock = new Block();
fiacBlock.addSimpleTag("16R", "FIAC");
fiacBlock.addSimpleTag("36B", ":SETT//UNIT/1,3456789012345");
fiacBlock.addSimpleTag("97A", ":SAFE//x");
fiacBlock.addSimpleTag("16S", "FIAC");

smObj.getBlock4().addElement(fiacBlock);
//SETDET
Block setdetBlock = new Block();
setdetBlock.addSimpleTag("16R", "SETDET");
setdetBlock.addSimpleTag("22F", ":STCO/A2C4E6G8/PHYS");

BlockRepSeq setprtryBlock;
setprtryBlock = new BlockRepSeq();
setprtryBlock.addSimpleTag("16R", "SETPRTY");
setprtryBlock.addSimpleTag("95R", ":REAG/A2C4E6G8/x");
setprtryBlock.addSimpleTag("16S", "SETPRTY");
setdetBlock.addRepetitive(setprtryBlock);

setdetBlock.addSimpleTag("16S", "SETDET");

smObj.getBlock4().addElement(setdetBlock);
//Build block5 as described in previous section.
// Create the SwiftValid object calling the ValidateMsg method.
smObj.displayMessage();
svObj = SMV.validateMsg(smObj);
// Now validate and build the outgoing message in a string format as SWIFT expects it.
if (!svObj.getErrorMessage().trim().equalsIgnoreCase("")){ //If validation error
    String errorMessage = svObj.getErrorMessage();
    System.out.println(errorMessage); //Print error message.
} else { // Else no error.
    String swiftMessage = svObj.getMessage();
    System.out.println(swiftMessage); //Print the constructed Swift message.
}

Note

If we want to build a "Block" with a repetitive sequence named Rep1 (BlockRepSeq Rep1) which has another repetitive sequence named Rep2 inside it (BlockRepSeq Rep2), then: We create the second (inner) repetitive sequence (BlockRepSeq Rep2), we fill it with values, then we put it inside the first BlockRepSeq calling the addSubSequence method of the BlockRepSeq class, like this:

Rep1.addSubSequence(Rep2);

Contact and Support

The support team is available to answer questions on using the component, code assistance, error determination, ideas, examples etc. Please forward your questions to: info@paymentcomponents.com Also visit www.paymentcomponents.com for other components and services by PaymentComponents.